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