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