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.Widget;
     20 import android.content.Context;
     21 import android.content.res.Configuration;
     22 import android.graphics.Bitmap;
     23 import android.graphics.Canvas;
     24 import android.graphics.Paint;
     25 import android.graphics.Picture;
     26 import android.graphics.Rect;
     27 import android.graphics.drawable.Drawable;
     28 import android.net.http.SslCertificate;
     29 import android.os.Build;
     30 import android.os.Bundle;
     31 import android.os.CancellationSignal;
     32 import android.os.Looper;
     33 import android.os.Message;
     34 import android.os.StrictMode;
     35 import android.print.PrintDocumentAdapter;
     36 import android.util.AttributeSet;
     37 import android.util.Log;
     38 import android.view.KeyEvent;
     39 import android.view.MotionEvent;
     40 import android.view.View;
     41 import android.view.ViewDebug;
     42 import android.view.ViewGroup;
     43 import android.view.ViewTreeObserver;
     44 import android.view.accessibility.AccessibilityEvent;
     45 import android.view.accessibility.AccessibilityNodeInfo;
     46 import android.view.accessibility.AccessibilityNodeProvider;
     47 import android.view.inputmethod.EditorInfo;
     48 import android.view.inputmethod.InputConnection;
     49 import android.widget.AbsoluteLayout;
     50 
     51 import java.io.BufferedWriter;
     52 import java.io.File;
     53 import java.util.Map;
     54 
     55 /**
     56  * <p>A View that displays web pages. This class is the basis upon which you
     57  * can roll your own web browser or simply display some online content within your Activity.
     58  * It uses the WebKit rendering engine to display
     59  * web pages and includes methods to navigate forward and backward
     60  * through a history, zoom in and out, perform text searches and more.</p>
     61  * <p>Note that, in order for your Activity to access the Internet and load web pages
     62  * in a WebView, you must add the {@code INTERNET} permissions to your
     63  * Android Manifest file:</p>
     64  * <pre>&lt;uses-permission android:name="android.permission.INTERNET" /></pre>
     65  *
     66  * <p>This must be a child of the <a
     67  * href="{@docRoot}guide/topics/manifest/manifest-element.html">{@code <manifest>}</a>
     68  * element.</p>
     69  *
     70  * <p>For more information, read
     71  * <a href="{@docRoot}guide/webapps/webview.html">Building Web Apps in WebView</a>.</p>
     72  *
     73  * <h3>Basic usage</h3>
     74  *
     75  * <p>By default, a WebView provides no browser-like widgets, does not
     76  * enable JavaScript and web page errors are ignored. If your goal is only
     77  * to display some HTML as a part of your UI, this is probably fine;
     78  * the user won't need to interact with the web page beyond reading
     79  * it, and the web page won't need to interact with the user. If you
     80  * actually want a full-blown web browser, then you probably want to
     81  * invoke the Browser application with a URL Intent rather than show it
     82  * with a WebView. For example:
     83  * <pre>
     84  * Uri uri = Uri.parse("http://www.example.com");
     85  * Intent intent = new Intent(Intent.ACTION_VIEW, uri);
     86  * startActivity(intent);
     87  * </pre>
     88  * <p>See {@link android.content.Intent} for more information.</p>
     89  *
     90  * <p>To provide a WebView in your own Activity, include a {@code <WebView>} in your layout,
     91  * or set the entire Activity window as a WebView during {@link
     92  * android.app.Activity#onCreate(Bundle) onCreate()}:</p>
     93  * <pre class="prettyprint">
     94  * WebView webview = new WebView(this);
     95  * setContentView(webview);
     96  * </pre>
     97  *
     98  * <p>Then load the desired web page:</p>
     99  * <pre>
    100  * // Simplest usage: note that an exception will NOT be thrown
    101  * // if there is an error loading this page (see below).
    102  * webview.loadUrl("http://slashdot.org/");
    103  *
    104  * // OR, you can also load from an HTML string:
    105  * String summary = "&lt;html>&lt;body>You scored &lt;b>192&lt;/b> points.&lt;/body>&lt;/html>";
    106  * webview.loadData(summary, "text/html", null);
    107  * // ... although note that there are restrictions on what this HTML can do.
    108  * // See the JavaDocs for {@link #loadData(String,String,String) loadData()} and {@link
    109  * #loadDataWithBaseURL(String,String,String,String,String) loadDataWithBaseURL()} for more info.
    110  * </pre>
    111  *
    112  * <p>A WebView has several customization points where you can add your
    113  * own behavior. These are:</p>
    114  *
    115  * <ul>
    116  *   <li>Creating and setting a {@link android.webkit.WebChromeClient} subclass.
    117  *       This class is called when something that might impact a
    118  *       browser UI happens, for instance, progress updates and
    119  *       JavaScript alerts are sent here (see <a
    120  * href="{@docRoot}guide/developing/debug-tasks.html#DebuggingWebPages">Debugging Tasks</a>).
    121  *   </li>
    122  *   <li>Creating and setting a {@link android.webkit.WebViewClient} subclass.
    123  *       It will be called when things happen that impact the
    124  *       rendering of the content, eg, errors or form submissions. You
    125  *       can also intercept URL loading here (via {@link
    126  * android.webkit.WebViewClient#shouldOverrideUrlLoading(WebView,String)
    127  * shouldOverrideUrlLoading()}).</li>
    128  *   <li>Modifying the {@link android.webkit.WebSettings}, such as
    129  * enabling JavaScript with {@link android.webkit.WebSettings#setJavaScriptEnabled(boolean)
    130  * setJavaScriptEnabled()}. </li>
    131  *   <li>Injecting Java objects into the WebView using the
    132  *       {@link android.webkit.WebView#addJavascriptInterface} method. This
    133  *       method allows you to inject Java objects into a page's JavaScript
    134  *       context, so that they can be accessed by JavaScript in the page.</li>
    135  * </ul>
    136  *
    137  * <p>Here's a more complicated example, showing error handling,
    138  *    settings, and progress notification:</p>
    139  *
    140  * <pre class="prettyprint">
    141  * // Let's display the progress in the activity title bar, like the
    142  * // browser app does.
    143  * getWindow().requestFeature(Window.FEATURE_PROGRESS);
    144  *
    145  * webview.getSettings().setJavaScriptEnabled(true);
    146  *
    147  * final Activity activity = this;
    148  * webview.setWebChromeClient(new WebChromeClient() {
    149  *   public void onProgressChanged(WebView view, int progress) {
    150  *     // Activities and WebViews measure progress with different scales.
    151  *     // The progress meter will automatically disappear when we reach 100%
    152  *     activity.setProgress(progress * 1000);
    153  *   }
    154  * });
    155  * webview.setWebViewClient(new WebViewClient() {
    156  *   public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
    157  *     Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_SHORT).show();
    158  *   }
    159  * });
    160  *
    161  * webview.loadUrl("http://developer.android.com/");
    162  * </pre>
    163  *
    164  * <h3>Zoom</h3>
    165  *
    166  * <p>To enable the built-in zoom, set
    167  * {@link #getSettings() WebSettings}.{@link WebSettings#setBuiltInZoomControls(boolean)}
    168  * (introduced in API level {@link android.os.Build.VERSION_CODES#CUPCAKE}).</p>
    169  * <p>NOTE: Using zoom if either the height or width is set to
    170  * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} may lead to undefined behavior
    171  * and should be avoided.</p>
    172  *
    173  * <h3>Cookie and window management</h3>
    174  *
    175  * <p>For obvious security reasons, your application has its own
    176  * cache, cookie store etc.&mdash;it does not share the Browser
    177  * application's data.
    178  * </p>
    179  *
    180  * <p>By default, requests by the HTML to open new windows are
    181  * ignored. This is true whether they be opened by JavaScript or by
    182  * the target attribute on a link. You can customize your
    183  * {@link WebChromeClient} to provide your own behaviour for opening multiple windows,
    184  * and render them in whatever manner you want.</p>
    185  *
    186  * <p>The standard behavior for an Activity is to be destroyed and
    187  * recreated when the device orientation or any other configuration changes. This will cause
    188  * the WebView to reload the current page. If you don't want that, you
    189  * can set your Activity to handle the {@code orientation} and {@code keyboardHidden}
    190  * changes, and then just leave the WebView alone. It'll automatically
    191  * re-orient itself as appropriate. Read <a
    192  * href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime Changes</a> for
    193  * more information about how to handle configuration changes during runtime.</p>
    194  *
    195  *
    196  * <h3>Building web pages to support different screen densities</h3>
    197  *
    198  * <p>The screen density of a device is based on the screen resolution. A screen with low density
    199  * has fewer available pixels per inch, where a screen with high density
    200  * has more &mdash; sometimes significantly more &mdash; pixels per inch. The density of a
    201  * screen is important because, other things being equal, a UI element (such as a button) whose
    202  * height and width are defined in terms of screen pixels will appear larger on the lower density
    203  * screen and smaller on the higher density screen.
    204  * For simplicity, Android collapses all actual screen densities into three generalized densities:
    205  * high, medium, and low.</p>
    206  * <p>By default, WebView scales a web page so that it is drawn at a size that matches the default
    207  * appearance on a medium density screen. So, it applies 1.5x scaling on a high density screen
    208  * (because its pixels are smaller) and 0.75x scaling on a low density screen (because its pixels
    209  * are bigger).
    210  * Starting with API level {@link android.os.Build.VERSION_CODES#ECLAIR}, WebView supports DOM, CSS,
    211  * and meta tag features to help you (as a web developer) target screens with different screen
    212  * densities.</p>
    213  * <p>Here's a summary of the features you can use to handle different screen densities:</p>
    214  * <ul>
    215  * <li>The {@code window.devicePixelRatio} DOM property. The value of this property specifies the
    216  * default scaling factor used for the current device. For example, if the value of {@code
    217  * window.devicePixelRatio} is "1.0", then the device is considered a medium density (mdpi) device
    218  * and default scaling is not applied to the web page; if the value is "1.5", then the device is
    219  * considered a high density device (hdpi) and the page content is scaled 1.5x; if the
    220  * value is "0.75", then the device is considered a low density device (ldpi) and the content is
    221  * scaled 0.75x.</li>
    222  * <li>The {@code -webkit-device-pixel-ratio} CSS media query. Use this to specify the screen
    223  * densities for which this style sheet is to be used. The corresponding value should be either
    224  * "0.75", "1", or "1.5", to indicate that the styles are for devices with low density, medium
    225  * density, or high density screens, respectively. For example:
    226  * <pre>
    227  * &lt;link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio:1.5)" href="hdpi.css" /&gt;</pre>
    228  * <p>The {@code hdpi.css} stylesheet is only used for devices with a screen pixel ration of 1.5,
    229  * which is the high density pixel ratio.</p>
    230  * </li>
    231  * </ul>
    232  *
    233  * <h3>HTML5 Video support</h3>
    234  *
    235  * <p>In order to support inline HTML5 video in your application, you need to have hardware
    236  * acceleration turned on, and set a {@link android.webkit.WebChromeClient}. For full screen support,
    237  * implementations of {@link WebChromeClient#onShowCustomView(View, WebChromeClient.CustomViewCallback)}
    238  * and {@link WebChromeClient#onHideCustomView()} are required,
    239  * {@link WebChromeClient#getVideoLoadingProgressView()} is optional.
    240  * </p>
    241  */
    242 // Implementation notes.
    243 // The WebView is a thin API class that delegates its public API to a backend WebViewProvider
    244 // class instance. WebView extends {@link AbsoluteLayout} for backward compatibility reasons.
    245 // Methods are delegated to the provider implementation: all public API methods introduced in this
    246 // file are fully delegated, whereas public and protected methods from the View base classes are
    247 // only delegated where a specific need exists for them to do so.
    248 @Widget
    249 public class WebView extends AbsoluteLayout
    250         implements ViewTreeObserver.OnGlobalFocusChangeListener,
    251         ViewGroup.OnHierarchyChangeListener, ViewDebug.HierarchyHandler {
    252 
    253     private static final String LOGTAG = "WebView";
    254 
    255     // Throwing an exception for incorrect thread usage if the
    256     // build target is JB MR2 or newer. Defaults to false, and is
    257     // set in the WebView constructor.
    258     private static Boolean sEnforceThreadChecking = false;
    259 
    260     /**
    261      *  Transportation object for returning WebView across thread boundaries.
    262      */
    263     public class WebViewTransport {
    264         private WebView mWebview;
    265 
    266         /**
    267          * Sets the WebView to the transportation object.
    268          *
    269          * @param webview the WebView to transport
    270          */
    271         public synchronized void setWebView(WebView webview) {
    272             mWebview = webview;
    273         }
    274 
    275         /**
    276          * Gets the WebView object.
    277          *
    278          * @return the transported WebView object
    279          */
    280         public synchronized WebView getWebView() {
    281             return mWebview;
    282         }
    283     }
    284 
    285     /**
    286      * URI scheme for telephone number.
    287      */
    288     public static final String SCHEME_TEL = "tel:";
    289     /**
    290      * URI scheme for email address.
    291      */
    292     public static final String SCHEME_MAILTO = "mailto:";
    293     /**
    294      * URI scheme for map address.
    295      */
    296     public static final String SCHEME_GEO = "geo:0,0?q=";
    297 
    298     /**
    299      * Interface to listen for find results.
    300      */
    301     public interface FindListener {
    302         /**
    303          * Notifies the listener about progress made by a find operation.
    304          *
    305          * @param activeMatchOrdinal the zero-based ordinal of the currently selected match
    306          * @param numberOfMatches how many matches have been found
    307          * @param isDoneCounting whether the find operation has actually completed. The listener
    308          *                       may be notified multiple times while the
    309          *                       operation is underway, and the numberOfMatches
    310          *                       value should not be considered final unless
    311          *                       isDoneCounting is true.
    312          */
    313         public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches,
    314             boolean isDoneCounting);
    315     }
    316 
    317     /**
    318      * Interface to listen for new pictures as they change.
    319      *
    320      * @deprecated This interface is now obsolete.
    321      */
    322     @Deprecated
    323     public interface PictureListener {
    324         /**
    325          * Used to provide notification that the WebView's picture has changed.
    326          * See {@link WebView#capturePicture} for details of the picture.
    327          *
    328          * @param view the WebView that owns the picture
    329          * @param picture the new picture. Applications targeting
    330          *     {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2} or above
    331          *     will always receive a null Picture.
    332          * @deprecated Deprecated due to internal changes.
    333          */
    334         @Deprecated
    335         public void onNewPicture(WebView view, Picture picture);
    336     }
    337 
    338     public static class HitTestResult {
    339         /**
    340          * Default HitTestResult, where the target is unknown.
    341          */
    342         public static final int UNKNOWN_TYPE = 0;
    343         /**
    344          * @deprecated This type is no longer used.
    345          */
    346         @Deprecated
    347         public static final int ANCHOR_TYPE = 1;
    348         /**
    349          * HitTestResult for hitting a phone number.
    350          */
    351         public static final int PHONE_TYPE = 2;
    352         /**
    353          * HitTestResult for hitting a map address.
    354          */
    355         public static final int GEO_TYPE = 3;
    356         /**
    357          * HitTestResult for hitting an email address.
    358          */
    359         public static final int EMAIL_TYPE = 4;
    360         /**
    361          * HitTestResult for hitting an HTML::img tag.
    362          */
    363         public static final int IMAGE_TYPE = 5;
    364         /**
    365          * @deprecated This type is no longer used.
    366          */
    367         @Deprecated
    368         public static final int IMAGE_ANCHOR_TYPE = 6;
    369         /**
    370          * HitTestResult for hitting a HTML::a tag with src=http.
    371          */
    372         public static final int SRC_ANCHOR_TYPE = 7;
    373         /**
    374          * HitTestResult for hitting a HTML::a tag with src=http + HTML::img.
    375          */
    376         public static final int SRC_IMAGE_ANCHOR_TYPE = 8;
    377         /**
    378          * HitTestResult for hitting an edit text area.
    379          */
    380         public static final int EDIT_TEXT_TYPE = 9;
    381 
    382         private int mType;
    383         private String mExtra;
    384 
    385         /**
    386          * @hide Only for use by WebViewProvider implementations
    387          */
    388         public HitTestResult() {
    389             mType = UNKNOWN_TYPE;
    390         }
    391 
    392         /**
    393          * @hide Only for use by WebViewProvider implementations
    394          */
    395         public void setType(int type) {
    396             mType = type;
    397         }
    398 
    399         /**
    400          * @hide Only for use by WebViewProvider implementations
    401          */
    402         public void setExtra(String extra) {
    403             mExtra = extra;
    404         }
    405 
    406         /**
    407          * Gets the type of the hit test result. See the XXX_TYPE constants
    408          * defined in this class.
    409          *
    410          * @return the type of the hit test result
    411          */
    412         public int getType() {
    413             return mType;
    414         }
    415 
    416         /**
    417          * Gets additional type-dependant information about the result. See
    418          * {@link WebView#getHitTestResult()} for details. May either be null
    419          * or contain extra information about this result.
    420          *
    421          * @return additional type-dependant information about the result
    422          */
    423         public String getExtra() {
    424             return mExtra;
    425         }
    426     }
    427 
    428     /**
    429      * Constructs a new WebView with a Context object.
    430      *
    431      * @param context a Context object used to access application assets
    432      */
    433     public WebView(Context context) {
    434         this(context, null);
    435     }
    436 
    437     /**
    438      * Constructs a new WebView with layout parameters.
    439      *
    440      * @param context a Context object used to access application assets
    441      * @param attrs an AttributeSet passed to our parent
    442      */
    443     public WebView(Context context, AttributeSet attrs) {
    444         this(context, attrs, com.android.internal.R.attr.webViewStyle);
    445     }
    446 
    447     /**
    448      * Constructs a new WebView with layout parameters and a default style.
    449      *
    450      * @param context a Context object used to access application assets
    451      * @param attrs an AttributeSet passed to our parent
    452      * @param defStyle the default style resource ID
    453      */
    454     public WebView(Context context, AttributeSet attrs, int defStyle) {
    455         this(context, attrs, defStyle, false);
    456     }
    457 
    458     /**
    459      * Constructs a new WebView with layout parameters and a default style.
    460      *
    461      * @param context a Context object used to access application assets
    462      * @param attrs an AttributeSet passed to our parent
    463      * @param defStyle the default style resource ID
    464      * @param privateBrowsing whether this WebView will be initialized in
    465      *                        private mode
    466      *
    467      * @deprecated Private browsing is no longer supported directly via
    468      * WebView and will be removed in a future release. Prefer using
    469      * {@link WebSettings}, {@link WebViewDatabase}, {@link CookieManager}
    470      * and {@link WebStorage} for fine-grained control of privacy data.
    471      */
    472     @Deprecated
    473     public WebView(Context context, AttributeSet attrs, int defStyle,
    474             boolean privateBrowsing) {
    475         this(context, attrs, defStyle, null, privateBrowsing);
    476     }
    477 
    478     /**
    479      * Constructs a new WebView with layout parameters, a default style and a set
    480      * of custom Javscript interfaces to be added to this WebView at initialization
    481      * time. This guarantees that these interfaces will be available when the JS
    482      * context is initialized.
    483      *
    484      * @param context a Context object used to access application assets
    485      * @param attrs an AttributeSet passed to our parent
    486      * @param defStyle the default style resource ID
    487      * @param javaScriptInterfaces a Map of interface names, as keys, and
    488      *                             object implementing those interfaces, as
    489      *                             values
    490      * @param privateBrowsing whether this WebView will be initialized in
    491      *                        private mode
    492      * @hide This is used internally by dumprendertree, as it requires the javaScript interfaces to
    493      *       be added synchronously, before a subsequent loadUrl call takes effect.
    494      */
    495     @SuppressWarnings("deprecation")  // for super() call into deprecated base class constructor.
    496     protected WebView(Context context, AttributeSet attrs, int defStyle,
    497             Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) {
    498         super(context, attrs, defStyle);
    499         if (context == null) {
    500             throw new IllegalArgumentException("Invalid context argument");
    501         }
    502         sEnforceThreadChecking = context.getApplicationInfo().targetSdkVersion >=
    503                 Build.VERSION_CODES.JELLY_BEAN_MR2;
    504         checkThread();
    505         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "WebView<init>");
    506 
    507         ensureProviderCreated();
    508         mProvider.init(javaScriptInterfaces, privateBrowsing);
    509         // Post condition of creating a webview is the CookieSyncManager.getInstance() is allowed.
    510         CookieSyncManager.setGetInstanceIsAllowed();
    511     }
    512 
    513     /**
    514      * Specifies whether the horizontal scrollbar has overlay style.
    515      *
    516      * @param overlay true if horizontal scrollbar should have overlay style
    517      */
    518     public void setHorizontalScrollbarOverlay(boolean overlay) {
    519         checkThread();
    520         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setHorizontalScrollbarOverlay=" + overlay);
    521         mProvider.setHorizontalScrollbarOverlay(overlay);
    522     }
    523 
    524     /**
    525      * Specifies whether the vertical scrollbar has overlay style.
    526      *
    527      * @param overlay true if vertical scrollbar should have overlay style
    528      */
    529     public void setVerticalScrollbarOverlay(boolean overlay) {
    530         checkThread();
    531         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setVerticalScrollbarOverlay=" + overlay);
    532         mProvider.setVerticalScrollbarOverlay(overlay);
    533     }
    534 
    535     /**
    536      * Gets whether horizontal scrollbar has overlay style.
    537      *
    538      * @return true if horizontal scrollbar has overlay style
    539      */
    540     public boolean overlayHorizontalScrollbar() {
    541         checkThread();
    542         return mProvider.overlayHorizontalScrollbar();
    543     }
    544 
    545     /**
    546      * Gets whether vertical scrollbar has overlay style.
    547      *
    548      * @return true if vertical scrollbar has overlay style
    549      */
    550     public boolean overlayVerticalScrollbar() {
    551         checkThread();
    552         return mProvider.overlayVerticalScrollbar();
    553     }
    554 
    555     /**
    556      * Gets the visible height (in pixels) of the embedded title bar (if any).
    557      *
    558      * @deprecated This method is now obsolete.
    559      * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
    560      */
    561     public int getVisibleTitleHeight() {
    562         checkThread();
    563         return mProvider.getVisibleTitleHeight();
    564     }
    565 
    566     /**
    567      * Gets the SSL certificate for the main top-level page or null if there is
    568      * no certificate (the site is not secure).
    569      *
    570      * @return the SSL certificate for the main top-level page
    571      */
    572     public SslCertificate getCertificate() {
    573         checkThread();
    574         return mProvider.getCertificate();
    575     }
    576 
    577     /**
    578      * Sets the SSL certificate for the main top-level page.
    579      *
    580      * @deprecated Calling this function has no useful effect, and will be
    581      * ignored in future releases.
    582      */
    583     @Deprecated
    584     public void setCertificate(SslCertificate certificate) {
    585         checkThread();
    586         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setCertificate=" + certificate);
    587         mProvider.setCertificate(certificate);
    588     }
    589 
    590     //-------------------------------------------------------------------------
    591     // Methods called by activity
    592     //-------------------------------------------------------------------------
    593 
    594     /**
    595      * Sets a username and password pair for the specified host. This data is
    596      * used by the Webview to autocomplete username and password fields in web
    597      * forms. Note that this is unrelated to the credentials used for HTTP
    598      * authentication.
    599      *
    600      * @param host the host that required the credentials
    601      * @param username the username for the given host
    602      * @param password the password for the given host
    603      * @see WebViewDatabase#clearUsernamePassword
    604      * @see WebViewDatabase#hasUsernamePassword
    605      * @deprecated Saving passwords in WebView will not be supported in future versions.
    606      */
    607     @Deprecated
    608     public void savePassword(String host, String username, String password) {
    609         checkThread();
    610         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "savePassword=" + host);
    611         mProvider.savePassword(host, username, password);
    612     }
    613 
    614     /**
    615      * Stores HTTP authentication credentials for a given host and realm. This
    616      * method is intended to be used with
    617      * {@link WebViewClient#onReceivedHttpAuthRequest}.
    618      *
    619      * @param host the host to which the credentials apply
    620      * @param realm the realm to which the credentials apply
    621      * @param username the username
    622      * @param password the password
    623      * @see #getHttpAuthUsernamePassword
    624      * @see WebViewDatabase#hasHttpAuthUsernamePassword
    625      * @see WebViewDatabase#clearHttpAuthUsernamePassword
    626      */
    627     public void setHttpAuthUsernamePassword(String host, String realm,
    628             String username, String password) {
    629         checkThread();
    630         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setHttpAuthUsernamePassword=" + host);
    631         mProvider.setHttpAuthUsernamePassword(host, realm, username, password);
    632     }
    633 
    634     /**
    635      * Retrieves HTTP authentication credentials for a given host and realm.
    636      * This method is intended to be used with
    637      * {@link WebViewClient#onReceivedHttpAuthRequest}.
    638      *
    639      * @param host the host to which the credentials apply
    640      * @param realm the realm to which the credentials apply
    641      * @return the credentials as a String array, if found. The first element
    642      *         is the username and the second element is the password. Null if
    643      *         no credentials are found.
    644      * @see #setHttpAuthUsernamePassword
    645      * @see WebViewDatabase#hasHttpAuthUsernamePassword
    646      * @see WebViewDatabase#clearHttpAuthUsernamePassword
    647      */
    648     public String[] getHttpAuthUsernamePassword(String host, String realm) {
    649         checkThread();
    650         return mProvider.getHttpAuthUsernamePassword(host, realm);
    651     }
    652 
    653     /**
    654      * Destroys the internal state of this WebView. This method should be called
    655      * after this WebView has been removed from the view system. No other
    656      * methods may be called on this WebView after destroy.
    657      */
    658     public void destroy() {
    659         checkThread();
    660         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "destroy");
    661         mProvider.destroy();
    662     }
    663 
    664     /**
    665      * Enables platform notifications of data state and proxy changes.
    666      * Notifications are enabled by default.
    667      *
    668      * @deprecated This method is now obsolete.
    669      * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
    670      */
    671     @Deprecated
    672     public static void enablePlatformNotifications() {
    673         getFactory().getStatics().setPlatformNotificationsEnabled(true);
    674     }
    675 
    676     /**
    677      * Disables platform notifications of data state and proxy changes.
    678      * Notifications are enabled by default.
    679      *
    680      * @deprecated This method is now obsolete.
    681      * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
    682      */
    683     @Deprecated
    684     public static void disablePlatformNotifications() {
    685         getFactory().getStatics().setPlatformNotificationsEnabled(false);
    686     }
    687 
    688     /**
    689      * Informs WebView of the network state. This is used to set
    690      * the JavaScript property window.navigator.isOnline and
    691      * generates the online/offline event as specified in HTML5, sec. 5.7.7
    692      *
    693      * @param networkUp a boolean indicating if network is available
    694      */
    695     public void setNetworkAvailable(boolean networkUp) {
    696         checkThread();
    697         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setNetworkAvailable=" + networkUp);
    698         mProvider.setNetworkAvailable(networkUp);
    699     }
    700 
    701     /**
    702      * Saves the state of this WebView used in
    703      * {@link android.app.Activity#onSaveInstanceState}. Please note that this
    704      * method no longer stores the display data for this WebView. The previous
    705      * behavior could potentially leak files if {@link #restoreState} was never
    706      * called.
    707      *
    708      * @param outState the Bundle to store this WebView's state
    709      * @return the same copy of the back/forward list used to save the state. If
    710      *         saveState fails, the returned list will be null.
    711      */
    712     public WebBackForwardList saveState(Bundle outState) {
    713         checkThread();
    714         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "saveState");
    715         return mProvider.saveState(outState);
    716     }
    717 
    718     /**
    719      * Saves the current display data to the Bundle given. Used in conjunction
    720      * with {@link #saveState}.
    721      * @param b a Bundle to store the display data
    722      * @param dest the file to store the serialized picture data. Will be
    723      *             overwritten with this WebView's picture data.
    724      * @return true if the picture was successfully saved
    725      * @deprecated This method is now obsolete.
    726      * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
    727      */
    728     @Deprecated
    729     public boolean savePicture(Bundle b, final File dest) {
    730         checkThread();
    731         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "savePicture=" + dest.getName());
    732         return mProvider.savePicture(b, dest);
    733     }
    734 
    735     /**
    736      * Restores the display data that was saved in {@link #savePicture}. Used in
    737      * conjunction with {@link #restoreState}. Note that this will not work if
    738      * this WebView is hardware accelerated.
    739      *
    740      * @param b a Bundle containing the saved display data
    741      * @param src the file where the picture data was stored
    742      * @return true if the picture was successfully restored
    743      * @deprecated This method is now obsolete.
    744      * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
    745      */
    746     @Deprecated
    747     public boolean restorePicture(Bundle b, File src) {
    748         checkThread();
    749         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "restorePicture=" + src.getName());
    750         return mProvider.restorePicture(b, src);
    751     }
    752 
    753     /**
    754      * Restores the state of this WebView from the given Bundle. This method is
    755      * intended for use in {@link android.app.Activity#onRestoreInstanceState}
    756      * and should be called to restore the state of this WebView. If
    757      * it is called after this WebView has had a chance to build state (load
    758      * pages, create a back/forward list, etc.) there may be undesirable
    759      * side-effects. Please note that this method no longer restores the
    760      * display data for this WebView.
    761      *
    762      * @param inState the incoming Bundle of state
    763      * @return the restored back/forward list or null if restoreState failed
    764      */
    765     public WebBackForwardList restoreState(Bundle inState) {
    766         checkThread();
    767         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "restoreState");
    768         return mProvider.restoreState(inState);
    769     }
    770 
    771     /**
    772      * Loads the given URL with the specified additional HTTP headers.
    773      *
    774      * @param url the URL of the resource to load
    775      * @param additionalHttpHeaders the additional headers to be used in the
    776      *            HTTP request for this URL, specified as a map from name to
    777      *            value. Note that if this map contains any of the headers
    778      *            that are set by default by this WebView, such as those
    779      *            controlling caching, accept types or the User-Agent, their
    780      *            values may be overriden by this WebView's defaults.
    781      */
    782     public void loadUrl(String url, Map<String, String> additionalHttpHeaders) {
    783         checkThread();
    784         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadUrl(extra headers)=" + url);
    785         mProvider.loadUrl(url, additionalHttpHeaders);
    786     }
    787 
    788     /**
    789      * Loads the given URL.
    790      *
    791      * @param url the URL of the resource to load
    792      */
    793     public void loadUrl(String url) {
    794         checkThread();
    795         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadUrl=" + url);
    796         mProvider.loadUrl(url);
    797     }
    798 
    799     /**
    800      * Loads the URL with postData using "POST" method into this WebView. If url
    801      * is not a network URL, it will be loaded with {link
    802      * {@link #loadUrl(String)} instead.
    803      *
    804      * @param url the URL of the resource to load
    805      * @param postData the data will be passed to "POST" request, which must be
    806      *     be "application/x-www-form-urlencoded" encoded.
    807      */
    808     public void postUrl(String url, byte[] postData) {
    809         checkThread();
    810         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "postUrl=" + url);
    811         mProvider.postUrl(url, postData);
    812     }
    813 
    814     /**
    815      * Loads the given data into this WebView using a 'data' scheme URL.
    816      * <p>
    817      * Note that JavaScript's same origin policy means that script running in a
    818      * page loaded using this method will be unable to access content loaded
    819      * using any scheme other than 'data', including 'http(s)'. To avoid this
    820      * restriction, use {@link
    821      * #loadDataWithBaseURL(String,String,String,String,String)
    822      * loadDataWithBaseURL()} with an appropriate base URL.
    823      * <p>
    824      * The encoding parameter specifies whether the data is base64 or URL
    825      * encoded. If the data is base64 encoded, the value of the encoding
    826      * parameter must be 'base64'. For all other values of the parameter,
    827      * including null, it is assumed that the data uses ASCII encoding for
    828      * octets inside the range of safe URL characters and use the standard %xx
    829      * hex encoding of URLs for octets outside that range. For example, '#',
    830      * '%', '\', '?' should be replaced by %23, %25, %27, %3f respectively.
    831      * <p>
    832      * The 'data' scheme URL formed by this method uses the default US-ASCII
    833      * charset. If you need need to set a different charset, you should form a
    834      * 'data' scheme URL which explicitly specifies a charset parameter in the
    835      * mediatype portion of the URL and call {@link #loadUrl(String)} instead.
    836      * Note that the charset obtained from the mediatype portion of a data URL
    837      * always overrides that specified in the HTML or XML document itself.
    838      *
    839      * @param data a String of data in the given encoding
    840      * @param mimeType the MIME type of the data, e.g. 'text/html'
    841      * @param encoding the encoding of the data
    842      */
    843     public void loadData(String data, String mimeType, String encoding) {
    844         checkThread();
    845         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadData");
    846         mProvider.loadData(data, mimeType, encoding);
    847     }
    848 
    849     /**
    850      * Loads the given data into this WebView, using baseUrl as the base URL for
    851      * the content. The base URL is used both to resolve relative URLs and when
    852      * applying JavaScript's same origin policy. The historyUrl is used for the
    853      * history entry.
    854      * <p>
    855      * Note that content specified in this way can access local device files
    856      * (via 'file' scheme URLs) only if baseUrl specifies a scheme other than
    857      * 'http', 'https', 'ftp', 'ftps', 'about' or 'javascript'.
    858      * <p>
    859      * If the base URL uses the data scheme, this method is equivalent to
    860      * calling {@link #loadData(String,String,String) loadData()} and the
    861      * historyUrl is ignored, and the data will be treated as part of a data: URL.
    862      * If the base URL uses any other scheme, then the data will be loaded into
    863      * the WebView as a plain string (i.e. not part of a data URL) and any URL-encoded
    864      * entities in the string will not be decoded.
    865      *
    866      * @param baseUrl the URL to use as the page's base URL. If null defaults to
    867      *                'about:blank'.
    868      * @param data a String of data in the given encoding
    869      * @param mimeType the MIMEType of the data, e.g. 'text/html'. If null,
    870      *                 defaults to 'text/html'.
    871      * @param encoding the encoding of the data
    872      * @param historyUrl the URL to use as the history entry. If null defaults
    873      *                   to 'about:blank'. If non-null, this must be a valid URL.
    874      */
    875     public void loadDataWithBaseURL(String baseUrl, String data,
    876             String mimeType, String encoding, String historyUrl) {
    877         checkThread();
    878         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadDataWithBaseURL=" + baseUrl);
    879         mProvider.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
    880     }
    881 
    882     /**
    883      * Asynchronously evaluates JavaScript in the context of the currently displayed page.
    884      * If non-null, |resultCallback| will be invoked with any result returned from that
    885      * execution. This method must be called on the UI thread and the callback will
    886      * be made on the UI thread.
    887      *
    888      * @param script the JavaScript to execute.
    889      * @param resultCallback A callback to be invoked when the script execution
    890      *                       completes with the result of the execution (if any).
    891      *                       May be null if no notificaion of the result is required.
    892      */
    893     public void evaluateJavascript(String script, ValueCallback<String> resultCallback) {
    894         checkThread();
    895         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "evaluateJavascript=" + script);
    896         mProvider.evaluateJavaScript(script, resultCallback);
    897     }
    898 
    899     /**
    900      * Saves the current view as a web archive.
    901      *
    902      * @param filename the filename where the archive should be placed
    903      */
    904     public void saveWebArchive(String filename) {
    905         checkThread();
    906         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "saveWebArchive=" + filename);
    907         mProvider.saveWebArchive(filename);
    908     }
    909 
    910     /**
    911      * Saves the current view as a web archive.
    912      *
    913      * @param basename the filename where the archive should be placed
    914      * @param autoname if false, takes basename to be a file. If true, basename
    915      *                 is assumed to be a directory in which a filename will be
    916      *                 chosen according to the URL of the current page.
    917      * @param callback called after the web archive has been saved. The
    918      *                 parameter for onReceiveValue will either be the filename
    919      *                 under which the file was saved, or null if saving the
    920      *                 file failed.
    921      */
    922     public void saveWebArchive(String basename, boolean autoname, ValueCallback<String> callback) {
    923         checkThread();
    924         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "saveWebArchive(auto)=" + basename);
    925         mProvider.saveWebArchive(basename, autoname, callback);
    926     }
    927 
    928     /**
    929      * Stops the current load.
    930      */
    931     public void stopLoading() {
    932         checkThread();
    933         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "stopLoading");
    934         mProvider.stopLoading();
    935     }
    936 
    937     /**
    938      * Reloads the current URL.
    939      */
    940     public void reload() {
    941         checkThread();
    942         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "reload");
    943         mProvider.reload();
    944     }
    945 
    946     /**
    947      * Gets whether this WebView has a back history item.
    948      *
    949      * @return true iff this WebView has a back history item
    950      */
    951     public boolean canGoBack() {
    952         checkThread();
    953         return mProvider.canGoBack();
    954     }
    955 
    956     /**
    957      * Goes back in the history of this WebView.
    958      */
    959     public void goBack() {
    960         checkThread();
    961         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "goBack");
    962         mProvider.goBack();
    963     }
    964 
    965     /**
    966      * Gets whether this WebView has a forward history item.
    967      *
    968      * @return true iff this Webview has a forward history item
    969      */
    970     public boolean canGoForward() {
    971         checkThread();
    972         return mProvider.canGoForward();
    973     }
    974 
    975     /**
    976      * Goes forward in the history of this WebView.
    977      */
    978     public void goForward() {
    979         checkThread();
    980         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "goForward");
    981         mProvider.goForward();
    982     }
    983 
    984     /**
    985      * Gets whether the page can go back or forward the given
    986      * number of steps.
    987      *
    988      * @param steps the negative or positive number of steps to move the
    989      *              history
    990      */
    991     public boolean canGoBackOrForward(int steps) {
    992         checkThread();
    993         return mProvider.canGoBackOrForward(steps);
    994     }
    995 
    996     /**
    997      * Goes to the history item that is the number of steps away from
    998      * the current item. Steps is negative if backward and positive
    999      * if forward.
   1000      *
   1001      * @param steps the number of steps to take back or forward in the back
   1002      *              forward list
   1003      */
   1004     public void goBackOrForward(int steps) {
   1005         checkThread();
   1006         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "goBackOrForwad=" + steps);
   1007         mProvider.goBackOrForward(steps);
   1008     }
   1009 
   1010     /**
   1011      * Gets whether private browsing is enabled in this WebView.
   1012      */
   1013     public boolean isPrivateBrowsingEnabled() {
   1014         checkThread();
   1015         return mProvider.isPrivateBrowsingEnabled();
   1016     }
   1017 
   1018     /**
   1019      * Scrolls the contents of this WebView up by half the view size.
   1020      *
   1021      * @param top true to jump to the top of the page
   1022      * @return true if the page was scrolled
   1023      */
   1024     public boolean pageUp(boolean top) {
   1025         checkThread();
   1026         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "pageUp");
   1027         return mProvider.pageUp(top);
   1028     }
   1029 
   1030     /**
   1031      * Scrolls the contents of this WebView down by half the page size.
   1032      *
   1033      * @param bottom true to jump to bottom of page
   1034      * @return true if the page was scrolled
   1035      */
   1036     public boolean pageDown(boolean bottom) {
   1037         checkThread();
   1038         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "pageDown");
   1039         return mProvider.pageDown(bottom);
   1040     }
   1041 
   1042     /**
   1043      * Clears this WebView so that onDraw() will draw nothing but white background,
   1044      * and onMeasure() will return 0 if MeasureSpec is not MeasureSpec.EXACTLY.
   1045      * @deprecated Use WebView.loadUrl("about:blank") to reliably reset the view state
   1046      *             and release page resources (including any running JavaScript).
   1047      */
   1048     @Deprecated
   1049     public void clearView() {
   1050         checkThread();
   1051         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearView");
   1052         mProvider.clearView();
   1053     }
   1054 
   1055     /**
   1056      * Gets a new picture that captures the current contents of this WebView.
   1057      * The picture is of the entire document being displayed, and is not
   1058      * limited to the area currently displayed by this WebView. Also, the
   1059      * picture is a static copy and is unaffected by later changes to the
   1060      * content being displayed.
   1061      * <p>
   1062      * Note that due to internal changes, for API levels between
   1063      * {@link android.os.Build.VERSION_CODES#HONEYCOMB} and
   1064      * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH} inclusive, the
   1065      * picture does not include fixed position elements or scrollable divs.
   1066      * <p>
   1067      * Note that from {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} the returned picture
   1068      * should only be drawn into bitmap-backed Canvas - using any other type of Canvas will involve
   1069      * additional conversion at a cost in memory and performance. Also the
   1070      * {@link android.graphics.Picture#createFromStream} and
   1071      * {@link android.graphics.Picture#writeToStream} methods are not supported on the
   1072      * returned object.
   1073      *
   1074      * @deprecated Use {@link #onDraw} to obtain a bitmap snapshot of the WebView, or
   1075      * {@link #saveWebArchive} to save the content to a file.
   1076      *
   1077      * @return a picture that captures the current contents of this WebView
   1078      */
   1079     @Deprecated
   1080     public Picture capturePicture() {
   1081         checkThread();
   1082         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "capturePicture");
   1083         return mProvider.capturePicture();
   1084     }
   1085 
   1086     /**
   1087      * Creates a PrintDocumentAdapter that provides the content of this Webview for printing.
   1088      * Only supported for API levels
   1089      * {@link android.os.Build.VERSION_CODES#KITKAT} and above.
   1090      *
   1091      * The adapter works by converting the Webview contents to a PDF stream. The Webview cannot
   1092      * be drawn during the conversion process - any such draws are undefined. It is recommended
   1093      * to use a dedicated off screen Webview for the printing. If necessary, an application may
   1094      * temporarily hide a visible WebView by using a custom PrintDocumentAdapter instance
   1095      * wrapped around the object returned and observing the onStart and onFinish methods. See
   1096      * {@link android.print.PrintDocumentAdapter} for more information.
   1097      */
   1098     public PrintDocumentAdapter createPrintDocumentAdapter() {
   1099         checkThread();
   1100         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "createPrintDocumentAdapter");
   1101         return mProvider.createPrintDocumentAdapter();
   1102     }
   1103 
   1104     /**
   1105      * Gets the current scale of this WebView.
   1106      *
   1107      * @return the current scale
   1108      *
   1109      * @deprecated This method is prone to inaccuracy due to race conditions
   1110      * between the web rendering and UI threads; prefer
   1111      * {@link WebViewClient#onScaleChanged}.
   1112      */
   1113     @Deprecated
   1114     @ViewDebug.ExportedProperty(category = "webview")
   1115     public float getScale() {
   1116         checkThread();
   1117         return mProvider.getScale();
   1118     }
   1119 
   1120     /**
   1121      * Sets the initial scale for this WebView. 0 means default.
   1122      * The behavior for the default scale depends on the state of
   1123      * {@link WebSettings#getUseWideViewPort()} and
   1124      * {@link WebSettings#getLoadWithOverviewMode()}.
   1125      * If the content fits into the WebView control by width, then
   1126      * the zoom is set to 100%. For wide content, the behavor
   1127      * depends on the state of {@link WebSettings#getLoadWithOverviewMode()}.
   1128      * If its value is true, the content will be zoomed out to be fit
   1129      * by width into the WebView control, otherwise not.
   1130      *
   1131      * If initial scale is greater than 0, WebView starts with this value
   1132      * as initial scale.
   1133      * Please note that unlike the scale properties in the viewport meta tag,
   1134      * this method doesn't take the screen density into account.
   1135      *
   1136      * @param scaleInPercent the initial scale in percent
   1137      */
   1138     public void setInitialScale(int scaleInPercent) {
   1139         checkThread();
   1140         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setInitialScale=" + scaleInPercent);
   1141         mProvider.setInitialScale(scaleInPercent);
   1142     }
   1143 
   1144     /**
   1145      * Invokes the graphical zoom picker widget for this WebView. This will
   1146      * result in the zoom widget appearing on the screen to control the zoom
   1147      * level of this WebView.
   1148      */
   1149     public void invokeZoomPicker() {
   1150         checkThread();
   1151         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "invokeZoomPicker");
   1152         mProvider.invokeZoomPicker();
   1153     }
   1154 
   1155     /**
   1156      * Gets a HitTestResult based on the current cursor node. If a HTML::a
   1157      * tag is found and the anchor has a non-JavaScript URL, the HitTestResult
   1158      * type is set to SRC_ANCHOR_TYPE and the URL is set in the "extra" field.
   1159      * If the anchor does not have a URL or if it is a JavaScript URL, the type
   1160      * will be UNKNOWN_TYPE and the URL has to be retrieved through
   1161      * {@link #requestFocusNodeHref} asynchronously. If a HTML::img tag is
   1162      * found, the HitTestResult type is set to IMAGE_TYPE and the URL is set in
   1163      * the "extra" field. A type of
   1164      * SRC_IMAGE_ANCHOR_TYPE indicates an anchor with a URL that has an image as
   1165      * a child node. If a phone number is found, the HitTestResult type is set
   1166      * to PHONE_TYPE and the phone number is set in the "extra" field of
   1167      * HitTestResult. If a map address is found, the HitTestResult type is set
   1168      * to GEO_TYPE and the address is set in the "extra" field of HitTestResult.
   1169      * If an email address is found, the HitTestResult type is set to EMAIL_TYPE
   1170      * and the email is set in the "extra" field of HitTestResult. Otherwise,
   1171      * HitTestResult type is set to UNKNOWN_TYPE.
   1172      */
   1173     public HitTestResult getHitTestResult() {
   1174         checkThread();
   1175         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "getHitTestResult");
   1176         return mProvider.getHitTestResult();
   1177     }
   1178 
   1179     /**
   1180      * Requests the anchor or image element URL at the last tapped point.
   1181      * If hrefMsg is null, this method returns immediately and does not
   1182      * dispatch hrefMsg to its target. If the tapped point hits an image,
   1183      * an anchor, or an image in an anchor, the message associates
   1184      * strings in named keys in its data. The value paired with the key
   1185      * may be an empty string.
   1186      *
   1187      * @param hrefMsg the message to be dispatched with the result of the
   1188      *                request. The message data contains three keys. "url"
   1189      *                returns the anchor's href attribute. "title" returns the
   1190      *                anchor's text. "src" returns the image's src attribute.
   1191      */
   1192     public void requestFocusNodeHref(Message hrefMsg) {
   1193         checkThread();
   1194         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "requestFocusNodeHref");
   1195         mProvider.requestFocusNodeHref(hrefMsg);
   1196     }
   1197 
   1198     /**
   1199      * Requests the URL of the image last touched by the user. msg will be sent
   1200      * to its target with a String representing the URL as its object.
   1201      *
   1202      * @param msg the message to be dispatched with the result of the request
   1203      *            as the data member with "url" as key. The result can be null.
   1204      */
   1205     public void requestImageRef(Message msg) {
   1206         checkThread();
   1207         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "requestImageRef");
   1208         mProvider.requestImageRef(msg);
   1209     }
   1210 
   1211     /**
   1212      * Gets the URL for the current page. This is not always the same as the URL
   1213      * passed to WebViewClient.onPageStarted because although the load for
   1214      * that URL has begun, the current page may not have changed.
   1215      *
   1216      * @return the URL for the current page
   1217      */
   1218     @ViewDebug.ExportedProperty(category = "webview")
   1219     public String getUrl() {
   1220         checkThread();
   1221         return mProvider.getUrl();
   1222     }
   1223 
   1224     /**
   1225      * Gets the original URL for the current page. This is not always the same
   1226      * as the URL passed to WebViewClient.onPageStarted because although the
   1227      * load for that URL has begun, the current page may not have changed.
   1228      * Also, there may have been redirects resulting in a different URL to that
   1229      * originally requested.
   1230      *
   1231      * @return the URL that was originally requested for the current page
   1232      */
   1233     @ViewDebug.ExportedProperty(category = "webview")
   1234     public String getOriginalUrl() {
   1235         checkThread();
   1236         return mProvider.getOriginalUrl();
   1237     }
   1238 
   1239     /**
   1240      * Gets the title for the current page. This is the title of the current page
   1241      * until WebViewClient.onReceivedTitle is called.
   1242      *
   1243      * @return the title for the current page
   1244      */
   1245     @ViewDebug.ExportedProperty(category = "webview")
   1246     public String getTitle() {
   1247         checkThread();
   1248         return mProvider.getTitle();
   1249     }
   1250 
   1251     /**
   1252      * Gets the favicon for the current page. This is the favicon of the current
   1253      * page until WebViewClient.onReceivedIcon is called.
   1254      *
   1255      * @return the favicon for the current page
   1256      */
   1257     public Bitmap getFavicon() {
   1258         checkThread();
   1259         return mProvider.getFavicon();
   1260     }
   1261 
   1262     /**
   1263      * Gets the touch icon URL for the apple-touch-icon <link> element, or
   1264      * a URL on this site's server pointing to the standard location of a
   1265      * touch icon.
   1266      *
   1267      * @hide
   1268      */
   1269     public String getTouchIconUrl() {
   1270         return mProvider.getTouchIconUrl();
   1271     }
   1272 
   1273     /**
   1274      * Gets the progress for the current page.
   1275      *
   1276      * @return the progress for the current page between 0 and 100
   1277      */
   1278     public int getProgress() {
   1279         checkThread();
   1280         return mProvider.getProgress();
   1281     }
   1282 
   1283     /**
   1284      * Gets the height of the HTML content.
   1285      *
   1286      * @return the height of the HTML content
   1287      */
   1288     @ViewDebug.ExportedProperty(category = "webview")
   1289     public int getContentHeight() {
   1290         checkThread();
   1291         return mProvider.getContentHeight();
   1292     }
   1293 
   1294     /**
   1295      * Gets the width of the HTML content.
   1296      *
   1297      * @return the width of the HTML content
   1298      * @hide
   1299      */
   1300     @ViewDebug.ExportedProperty(category = "webview")
   1301     public int getContentWidth() {
   1302         return mProvider.getContentWidth();
   1303     }
   1304 
   1305     /**
   1306      * Pauses all layout, parsing, and JavaScript timers for all WebViews. This
   1307      * is a global requests, not restricted to just this WebView. This can be
   1308      * useful if the application has been paused.
   1309      */
   1310     public void pauseTimers() {
   1311         checkThread();
   1312         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "pauseTimers");
   1313         mProvider.pauseTimers();
   1314     }
   1315 
   1316     /**
   1317      * Resumes all layout, parsing, and JavaScript timers for all WebViews.
   1318      * This will resume dispatching all timers.
   1319      */
   1320     public void resumeTimers() {
   1321         checkThread();
   1322         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "resumeTimers");
   1323         mProvider.resumeTimers();
   1324     }
   1325 
   1326     /**
   1327      * Pauses any extra processing associated with this WebView and its
   1328      * associated DOM, plugins, JavaScript etc. For example, if this WebView is
   1329      * taken offscreen, this could be called to reduce unnecessary CPU or
   1330      * network traffic. When this WebView is again "active", call onResume().
   1331      * Note that this differs from pauseTimers(), which affects all WebViews.
   1332      */
   1333     public void onPause() {
   1334         checkThread();
   1335         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "onPause");
   1336         mProvider.onPause();
   1337     }
   1338 
   1339     /**
   1340      * Resumes a WebView after a previous call to onPause().
   1341      */
   1342     public void onResume() {
   1343         checkThread();
   1344         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "onResume");
   1345         mProvider.onResume();
   1346     }
   1347 
   1348     /**
   1349      * Gets whether this WebView is paused, meaning onPause() was called.
   1350      * Calling onResume() sets the paused state back to false.
   1351      *
   1352      * @hide
   1353      */
   1354     public boolean isPaused() {
   1355         return mProvider.isPaused();
   1356     }
   1357 
   1358     /**
   1359      * Informs this WebView that memory is low so that it can free any available
   1360      * memory.
   1361      * @deprecated Memory caches are automatically dropped when no longer needed, and in response
   1362      *             to system memory pressure.
   1363      */
   1364     @Deprecated
   1365     public void freeMemory() {
   1366         checkThread();
   1367         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "freeMemory");
   1368         mProvider.freeMemory();
   1369     }
   1370 
   1371     /**
   1372      * Clears the resource cache. Note that the cache is per-application, so
   1373      * this will clear the cache for all WebViews used.
   1374      *
   1375      * @param includeDiskFiles if false, only the RAM cache is cleared
   1376      */
   1377     public void clearCache(boolean includeDiskFiles) {
   1378         checkThread();
   1379         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearCache");
   1380         mProvider.clearCache(includeDiskFiles);
   1381     }
   1382 
   1383     /**
   1384      * Removes the autocomplete popup from the currently focused form field, if
   1385      * present. Note this only affects the display of the autocomplete popup,
   1386      * it does not remove any saved form data from this WebView's store. To do
   1387      * that, use {@link WebViewDatabase#clearFormData}.
   1388      */
   1389     public void clearFormData() {
   1390         checkThread();
   1391         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearFormData");
   1392         mProvider.clearFormData();
   1393     }
   1394 
   1395     /**
   1396      * Tells this WebView to clear its internal back/forward list.
   1397      */
   1398     public void clearHistory() {
   1399         checkThread();
   1400         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearHistory");
   1401         mProvider.clearHistory();
   1402     }
   1403 
   1404     /**
   1405      * Clears the SSL preferences table stored in response to proceeding with
   1406      * SSL certificate errors.
   1407      */
   1408     public void clearSslPreferences() {
   1409         checkThread();
   1410         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearSslPreferences");
   1411         mProvider.clearSslPreferences();
   1412     }
   1413 
   1414     /**
   1415      * Gets the WebBackForwardList for this WebView. This contains the
   1416      * back/forward list for use in querying each item in the history stack.
   1417      * This is a copy of the private WebBackForwardList so it contains only a
   1418      * snapshot of the current state. Multiple calls to this method may return
   1419      * different objects. The object returned from this method will not be
   1420      * updated to reflect any new state.
   1421      */
   1422     public WebBackForwardList copyBackForwardList() {
   1423         checkThread();
   1424         return mProvider.copyBackForwardList();
   1425 
   1426     }
   1427 
   1428     /**
   1429      * Registers the listener to be notified as find-on-page operations
   1430      * progress. This will replace the current listener.
   1431      *
   1432      * @param listener an implementation of {@link FindListener}
   1433      */
   1434     public void setFindListener(FindListener listener) {
   1435         checkThread();
   1436         setupFindListenerIfNeeded();
   1437         mFindListener.mUserFindListener = listener;
   1438     }
   1439 
   1440     /**
   1441      * Highlights and scrolls to the next match found by
   1442      * {@link #findAllAsync}, wrapping around page boundaries as necessary.
   1443      * Notifies any registered {@link FindListener}. If {@link #findAllAsync(String)}
   1444      * has not been called yet, or if {@link #clearMatches} has been called since the
   1445      * last find operation, this function does nothing.
   1446      *
   1447      * @param forward the direction to search
   1448      * @see #setFindListener
   1449      */
   1450     public void findNext(boolean forward) {
   1451         checkThread();
   1452         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "findNext");
   1453         mProvider.findNext(forward);
   1454     }
   1455 
   1456     /**
   1457      * Finds all instances of find on the page and highlights them.
   1458      * Notifies any registered {@link FindListener}.
   1459      *
   1460      * @param find the string to find
   1461      * @return the number of occurances of the String "find" that were found
   1462      * @deprecated {@link #findAllAsync} is preferred.
   1463      * @see #setFindListener
   1464      */
   1465     @Deprecated
   1466     public int findAll(String find) {
   1467         checkThread();
   1468         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "findAll");
   1469         StrictMode.noteSlowCall("findAll blocks UI: prefer findAllAsync");
   1470         return mProvider.findAll(find);
   1471     }
   1472 
   1473     /**
   1474      * Finds all instances of find on the page and highlights them,
   1475      * asynchronously. Notifies any registered {@link FindListener}.
   1476      * Successive calls to this will cancel any pending searches.
   1477      *
   1478      * @param find the string to find.
   1479      * @see #setFindListener
   1480      */
   1481     public void findAllAsync(String find) {
   1482         checkThread();
   1483         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "findAllAsync");
   1484         mProvider.findAllAsync(find);
   1485     }
   1486 
   1487     /**
   1488      * Starts an ActionMode for finding text in this WebView.  Only works if this
   1489      * WebView is attached to the view system.
   1490      *
   1491      * @param text if non-null, will be the initial text to search for.
   1492      *             Otherwise, the last String searched for in this WebView will
   1493      *             be used to start.
   1494      * @param showIme if true, show the IME, assuming the user will begin typing.
   1495      *                If false and text is non-null, perform a find all.
   1496      * @return true if the find dialog is shown, false otherwise
   1497      * @deprecated This method does not work reliably on all Android versions;
   1498      *             implementing a custom find dialog using WebView.findAllAsync()
   1499      *             provides a more robust solution.
   1500      */
   1501     @Deprecated
   1502     public boolean showFindDialog(String text, boolean showIme) {
   1503         checkThread();
   1504         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "showFindDialog");
   1505         return mProvider.showFindDialog(text, showIme);
   1506     }
   1507 
   1508     /**
   1509      * Gets the first substring consisting of the address of a physical
   1510      * location. Currently, only addresses in the United States are detected,
   1511      * and consist of:
   1512      * <ul>
   1513      *   <li>a house number</li>
   1514      *   <li>a street name</li>
   1515      *   <li>a street type (Road, Circle, etc), either spelled out or
   1516      *       abbreviated</li>
   1517      *   <li>a city name</li>
   1518      *   <li>a state or territory, either spelled out or two-letter abbr</li>
   1519      *   <li>an optional 5 digit or 9 digit zip code</li>
   1520      * </ul>
   1521      * All names must be correctly capitalized, and the zip code, if present,
   1522      * must be valid for the state. The street type must be a standard USPS
   1523      * spelling or abbreviation. The state or territory must also be spelled
   1524      * or abbreviated using USPS standards. The house number may not exceed
   1525      * five digits.
   1526      *
   1527      * @param addr the string to search for addresses
   1528      * @return the address, or if no address is found, null
   1529      */
   1530     public static String findAddress(String addr) {
   1531         return getFactory().getStatics().findAddress(addr);
   1532     }
   1533 
   1534     /**
   1535      * Clears the highlighting surrounding text matches created by
   1536      * {@link #findAllAsync}.
   1537      */
   1538     public void clearMatches() {
   1539         checkThread();
   1540         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearMatches");
   1541         mProvider.clearMatches();
   1542     }
   1543 
   1544     /**
   1545      * Queries the document to see if it contains any image references. The
   1546      * message object will be dispatched with arg1 being set to 1 if images
   1547      * were found and 0 if the document does not reference any images.
   1548      *
   1549      * @param response the message that will be dispatched with the result
   1550      */
   1551     public void documentHasImages(Message response) {
   1552         checkThread();
   1553         mProvider.documentHasImages(response);
   1554     }
   1555 
   1556     /**
   1557      * Sets the WebViewClient that will receive various notifications and
   1558      * requests. This will replace the current handler.
   1559      *
   1560      * @param client an implementation of WebViewClient
   1561      */
   1562     public void setWebViewClient(WebViewClient client) {
   1563         checkThread();
   1564         mProvider.setWebViewClient(client);
   1565     }
   1566 
   1567     /**
   1568      * Registers the interface to be used when content can not be handled by
   1569      * the rendering engine, and should be downloaded instead. This will replace
   1570      * the current handler.
   1571      *
   1572      * @param listener an implementation of DownloadListener
   1573      */
   1574     public void setDownloadListener(DownloadListener listener) {
   1575         checkThread();
   1576         mProvider.setDownloadListener(listener);
   1577     }
   1578 
   1579     /**
   1580      * Sets the chrome handler. This is an implementation of WebChromeClient for
   1581      * use in handling JavaScript dialogs, favicons, titles, and the progress.
   1582      * This will replace the current handler.
   1583      *
   1584      * @param client an implementation of WebChromeClient
   1585      */
   1586     public void setWebChromeClient(WebChromeClient client) {
   1587         checkThread();
   1588         mProvider.setWebChromeClient(client);
   1589     }
   1590 
   1591     /**
   1592      * Sets the Picture listener. This is an interface used to receive
   1593      * notifications of a new Picture.
   1594      *
   1595      * @param listener an implementation of WebView.PictureListener
   1596      * @deprecated This method is now obsolete.
   1597      */
   1598     @Deprecated
   1599     public void setPictureListener(PictureListener listener) {
   1600         checkThread();
   1601         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setPictureListener=" + listener);
   1602         mProvider.setPictureListener(listener);
   1603     }
   1604 
   1605     /**
   1606      * Injects the supplied Java object into this WebView. The object is
   1607      * injected into the JavaScript context of the main frame, using the
   1608      * supplied name. This allows the Java object's methods to be
   1609      * accessed from JavaScript. For applications targeted to API
   1610      * level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
   1611      * and above, only public methods that are annotated with
   1612      * {@link android.webkit.JavascriptInterface} can be accessed from JavaScript.
   1613      * For applications targeted to API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN} or below,
   1614      * all public methods (including the inherited ones) can be accessed, see the
   1615      * important security note below for implications.
   1616      * <p> Note that injected objects will not
   1617      * appear in JavaScript until the page is next (re)loaded. For example:
   1618      * <pre>
   1619      * class JsObject {
   1620      *    {@literal @}JavascriptInterface
   1621      *    public String toString() { return "injectedObject"; }
   1622      * }
   1623      * webView.addJavascriptInterface(new JsObject(), "injectedObject");
   1624      * webView.loadData("<!DOCTYPE html><title></title>", "text/html", null);
   1625      * webView.loadUrl("javascript:alert(injectedObject.toString())");</pre>
   1626      * <p>
   1627      * <strong>IMPORTANT:</strong>
   1628      * <ul>
   1629      * <li> This method can be used to allow JavaScript to control the host
   1630      * application. This is a powerful feature, but also presents a security
   1631      * risk for applications targeted to API level
   1632      * {@link android.os.Build.VERSION_CODES#JELLY_BEAN} or below, because
   1633      * JavaScript could use reflection to access an
   1634      * injected object's public fields. Use of this method in a WebView
   1635      * containing untrusted content could allow an attacker to manipulate the
   1636      * host application in unintended ways, executing Java code with the
   1637      * permissions of the host application. Use extreme care when using this
   1638      * method in a WebView which could contain untrusted content.</li>
   1639      * <li> JavaScript interacts with Java object on a private, background
   1640      * thread of this WebView. Care is therefore required to maintain thread
   1641      * safety.</li>
   1642      * <li> The Java object's fields are not accessible.</li>
   1643      * </ul>
   1644      *
   1645      * @param object the Java object to inject into this WebView's JavaScript
   1646      *               context. Null values are ignored.
   1647      * @param name the name used to expose the object in JavaScript
   1648      */
   1649     public void addJavascriptInterface(Object object, String name) {
   1650         checkThread();
   1651         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "addJavascriptInterface=" + name);
   1652         mProvider.addJavascriptInterface(object, name);
   1653     }
   1654 
   1655     /**
   1656      * Removes a previously injected Java object from this WebView. Note that
   1657      * the removal will not be reflected in JavaScript until the page is next
   1658      * (re)loaded. See {@link #addJavascriptInterface}.
   1659      *
   1660      * @param name the name used to expose the object in JavaScript
   1661      */
   1662     public void removeJavascriptInterface(String name) {
   1663         checkThread();
   1664         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "removeJavascriptInterface=" + name);
   1665         mProvider.removeJavascriptInterface(name);
   1666     }
   1667 
   1668     /**
   1669      * Gets the WebSettings object used to control the settings for this
   1670      * WebView.
   1671      *
   1672      * @return a WebSettings object that can be used to control this WebView's
   1673      *         settings
   1674      */
   1675     public WebSettings getSettings() {
   1676         checkThread();
   1677         return mProvider.getSettings();
   1678     }
   1679 
   1680     /**
   1681      * Enables debugging of web contents (HTML / CSS / JavaScript)
   1682      * loaded into any WebViews of this application. This flag can be enabled
   1683      * in order to facilitate debugging of web layouts and JavaScript
   1684      * code running inside WebViews. Please refer to WebView documentation
   1685      * for the debugging guide.
   1686      *
   1687      * The default is false.
   1688      *
   1689      * @param enabled whether to enable web contents debugging
   1690      */
   1691     public static void setWebContentsDebuggingEnabled(boolean enabled) {
   1692         getFactory().getStatics().setWebContentsDebuggingEnabled(enabled);
   1693     }
   1694 
   1695     /**
   1696      * Gets the list of currently loaded plugins.
   1697      *
   1698      * @return the list of currently loaded plugins
   1699      * @deprecated This was used for Gears, which has been deprecated.
   1700      * @hide
   1701      */
   1702     @Deprecated
   1703     public static synchronized PluginList getPluginList() {
   1704         return new PluginList();
   1705     }
   1706 
   1707     /**
   1708      * @deprecated This was used for Gears, which has been deprecated.
   1709      * @hide
   1710      */
   1711     @Deprecated
   1712     public void refreshPlugins(boolean reloadOpenPages) {
   1713         checkThread();
   1714     }
   1715 
   1716     /**
   1717      * Puts this WebView into text selection mode. Do not rely on this
   1718      * functionality; it will be deprecated in the future.
   1719      *
   1720      * @deprecated This method is now obsolete.
   1721      * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
   1722      */
   1723     @Deprecated
   1724     public void emulateShiftHeld() {
   1725         checkThread();
   1726     }
   1727 
   1728     /**
   1729      * @deprecated WebView no longer needs to implement
   1730      * ViewGroup.OnHierarchyChangeListener.  This method does nothing now.
   1731      */
   1732     @Override
   1733     // Cannot add @hide as this can always be accessed via the interface.
   1734     @Deprecated
   1735     public void onChildViewAdded(View parent, View child) {}
   1736 
   1737     /**
   1738      * @deprecated WebView no longer needs to implement
   1739      * ViewGroup.OnHierarchyChangeListener.  This method does nothing now.
   1740      */
   1741     @Override
   1742     // Cannot add @hide as this can always be accessed via the interface.
   1743     @Deprecated
   1744     public void onChildViewRemoved(View p, View child) {}
   1745 
   1746     /**
   1747      * @deprecated WebView should not have implemented
   1748      * ViewTreeObserver.OnGlobalFocusChangeListener. This method does nothing now.
   1749      */
   1750     @Override
   1751     // Cannot add @hide as this can always be accessed via the interface.
   1752     @Deprecated
   1753     public void onGlobalFocusChanged(View oldFocus, View newFocus) {
   1754     }
   1755 
   1756     /**
   1757      * @deprecated Only the default case, true, will be supported in a future version.
   1758      */
   1759     @Deprecated
   1760     public void setMapTrackballToArrowKeys(boolean setMap) {
   1761         checkThread();
   1762         mProvider.setMapTrackballToArrowKeys(setMap);
   1763     }
   1764 
   1765 
   1766     public void flingScroll(int vx, int vy) {
   1767         checkThread();
   1768         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "flingScroll");
   1769         mProvider.flingScroll(vx, vy);
   1770     }
   1771 
   1772     /**
   1773      * Gets the zoom controls for this WebView, as a separate View. The caller
   1774      * is responsible for inserting this View into the layout hierarchy.
   1775      * <p/>
   1776      * API level {@link android.os.Build.VERSION_CODES#CUPCAKE} introduced
   1777      * built-in zoom mechanisms for the WebView, as opposed to these separate
   1778      * zoom controls. The built-in mechanisms are preferred and can be enabled
   1779      * using {@link WebSettings#setBuiltInZoomControls}.
   1780      *
   1781      * @deprecated the built-in zoom mechanisms are preferred
   1782      * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN}
   1783      */
   1784     @Deprecated
   1785     public View getZoomControls() {
   1786         checkThread();
   1787         return mProvider.getZoomControls();
   1788     }
   1789 
   1790     /**
   1791      * Gets whether this WebView can be zoomed in.
   1792      *
   1793      * @return true if this WebView can be zoomed in
   1794      *
   1795      * @deprecated This method is prone to inaccuracy due to race conditions
   1796      * between the web rendering and UI threads; prefer
   1797      * {@link WebViewClient#onScaleChanged}.
   1798      */
   1799     @Deprecated
   1800     public boolean canZoomIn() {
   1801         checkThread();
   1802         return mProvider.canZoomIn();
   1803     }
   1804 
   1805     /**
   1806      * Gets whether this WebView can be zoomed out.
   1807      *
   1808      * @return true if this WebView can be zoomed out
   1809      *
   1810      * @deprecated This method is prone to inaccuracy due to race conditions
   1811      * between the web rendering and UI threads; prefer
   1812      * {@link WebViewClient#onScaleChanged}.
   1813      */
   1814     @Deprecated
   1815     public boolean canZoomOut() {
   1816         checkThread();
   1817         return mProvider.canZoomOut();
   1818     }
   1819 
   1820     /**
   1821      * Performs zoom in in this WebView.
   1822      *
   1823      * @return true if zoom in succeeds, false if no zoom changes
   1824      */
   1825     public boolean zoomIn() {
   1826         checkThread();
   1827         return mProvider.zoomIn();
   1828     }
   1829 
   1830     /**
   1831      * Performs zoom out in this WebView.
   1832      *
   1833      * @return true if zoom out succeeds, false if no zoom changes
   1834      */
   1835     public boolean zoomOut() {
   1836         checkThread();
   1837         return mProvider.zoomOut();
   1838     }
   1839 
   1840     /**
   1841      * @deprecated This method is now obsolete.
   1842      * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
   1843      */
   1844     @Deprecated
   1845     public void debugDump() {
   1846         checkThread();
   1847     }
   1848 
   1849     /**
   1850      * See {@link ViewDebug.HierarchyHandler#dumpViewHierarchyWithProperties(BufferedWriter, int)}
   1851      * @hide
   1852      */
   1853     @Override
   1854     public void dumpViewHierarchyWithProperties(BufferedWriter out, int level) {
   1855         mProvider.dumpViewHierarchyWithProperties(out, level);
   1856     }
   1857 
   1858     /**
   1859      * See {@link ViewDebug.HierarchyHandler#findHierarchyView(String, int)}
   1860      * @hide
   1861      */
   1862     @Override
   1863     public View findHierarchyView(String className, int hashCode) {
   1864         return mProvider.findHierarchyView(className, hashCode);
   1865     }
   1866 
   1867     //-------------------------------------------------------------------------
   1868     // Interface for WebView providers
   1869     //-------------------------------------------------------------------------
   1870 
   1871     /**
   1872      * Gets the WebViewProvider. Used by providers to obtain the underlying
   1873      * implementation, e.g. when the appliction responds to
   1874      * WebViewClient.onCreateWindow() request.
   1875      *
   1876      * @hide WebViewProvider is not public API.
   1877      */
   1878     public WebViewProvider getWebViewProvider() {
   1879         return mProvider;
   1880     }
   1881 
   1882     /**
   1883      * Callback interface, allows the provider implementation to access non-public methods
   1884      * and fields, and make super-class calls in this WebView instance.
   1885      * @hide Only for use by WebViewProvider implementations
   1886      */
   1887     public class PrivateAccess {
   1888         // ---- Access to super-class methods ----
   1889         public int super_getScrollBarStyle() {
   1890             return WebView.super.getScrollBarStyle();
   1891         }
   1892 
   1893         public void super_scrollTo(int scrollX, int scrollY) {
   1894             WebView.super.scrollTo(scrollX, scrollY);
   1895         }
   1896 
   1897         public void super_computeScroll() {
   1898             WebView.super.computeScroll();
   1899         }
   1900 
   1901         public boolean super_onHoverEvent(MotionEvent event) {
   1902             return WebView.super.onHoverEvent(event);
   1903         }
   1904 
   1905         public boolean super_performAccessibilityAction(int action, Bundle arguments) {
   1906             return WebView.super.performAccessibilityAction(action, arguments);
   1907         }
   1908 
   1909         public boolean super_performLongClick() {
   1910             return WebView.super.performLongClick();
   1911         }
   1912 
   1913         public boolean super_setFrame(int left, int top, int right, int bottom) {
   1914             return WebView.super.setFrame(left, top, right, bottom);
   1915         }
   1916 
   1917         public boolean super_dispatchKeyEvent(KeyEvent event) {
   1918             return WebView.super.dispatchKeyEvent(event);
   1919         }
   1920 
   1921         public boolean super_onGenericMotionEvent(MotionEvent event) {
   1922             return WebView.super.onGenericMotionEvent(event);
   1923         }
   1924 
   1925         public boolean super_requestFocus(int direction, Rect previouslyFocusedRect) {
   1926             return WebView.super.requestFocus(direction, previouslyFocusedRect);
   1927         }
   1928 
   1929         public void super_setLayoutParams(ViewGroup.LayoutParams params) {
   1930             WebView.super.setLayoutParams(params);
   1931         }
   1932 
   1933         // ---- Access to non-public methods ----
   1934         public void overScrollBy(int deltaX, int deltaY,
   1935                 int scrollX, int scrollY,
   1936                 int scrollRangeX, int scrollRangeY,
   1937                 int maxOverScrollX, int maxOverScrollY,
   1938                 boolean isTouchEvent) {
   1939             WebView.this.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY,
   1940                     maxOverScrollX, maxOverScrollY, isTouchEvent);
   1941         }
   1942 
   1943         public void awakenScrollBars(int duration) {
   1944             WebView.this.awakenScrollBars(duration);
   1945         }
   1946 
   1947         public void awakenScrollBars(int duration, boolean invalidate) {
   1948             WebView.this.awakenScrollBars(duration, invalidate);
   1949         }
   1950 
   1951         public float getVerticalScrollFactor() {
   1952             return WebView.this.getVerticalScrollFactor();
   1953         }
   1954 
   1955         public float getHorizontalScrollFactor() {
   1956             return WebView.this.getHorizontalScrollFactor();
   1957         }
   1958 
   1959         public void setMeasuredDimension(int measuredWidth, int measuredHeight) {
   1960             WebView.this.setMeasuredDimension(measuredWidth, measuredHeight);
   1961         }
   1962 
   1963         public void onScrollChanged(int l, int t, int oldl, int oldt) {
   1964             WebView.this.onScrollChanged(l, t, oldl, oldt);
   1965         }
   1966 
   1967         public int getHorizontalScrollbarHeight() {
   1968             return WebView.this.getHorizontalScrollbarHeight();
   1969         }
   1970 
   1971         public void super_onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar,
   1972                 int l, int t, int r, int b) {
   1973             WebView.super.onDrawVerticalScrollBar(canvas, scrollBar, l, t, r, b);
   1974         }
   1975 
   1976         // ---- Access to (non-public) fields ----
   1977         /** Raw setter for the scroll X value, without invoking onScrollChanged handlers etc. */
   1978         public void setScrollXRaw(int scrollX) {
   1979             WebView.this.mScrollX = scrollX;
   1980         }
   1981 
   1982         /** Raw setter for the scroll Y value, without invoking onScrollChanged handlers etc. */
   1983         public void setScrollYRaw(int scrollY) {
   1984             WebView.this.mScrollY = scrollY;
   1985         }
   1986 
   1987     }
   1988 
   1989     //-------------------------------------------------------------------------
   1990     // Package-private internal stuff
   1991     //-------------------------------------------------------------------------
   1992 
   1993     // Only used by android.webkit.FindActionModeCallback.
   1994     void setFindDialogFindListener(FindListener listener) {
   1995         checkThread();
   1996         setupFindListenerIfNeeded();
   1997         mFindListener.mFindDialogFindListener = listener;
   1998     }
   1999 
   2000     // Only used by android.webkit.FindActionModeCallback.
   2001     void notifyFindDialogDismissed() {
   2002         checkThread();
   2003         mProvider.notifyFindDialogDismissed();
   2004     }
   2005 
   2006     //-------------------------------------------------------------------------
   2007     // Private internal stuff
   2008     //-------------------------------------------------------------------------
   2009 
   2010     private WebViewProvider mProvider;
   2011 
   2012     /**
   2013      * In addition to the FindListener that the user may set via the WebView.setFindListener
   2014      * API, FindActionModeCallback will register it's own FindListener. We keep them separate
   2015      * via this class so that that the two FindListeners can potentially exist at once.
   2016      */
   2017     private class FindListenerDistributor implements FindListener {
   2018         private FindListener mFindDialogFindListener;
   2019         private FindListener mUserFindListener;
   2020 
   2021         @Override
   2022         public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches,
   2023                 boolean isDoneCounting) {
   2024             if (mFindDialogFindListener != null) {
   2025                 mFindDialogFindListener.onFindResultReceived(activeMatchOrdinal, numberOfMatches,
   2026                         isDoneCounting);
   2027             }
   2028 
   2029             if (mUserFindListener != null) {
   2030                 mUserFindListener.onFindResultReceived(activeMatchOrdinal, numberOfMatches,
   2031                         isDoneCounting);
   2032             }
   2033         }
   2034     }
   2035     private FindListenerDistributor mFindListener;
   2036 
   2037     private void setupFindListenerIfNeeded() {
   2038         if (mFindListener == null) {
   2039             mFindListener = new FindListenerDistributor();
   2040             mProvider.setFindListener(mFindListener);
   2041         }
   2042     }
   2043 
   2044     private void ensureProviderCreated() {
   2045         checkThread();
   2046         if (mProvider == null) {
   2047             // As this can get called during the base class constructor chain, pass the minimum
   2048             // number of dependencies here; the rest are deferred to init().
   2049             mProvider = getFactory().createWebView(this, new PrivateAccess());
   2050         }
   2051     }
   2052 
   2053     private static synchronized WebViewFactoryProvider getFactory() {
   2054         return WebViewFactory.getProvider();
   2055     }
   2056 
   2057     private final Looper mWebViewThread = Looper.myLooper();
   2058 
   2059     private void checkThread() {
   2060         // Ignore mWebViewThread == null because this can be called during in the super class
   2061         // constructor, before this class's own constructor has even started.
   2062         if (mWebViewThread != null && Looper.myLooper() != mWebViewThread) {
   2063             Throwable throwable = new Throwable(
   2064                     "A WebView method was called on thread '" +
   2065                     Thread.currentThread().getName() + "'. " +
   2066                     "All WebView methods must be called on the same thread. " +
   2067                     "(Expected Looper " + mWebViewThread + " called on " + Looper.myLooper() +
   2068                     ", FYI main Looper is " + Looper.getMainLooper() + ")");
   2069             Log.w(LOGTAG, Log.getStackTraceString(throwable));
   2070             StrictMode.onWebViewMethodCalledOnWrongThread(throwable);
   2071 
   2072             if (sEnforceThreadChecking) {
   2073                 throw new RuntimeException(throwable);
   2074             }
   2075         }
   2076     }
   2077 
   2078     //-------------------------------------------------------------------------
   2079     // Override View methods
   2080     //-------------------------------------------------------------------------
   2081 
   2082     // TODO: Add a test that enumerates all methods in ViewDelegte & ScrollDelegate, and ensures
   2083     // there's a corresponding override (or better, caller) for each of them in here.
   2084 
   2085     @Override
   2086     protected void onAttachedToWindow() {
   2087         super.onAttachedToWindow();
   2088         mProvider.getViewDelegate().onAttachedToWindow();
   2089     }
   2090 
   2091     @Override
   2092     protected void onDetachedFromWindow() {
   2093         mProvider.getViewDelegate().onDetachedFromWindow();
   2094         super.onDetachedFromWindow();
   2095     }
   2096 
   2097     @Override
   2098     public void setLayoutParams(ViewGroup.LayoutParams params) {
   2099         mProvider.getViewDelegate().setLayoutParams(params);
   2100     }
   2101 
   2102     @Override
   2103     public void setOverScrollMode(int mode) {
   2104         super.setOverScrollMode(mode);
   2105         // This method may be called in the constructor chain, before the WebView provider is
   2106         // created.
   2107         ensureProviderCreated();
   2108         mProvider.getViewDelegate().setOverScrollMode(mode);
   2109     }
   2110 
   2111     @Override
   2112     public void setScrollBarStyle(int style) {
   2113         mProvider.getViewDelegate().setScrollBarStyle(style);
   2114         super.setScrollBarStyle(style);
   2115     }
   2116 
   2117     @Override
   2118     protected int computeHorizontalScrollRange() {
   2119         return mProvider.getScrollDelegate().computeHorizontalScrollRange();
   2120     }
   2121 
   2122     @Override
   2123     protected int computeHorizontalScrollOffset() {
   2124         return mProvider.getScrollDelegate().computeHorizontalScrollOffset();
   2125     }
   2126 
   2127     @Override
   2128     protected int computeVerticalScrollRange() {
   2129         return mProvider.getScrollDelegate().computeVerticalScrollRange();
   2130     }
   2131 
   2132     @Override
   2133     protected int computeVerticalScrollOffset() {
   2134         return mProvider.getScrollDelegate().computeVerticalScrollOffset();
   2135     }
   2136 
   2137     @Override
   2138     protected int computeVerticalScrollExtent() {
   2139         return mProvider.getScrollDelegate().computeVerticalScrollExtent();
   2140     }
   2141 
   2142     @Override
   2143     public void computeScroll() {
   2144         mProvider.getScrollDelegate().computeScroll();
   2145     }
   2146 
   2147     @Override
   2148     public boolean onHoverEvent(MotionEvent event) {
   2149         return mProvider.getViewDelegate().onHoverEvent(event);
   2150     }
   2151 
   2152     @Override
   2153     public boolean onTouchEvent(MotionEvent event) {
   2154         return mProvider.getViewDelegate().onTouchEvent(event);
   2155     }
   2156 
   2157     @Override
   2158     public boolean onGenericMotionEvent(MotionEvent event) {
   2159         return mProvider.getViewDelegate().onGenericMotionEvent(event);
   2160     }
   2161 
   2162     @Override
   2163     public boolean onTrackballEvent(MotionEvent event) {
   2164         return mProvider.getViewDelegate().onTrackballEvent(event);
   2165     }
   2166 
   2167     @Override
   2168     public boolean onKeyDown(int keyCode, KeyEvent event) {
   2169         return mProvider.getViewDelegate().onKeyDown(keyCode, event);
   2170     }
   2171 
   2172     @Override
   2173     public boolean onKeyUp(int keyCode, KeyEvent event) {
   2174         return mProvider.getViewDelegate().onKeyUp(keyCode, event);
   2175     }
   2176 
   2177     @Override
   2178     public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
   2179         return mProvider.getViewDelegate().onKeyMultiple(keyCode, repeatCount, event);
   2180     }
   2181 
   2182     /*
   2183     TODO: These are not currently implemented in WebViewClassic, but it seems inconsistent not
   2184     to be delegating them too.
   2185 
   2186     @Override
   2187     public boolean onKeyPreIme(int keyCode, KeyEvent event) {
   2188         return mProvider.getViewDelegate().onKeyPreIme(keyCode, event);
   2189     }
   2190     @Override
   2191     public boolean onKeyLongPress(int keyCode, KeyEvent event) {
   2192         return mProvider.getViewDelegate().onKeyLongPress(keyCode, event);
   2193     }
   2194     @Override
   2195     public boolean onKeyShortcut(int keyCode, KeyEvent event) {
   2196         return mProvider.getViewDelegate().onKeyShortcut(keyCode, event);
   2197     }
   2198     */
   2199 
   2200     @Override
   2201     public AccessibilityNodeProvider getAccessibilityNodeProvider() {
   2202         AccessibilityNodeProvider provider =
   2203                 mProvider.getViewDelegate().getAccessibilityNodeProvider();
   2204         return provider == null ? super.getAccessibilityNodeProvider() : provider;
   2205     }
   2206 
   2207     @Deprecated
   2208     @Override
   2209     public boolean shouldDelayChildPressedState() {
   2210         return mProvider.getViewDelegate().shouldDelayChildPressedState();
   2211     }
   2212 
   2213     @Override
   2214     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
   2215         super.onInitializeAccessibilityNodeInfo(info);
   2216         info.setClassName(WebView.class.getName());
   2217         mProvider.getViewDelegate().onInitializeAccessibilityNodeInfo(info);
   2218     }
   2219 
   2220     @Override
   2221     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
   2222         super.onInitializeAccessibilityEvent(event);
   2223         event.setClassName(WebView.class.getName());
   2224         mProvider.getViewDelegate().onInitializeAccessibilityEvent(event);
   2225     }
   2226 
   2227     @Override
   2228     public boolean performAccessibilityAction(int action, Bundle arguments) {
   2229         return mProvider.getViewDelegate().performAccessibilityAction(action, arguments);
   2230     }
   2231 
   2232     /** @hide */
   2233     @Override
   2234     protected void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar,
   2235             int l, int t, int r, int b) {
   2236         mProvider.getViewDelegate().onDrawVerticalScrollBar(canvas, scrollBar, l, t, r, b);
   2237     }
   2238 
   2239     @Override
   2240     protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
   2241         mProvider.getViewDelegate().onOverScrolled(scrollX, scrollY, clampedX, clampedY);
   2242     }
   2243 
   2244     @Override
   2245     protected void onWindowVisibilityChanged(int visibility) {
   2246         super.onWindowVisibilityChanged(visibility);
   2247         mProvider.getViewDelegate().onWindowVisibilityChanged(visibility);
   2248     }
   2249 
   2250     @Override
   2251     protected void onDraw(Canvas canvas) {
   2252         mProvider.getViewDelegate().onDraw(canvas);
   2253     }
   2254 
   2255     @Override
   2256     public boolean performLongClick() {
   2257         return mProvider.getViewDelegate().performLongClick();
   2258     }
   2259 
   2260     @Override
   2261     protected void onConfigurationChanged(Configuration newConfig) {
   2262         mProvider.getViewDelegate().onConfigurationChanged(newConfig);
   2263     }
   2264 
   2265     @Override
   2266     public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
   2267         return mProvider.getViewDelegate().onCreateInputConnection(outAttrs);
   2268     }
   2269 
   2270     @Override
   2271     protected void onVisibilityChanged(View changedView, int visibility) {
   2272         super.onVisibilityChanged(changedView, visibility);
   2273         // This method may be called in the constructor chain, before the WebView provider is
   2274         // created.
   2275         ensureProviderCreated();
   2276         mProvider.getViewDelegate().onVisibilityChanged(changedView, visibility);
   2277     }
   2278 
   2279     @Override
   2280     public void onWindowFocusChanged(boolean hasWindowFocus) {
   2281         mProvider.getViewDelegate().onWindowFocusChanged(hasWindowFocus);
   2282         super.onWindowFocusChanged(hasWindowFocus);
   2283     }
   2284 
   2285     @Override
   2286     protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
   2287         mProvider.getViewDelegate().onFocusChanged(focused, direction, previouslyFocusedRect);
   2288         super.onFocusChanged(focused, direction, previouslyFocusedRect);
   2289     }
   2290 
   2291     /** @hide */
   2292     @Override
   2293     protected boolean setFrame(int left, int top, int right, int bottom) {
   2294         return mProvider.getViewDelegate().setFrame(left, top, right, bottom);
   2295     }
   2296 
   2297     @Override
   2298     protected void onSizeChanged(int w, int h, int ow, int oh) {
   2299         super.onSizeChanged(w, h, ow, oh);
   2300         mProvider.getViewDelegate().onSizeChanged(w, h, ow, oh);
   2301     }
   2302 
   2303     @Override
   2304     protected void onScrollChanged(int l, int t, int oldl, int oldt) {
   2305         super.onScrollChanged(l, t, oldl, oldt);
   2306         mProvider.getViewDelegate().onScrollChanged(l, t, oldl, oldt);
   2307     }
   2308 
   2309     @Override
   2310     public boolean dispatchKeyEvent(KeyEvent event) {
   2311         return mProvider.getViewDelegate().dispatchKeyEvent(event);
   2312     }
   2313 
   2314     @Override
   2315     public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
   2316         return mProvider.getViewDelegate().requestFocus(direction, previouslyFocusedRect);
   2317     }
   2318 
   2319     @Override
   2320     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
   2321         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
   2322         mProvider.getViewDelegate().onMeasure(widthMeasureSpec, heightMeasureSpec);
   2323     }
   2324 
   2325     @Override
   2326     public boolean requestChildRectangleOnScreen(View child, Rect rect, boolean immediate) {
   2327         return mProvider.getViewDelegate().requestChildRectangleOnScreen(child, rect, immediate);
   2328     }
   2329 
   2330     @Override
   2331     public void setBackgroundColor(int color) {
   2332         mProvider.getViewDelegate().setBackgroundColor(color);
   2333     }
   2334 
   2335     @Override
   2336     public void setLayerType(int layerType, Paint paint) {
   2337         super.setLayerType(layerType, paint);
   2338         mProvider.getViewDelegate().setLayerType(layerType, paint);
   2339     }
   2340 
   2341     @Override
   2342     protected void dispatchDraw(Canvas canvas) {
   2343         mProvider.getViewDelegate().preDispatchDraw(canvas);
   2344         super.dispatchDraw(canvas);
   2345     }
   2346 }
   2347