1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.webkit; 18 19 import android.graphics.Bitmap; 20 import android.net.http.SslError; 21 import android.os.Message; 22 import android.view.InputEvent; 23 import android.view.KeyEvent; 24 import android.view.ViewRootImpl; 25 26 public class WebViewClient { 27 28 /** 29 * Give the host application a chance to take over the control when a new 30 * url is about to be loaded in the current WebView. If WebViewClient is not 31 * provided, by default WebView will ask Activity Manager to choose the 32 * proper handler for the url. If WebViewClient is provided, return true 33 * means the host application handles the url, while return false means the 34 * current WebView handles the url. 35 * This method is not called for requests using the POST "method". 36 * 37 * @param view The WebView that is initiating the callback. 38 * @param url The url to be loaded. 39 * @return True if the host application wants to leave the current WebView 40 * and handle the url itself, otherwise return false. 41 * @deprecated Use {@link #shouldOverrideUrlLoading(WebView, WebResourceRequest) 42 * shouldOverrideUrlLoading(WebView, WebResourceRequest)} instead. 43 */ 44 @Deprecated shouldOverrideUrlLoading(WebView view, String url)45 public boolean shouldOverrideUrlLoading(WebView view, String url) { 46 return false; 47 } 48 49 /** 50 * Give the host application a chance to take over the control when a new 51 * url is about to be loaded in the current WebView. If WebViewClient is not 52 * provided, by default WebView will ask Activity Manager to choose the 53 * proper handler for the url. If WebViewClient is provided, return true 54 * means the host application handles the url, while return false means the 55 * current WebView handles the url. 56 * 57 * <p>Notes: 58 * <ul> 59 * <li>This method is not called for requests using the POST "method".</li> 60 * <li>This method is also called for subframes with non-http schemes, thus it is 61 * strongly disadvised to unconditionally call {@link WebView#loadUrl(String)} 62 * with the request's url from inside the method and then return true, 63 * as this will make WebView to attempt loading a non-http url, and thus fail.</li> 64 * </ul> 65 * </p> 66 * 67 * @param view The WebView that is initiating the callback. 68 * @param request Object containing the details of the request. 69 * @return True if the host application wants to leave the current WebView 70 * and handle the url itself, otherwise return false. 71 */ shouldOverrideUrlLoading(WebView view, WebResourceRequest request)72 public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { 73 return shouldOverrideUrlLoading(view, request.getUrl().toString()); 74 } 75 76 /** 77 * Notify the host application that a page has started loading. This method 78 * is called once for each main frame load so a page with iframes or 79 * framesets will call onPageStarted one time for the main frame. This also 80 * means that onPageStarted will not be called when the contents of an 81 * embedded frame changes, i.e. clicking a link whose target is an iframe, 82 * it will also not be called for fragment navigations (navigations to 83 * #fragment_id). 84 * 85 * @param view The WebView that is initiating the callback. 86 * @param url The url to be loaded. 87 * @param favicon The favicon for this page if it already exists in the 88 * database. 89 */ onPageStarted(WebView view, String url, Bitmap favicon)90 public void onPageStarted(WebView view, String url, Bitmap favicon) { 91 } 92 93 /** 94 * Notify the host application that a page has finished loading. This method 95 * is called only for main frame. When onPageFinished() is called, the 96 * rendering picture may not be updated yet. To get the notification for the 97 * new Picture, use {@link WebView.PictureListener#onNewPicture}. 98 * 99 * @param view The WebView that is initiating the callback. 100 * @param url The url of the page. 101 */ onPageFinished(WebView view, String url)102 public void onPageFinished(WebView view, String url) { 103 } 104 105 /** 106 * Notify the host application that the WebView will load the resource 107 * specified by the given url. 108 * 109 * @param view The WebView that is initiating the callback. 110 * @param url The url of the resource the WebView will load. 111 */ onLoadResource(WebView view, String url)112 public void onLoadResource(WebView view, String url) { 113 } 114 115 /** 116 * Notify the host application that {@link android.webkit.WebView} content left over from 117 * previous page navigations will no longer be drawn. 118 * 119 * <p>This callback can be used to determine the point at which it is safe to make a recycled 120 * {@link android.webkit.WebView} visible, ensuring that no stale content is shown. It is called 121 * at the earliest point at which it can be guaranteed that {@link WebView#onDraw} will no 122 * longer draw any content from previous navigations. The next draw will display either the 123 * {@link WebView#setBackgroundColor background color} of the {@link WebView}, or some of the 124 * contents of the newly loaded page. 125 * 126 * <p>This method is called when the body of the HTTP response has started loading, is reflected 127 * in the DOM, and will be visible in subsequent draws. This callback occurs early in the 128 * document loading process, and as such you should expect that linked resources (for example, 129 * css and images) may not be available.</p> 130 * 131 * <p>For more fine-grained notification of visual state updates, see {@link 132 * WebView#postVisualStateCallback}.</p> 133 * 134 * <p>Please note that all the conditions and recommendations applicable to 135 * {@link WebView#postVisualStateCallback} also apply to this API.<p> 136 * 137 * <p>This callback is only called for main frame navigations.</p> 138 * 139 * @param view The {@link android.webkit.WebView} for which the navigation occurred. 140 * @param url The URL corresponding to the page navigation that triggered this callback. 141 */ onPageCommitVisible(WebView view, String url)142 public void onPageCommitVisible(WebView view, String url) { 143 } 144 145 /** 146 * Notify the host application of a resource request and allow the 147 * application to return the data. If the return value is null, the WebView 148 * will continue to load the resource as usual. Otherwise, the return 149 * response and data will be used. NOTE: This method is called on a thread 150 * other than the UI thread so clients should exercise caution 151 * when accessing private data or the view system. 152 * 153 * @param view The {@link android.webkit.WebView} that is requesting the 154 * resource. 155 * @param url The raw url of the resource. 156 * @return A {@link android.webkit.WebResourceResponse} containing the 157 * response information or null if the WebView should load the 158 * resource itself. 159 * @deprecated Use {@link #shouldInterceptRequest(WebView, WebResourceRequest) 160 * shouldInterceptRequest(WebView, WebResourceRequest)} instead. 161 */ 162 @Deprecated shouldInterceptRequest(WebView view, String url)163 public WebResourceResponse shouldInterceptRequest(WebView view, 164 String url) { 165 return null; 166 } 167 168 /** 169 * Notify the host application of a resource request and allow the 170 * application to return the data. If the return value is null, the WebView 171 * will continue to load the resource as usual. Otherwise, the return 172 * response and data will be used. NOTE: This method is called on a thread 173 * other than the UI thread so clients should exercise caution 174 * when accessing private data or the view system. 175 * 176 * @param view The {@link android.webkit.WebView} that is requesting the 177 * resource. 178 * @param request Object containing the details of the request. 179 * @return A {@link android.webkit.WebResourceResponse} containing the 180 * response information or null if the WebView should load the 181 * resource itself. 182 */ shouldInterceptRequest(WebView view, WebResourceRequest request)183 public WebResourceResponse shouldInterceptRequest(WebView view, 184 WebResourceRequest request) { 185 return shouldInterceptRequest(view, request.getUrl().toString()); 186 } 187 188 /** 189 * Notify the host application that there have been an excessive number of 190 * HTTP redirects. As the host application if it would like to continue 191 * trying to load the resource. The default behavior is to send the cancel 192 * message. 193 * 194 * @param view The WebView that is initiating the callback. 195 * @param cancelMsg The message to send if the host wants to cancel 196 * @param continueMsg The message to send if the host wants to continue 197 * @deprecated This method is no longer called. When the WebView encounters 198 * a redirect loop, it will cancel the load. 199 */ 200 @Deprecated onTooManyRedirects(WebView view, Message cancelMsg, Message continueMsg)201 public void onTooManyRedirects(WebView view, Message cancelMsg, 202 Message continueMsg) { 203 cancelMsg.sendToTarget(); 204 } 205 206 // These ints must match up to the hidden values in EventHandler. 207 /** Generic error */ 208 public static final int ERROR_UNKNOWN = -1; 209 /** Server or proxy hostname lookup failed */ 210 public static final int ERROR_HOST_LOOKUP = -2; 211 /** Unsupported authentication scheme (not basic or digest) */ 212 public static final int ERROR_UNSUPPORTED_AUTH_SCHEME = -3; 213 /** User authentication failed on server */ 214 public static final int ERROR_AUTHENTICATION = -4; 215 /** User authentication failed on proxy */ 216 public static final int ERROR_PROXY_AUTHENTICATION = -5; 217 /** Failed to connect to the server */ 218 public static final int ERROR_CONNECT = -6; 219 /** Failed to read or write to the server */ 220 public static final int ERROR_IO = -7; 221 /** Connection timed out */ 222 public static final int ERROR_TIMEOUT = -8; 223 /** Too many redirects */ 224 public static final int ERROR_REDIRECT_LOOP = -9; 225 /** Unsupported URI scheme */ 226 public static final int ERROR_UNSUPPORTED_SCHEME = -10; 227 /** Failed to perform SSL handshake */ 228 public static final int ERROR_FAILED_SSL_HANDSHAKE = -11; 229 /** Malformed URL */ 230 public static final int ERROR_BAD_URL = -12; 231 /** Generic file error */ 232 public static final int ERROR_FILE = -13; 233 /** File not found */ 234 public static final int ERROR_FILE_NOT_FOUND = -14; 235 /** Too many requests during this load */ 236 public static final int ERROR_TOO_MANY_REQUESTS = -15; 237 /** Resource load was cancelled by Safe Browsing */ 238 public static final int ERROR_UNSAFE_RESOURCE = -16; 239 240 /** 241 * Report an error to the host application. These errors are unrecoverable 242 * (i.e. the main resource is unavailable). The errorCode parameter 243 * corresponds to one of the ERROR_* constants. 244 * @param view The WebView that is initiating the callback. 245 * @param errorCode The error code corresponding to an ERROR_* value. 246 * @param description A String describing the error. 247 * @param failingUrl The url that failed to load. 248 * @deprecated Use {@link #onReceivedError(WebView, WebResourceRequest, WebResourceError) 249 * onReceivedError(WebView, WebResourceRequest, WebResourceError)} instead. 250 */ 251 @Deprecated onReceivedError(WebView view, int errorCode, String description, String failingUrl)252 public void onReceivedError(WebView view, int errorCode, 253 String description, String failingUrl) { 254 } 255 256 /** 257 * Report web resource loading error to the host application. These errors usually indicate 258 * inability to connect to the server. Note that unlike the deprecated version of the callback, 259 * the new version will be called for any resource (iframe, image, etc), not just for the main 260 * page. Thus, it is recommended to perform minimum required work in this callback. 261 * @param view The WebView that is initiating the callback. 262 * @param request The originating request. 263 * @param error Information about the error occured. 264 */ onReceivedError(WebView view, WebResourceRequest request, WebResourceError error)265 public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { 266 if (request.isForMainFrame()) { 267 onReceivedError(view, 268 error.getErrorCode(), error.getDescription().toString(), 269 request.getUrl().toString()); 270 } 271 } 272 273 /** 274 * Notify the host application that an HTTP error has been received from the server while 275 * loading a resource. HTTP errors have status codes >= 400. This callback will be called 276 * for any resource (iframe, image, etc), not just for the main page. Thus, it is recommended to 277 * perform minimum required work in this callback. Note that the content of the server 278 * response may not be provided within the <b>errorResponse</b> parameter. 279 * @param view The WebView that is initiating the callback. 280 * @param request The originating request. 281 * @param errorResponse Information about the error occured. 282 */ onReceivedHttpError( WebView view, WebResourceRequest request, WebResourceResponse errorResponse)283 public void onReceivedHttpError( 284 WebView view, WebResourceRequest request, WebResourceResponse errorResponse) { 285 } 286 287 /** 288 * As the host application if the browser should resend data as the 289 * requested page was a result of a POST. The default is to not resend the 290 * data. 291 * 292 * @param view The WebView that is initiating the callback. 293 * @param dontResend The message to send if the browser should not resend 294 * @param resend The message to send if the browser should resend data 295 */ onFormResubmission(WebView view, Message dontResend, Message resend)296 public void onFormResubmission(WebView view, Message dontResend, 297 Message resend) { 298 dontResend.sendToTarget(); 299 } 300 301 /** 302 * Notify the host application to update its visited links database. 303 * 304 * @param view The WebView that is initiating the callback. 305 * @param url The url being visited. 306 * @param isReload True if this url is being reloaded. 307 */ doUpdateVisitedHistory(WebView view, String url, boolean isReload)308 public void doUpdateVisitedHistory(WebView view, String url, 309 boolean isReload) { 310 } 311 312 /** 313 * Notify the host application that an SSL error occurred while loading a 314 * resource. The host application must call either handler.cancel() or 315 * handler.proceed(). Note that the decision may be retained for use in 316 * response to future SSL errors. The default behavior is to cancel the 317 * load. 318 * 319 * @param view The WebView that is initiating the callback. 320 * @param handler An SslErrorHandler object that will handle the user's 321 * response. 322 * @param error The SSL error object. 323 */ onReceivedSslError(WebView view, SslErrorHandler handler, SslError error)324 public void onReceivedSslError(WebView view, SslErrorHandler handler, 325 SslError error) { 326 handler.cancel(); 327 } 328 329 /** 330 * Notify the host application to handle a SSL client certificate 331 * request. The host application is responsible for showing the UI 332 * if desired and providing the keys. There are three ways to 333 * respond: proceed(), cancel() or ignore(). Webview stores the response 334 * in memory (for the life of the application) if proceed() or cancel() is 335 * called and does not call onReceivedClientCertRequest() again for the 336 * same host and port pair. Webview does not store the response if ignore() 337 * is called. Note that, multiple layers in chromium network stack might be 338 * caching the responses, so the behavior for ignore is only a best case 339 * effort. 340 * 341 * This method is called on the UI thread. During the callback, the 342 * connection is suspended. 343 * 344 * For most use cases, the application program should implement the 345 * {@link android.security.KeyChainAliasCallback} interface and pass it to 346 * {@link android.security.KeyChain#choosePrivateKeyAlias} to start an 347 * activity for the user to choose the proper alias. The keychain activity will 348 * provide the alias through the callback method in the implemented interface. Next 349 * the application should create an async task to call 350 * {@link android.security.KeyChain#getPrivateKey} to receive the key. 351 * 352 * An example implementation of client certificates can be seen at 353 * <A href="https://android.googlesource.com/platform/packages/apps/Browser/+/android-5.1.1_r1/src/com/android/browser/Tab.java"> 354 * AOSP Browser</a> 355 * 356 * The default behavior is to cancel, returning no client certificate. 357 * 358 * @param view The WebView that is initiating the callback 359 * @param request An instance of a {@link ClientCertRequest} 360 * 361 */ onReceivedClientCertRequest(WebView view, ClientCertRequest request)362 public void onReceivedClientCertRequest(WebView view, ClientCertRequest request) { 363 request.cancel(); 364 } 365 366 /** 367 * Notifies the host application that the WebView received an HTTP 368 * authentication request. The host application can use the supplied 369 * {@link HttpAuthHandler} to set the WebView's response to the request. 370 * The default behavior is to cancel the request. 371 * 372 * @param view the WebView that is initiating the callback 373 * @param handler the HttpAuthHandler used to set the WebView's response 374 * @param host the host requiring authentication 375 * @param realm the realm for which authentication is required 376 * @see WebView#getHttpAuthUsernamePassword 377 */ onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm)378 public void onReceivedHttpAuthRequest(WebView view, 379 HttpAuthHandler handler, String host, String realm) { 380 handler.cancel(); 381 } 382 383 /** 384 * Give the host application a chance to handle the key event synchronously. 385 * e.g. menu shortcut key events need to be filtered this way. If return 386 * true, WebView will not handle the key event. If return false, WebView 387 * will always handle the key event, so none of the super in the view chain 388 * will see the key event. The default behavior returns false. 389 * 390 * @param view The WebView that is initiating the callback. 391 * @param event The key event. 392 * @return True if the host application wants to handle the key event 393 * itself, otherwise return false 394 */ shouldOverrideKeyEvent(WebView view, KeyEvent event)395 public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) { 396 return false; 397 } 398 399 /** 400 * Notify the host application that a key was not handled by the WebView. 401 * Except system keys, WebView always consumes the keys in the normal flow 402 * or if shouldOverrideKeyEvent returns true. This is called asynchronously 403 * from where the key is dispatched. It gives the host application a chance 404 * to handle the unhandled key events. 405 * 406 * @param view The WebView that is initiating the callback. 407 * @param event The key event. 408 */ onUnhandledKeyEvent(WebView view, KeyEvent event)409 public void onUnhandledKeyEvent(WebView view, KeyEvent event) { 410 onUnhandledInputEventInternal(view, event); 411 } 412 413 /** 414 * Notify the host application that a input event was not handled by the WebView. 415 * Except system keys, WebView always consumes input events in the normal flow 416 * or if shouldOverrideKeyEvent returns true. This is called asynchronously 417 * from where the event is dispatched. It gives the host application a chance 418 * to handle the unhandled input events. 419 * 420 * Note that if the event is a {@link android.view.MotionEvent}, then it's lifetime is only 421 * that of the function call. If the WebViewClient wishes to use the event beyond that, then it 422 * <i>must</i> create a copy of the event. 423 * 424 * It is the responsibility of overriders of this method to call 425 * {@link #onUnhandledKeyEvent(WebView, KeyEvent)} 426 * when appropriate if they wish to continue receiving events through it. 427 * 428 * @param view The WebView that is initiating the callback. 429 * @param event The input event. 430 * @removed 431 */ onUnhandledInputEvent(WebView view, InputEvent event)432 public void onUnhandledInputEvent(WebView view, InputEvent event) { 433 if (event instanceof KeyEvent) { 434 onUnhandledKeyEvent(view, (KeyEvent) event); 435 return; 436 } 437 onUnhandledInputEventInternal(view, event); 438 } 439 onUnhandledInputEventInternal(WebView view, InputEvent event)440 private void onUnhandledInputEventInternal(WebView view, InputEvent event) { 441 ViewRootImpl root = view.getViewRootImpl(); 442 if (root != null) { 443 root.dispatchUnhandledInputEvent(event); 444 } 445 } 446 447 /** 448 * Notify the host application that the scale applied to the WebView has 449 * changed. 450 * 451 * @param view The WebView that is initiating the callback. 452 * @param oldScale The old scale factor 453 * @param newScale The new scale factor 454 */ onScaleChanged(WebView view, float oldScale, float newScale)455 public void onScaleChanged(WebView view, float oldScale, float newScale) { 456 } 457 458 /** 459 * Notify the host application that a request to automatically log in the 460 * user has been processed. 461 * @param view The WebView requesting the login. 462 * @param realm The account realm used to look up accounts. 463 * @param account An optional account. If not null, the account should be 464 * checked against accounts on the device. If it is a valid 465 * account, it should be used to log in the user. 466 * @param args Authenticator specific arguments used to log in the user. 467 */ onReceivedLoginRequest(WebView view, String realm, String account, String args)468 public void onReceivedLoginRequest(WebView view, String realm, 469 String account, String args) { 470 } 471 472 /** 473 * Notify host application that the given webview's render process has exited. 474 * 475 * Multiple WebView instances may be associated with a single render process; 476 * onRenderProcessGone will be called for each WebView that was affected. 477 * The application's implementation of this callback should only attempt to 478 * clean up the specific WebView given as a parameter, and should not assume 479 * that other WebView instances are affected. 480 * 481 * The given WebView can't be used, and should be removed from the view hierarchy, 482 * all references to it should be cleaned up, e.g any references in the Activity 483 * or other classes saved using findViewById and similar calls, etc 484 * 485 * To cause an render process crash for test purpose, the application can 486 * call loadUrl("chrome://crash") on the WebView. Note that multiple WebView 487 * instances may be affected if they share a render process, not just the 488 * specific WebView which loaded chrome://crash. 489 * 490 * @param view The WebView which needs to be cleaned up. 491 * @param detail the reason why it exited. 492 * @return true if the host application handled the situation that process has 493 * exited, otherwise, application will crash if render process crashed, 494 * or be killed if render process was killed by the system. 495 */ onRenderProcessGone(WebView view, RenderProcessGoneDetail detail)496 public boolean onRenderProcessGone(WebView view, RenderProcessGoneDetail detail) { 497 return false; 498 } 499 } 500