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