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