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 238 /** 239 * Report an error to the host application. These errors are unrecoverable 240 * (i.e. the main resource is unavailable). The errorCode parameter 241 * corresponds to one of the ERROR_* constants. 242 * @param view The WebView that is initiating the callback. 243 * @param errorCode The error code corresponding to an ERROR_* value. 244 * @param description A String describing the error. 245 * @param failingUrl The url that failed to load. 246 * @deprecated Use {@link #onReceivedError(WebView, WebResourceRequest, WebResourceError) 247 * onReceivedError(WebView, WebResourceRequest, WebResourceError)} instead. 248 */ 249 @Deprecated onReceivedError(WebView view, int errorCode, String description, String failingUrl)250 public void onReceivedError(WebView view, int errorCode, 251 String description, String failingUrl) { 252 } 253 254 /** 255 * Report web resource loading error to the host application. These errors usually indicate 256 * inability to connect to the server. Note that unlike the deprecated version of the callback, 257 * the new version will be called for any resource (iframe, image, etc), not just for the main 258 * page. Thus, it is recommended to perform minimum required work in this callback. 259 * @param view The WebView that is initiating the callback. 260 * @param request The originating request. 261 * @param error Information about the error occured. 262 */ onReceivedError(WebView view, WebResourceRequest request, WebResourceError error)263 public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { 264 if (request.isForMainFrame()) { 265 onReceivedError(view, 266 error.getErrorCode(), error.getDescription().toString(), 267 request.getUrl().toString()); 268 } 269 } 270 271 /** 272 * Notify the host application that an HTTP error has been received from the server while 273 * loading a resource. HTTP errors have status codes >= 400. This callback will be called 274 * for any resource (iframe, image, etc), not just for the main page. Thus, it is recommended to 275 * perform minimum required work in this callback. Note that the content of the server 276 * response may not be provided within the <b>errorResponse</b> parameter. 277 * @param view The WebView that is initiating the callback. 278 * @param request The originating request. 279 * @param errorResponse Information about the error occured. 280 */ onReceivedHttpError( WebView view, WebResourceRequest request, WebResourceResponse errorResponse)281 public void onReceivedHttpError( 282 WebView view, WebResourceRequest request, WebResourceResponse errorResponse) { 283 } 284 285 /** 286 * As the host application if the browser should resend data as the 287 * requested page was a result of a POST. The default is to not resend the 288 * data. 289 * 290 * @param view The WebView that is initiating the callback. 291 * @param dontResend The message to send if the browser should not resend 292 * @param resend The message to send if the browser should resend data 293 */ onFormResubmission(WebView view, Message dontResend, Message resend)294 public void onFormResubmission(WebView view, Message dontResend, 295 Message resend) { 296 dontResend.sendToTarget(); 297 } 298 299 /** 300 * Notify the host application to update its visited links database. 301 * 302 * @param view The WebView that is initiating the callback. 303 * @param url The url being visited. 304 * @param isReload True if this url is being reloaded. 305 */ doUpdateVisitedHistory(WebView view, String url, boolean isReload)306 public void doUpdateVisitedHistory(WebView view, String url, 307 boolean isReload) { 308 } 309 310 /** 311 * Notify the host application that an SSL error occurred while loading a 312 * resource. The host application must call either handler.cancel() or 313 * handler.proceed(). Note that the decision may be retained for use in 314 * response to future SSL errors. The default behavior is to cancel the 315 * load. 316 * 317 * @param view The WebView that is initiating the callback. 318 * @param handler An SslErrorHandler object that will handle the user's 319 * response. 320 * @param error The SSL error object. 321 */ onReceivedSslError(WebView view, SslErrorHandler handler, SslError error)322 public void onReceivedSslError(WebView view, SslErrorHandler handler, 323 SslError error) { 324 handler.cancel(); 325 } 326 327 /** 328 * Notify the host application to handle a SSL client certificate 329 * request. The host application is responsible for showing the UI 330 * if desired and providing the keys. There are three ways to 331 * respond: proceed(), cancel() or ignore(). Webview stores the response 332 * in memory (for the life of the application) if proceed() or cancel() is 333 * called and does not call onReceivedClientCertRequest() again for the 334 * same host and port pair. Webview does not store the response if ignore() 335 * is called. Note that, multiple layers in chromium network stack might be 336 * caching the responses, so the behavior for ignore is only a best case 337 * effort. 338 * 339 * This method is called on the UI thread. During the callback, the 340 * connection is suspended. 341 * 342 * For most use cases, the application program should implement the 343 * {@link android.security.KeyChainAliasCallback} interface and pass it to 344 * {@link android.security.KeyChain#choosePrivateKeyAlias} to start an 345 * activity for the user to choose the proper alias. The keychain activity will 346 * provide the alias through the callback method in the implemented interface. Next 347 * the application should create an async task to call 348 * {@link android.security.KeyChain#getPrivateKey} to receive the key. 349 * 350 * An example implementation of client certificates can be seen at 351 * <A href="https://android.googlesource.com/platform/packages/apps/Browser/+/android-5.1.1_r1/src/com/android/browser/Tab.java"> 352 * AOSP Browser</a> 353 * 354 * The default behavior is to cancel, returning no client certificate. 355 * 356 * @param view The WebView that is initiating the callback 357 * @param request An instance of a {@link ClientCertRequest} 358 * 359 */ onReceivedClientCertRequest(WebView view, ClientCertRequest request)360 public void onReceivedClientCertRequest(WebView view, ClientCertRequest request) { 361 request.cancel(); 362 } 363 364 /** 365 * Notifies the host application that the WebView received an HTTP 366 * authentication request. The host application can use the supplied 367 * {@link HttpAuthHandler} to set the WebView's response to the request. 368 * The default behavior is to cancel the request. 369 * 370 * @param view the WebView that is initiating the callback 371 * @param handler the HttpAuthHandler used to set the WebView's response 372 * @param host the host requiring authentication 373 * @param realm the realm for which authentication is required 374 * @see WebView#getHttpAuthUsernamePassword 375 */ onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm)376 public void onReceivedHttpAuthRequest(WebView view, 377 HttpAuthHandler handler, String host, String realm) { 378 handler.cancel(); 379 } 380 381 /** 382 * Give the host application a chance to handle the key event synchronously. 383 * e.g. menu shortcut key events need to be filtered this way. If return 384 * true, WebView will not handle the key event. If return false, WebView 385 * will always handle the key event, so none of the super in the view chain 386 * will see the key event. The default behavior returns false. 387 * 388 * @param view The WebView that is initiating the callback. 389 * @param event The key event. 390 * @return True if the host application wants to handle the key event 391 * itself, otherwise return false 392 */ shouldOverrideKeyEvent(WebView view, KeyEvent event)393 public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) { 394 return false; 395 } 396 397 /** 398 * Notify the host application that a key was not handled by the WebView. 399 * Except system keys, WebView always consumes the keys in the normal flow 400 * or if shouldOverrideKeyEvent returns true. This is called asynchronously 401 * from where the key is dispatched. It gives the host application a chance 402 * to handle the unhandled key events. 403 * 404 * @param view The WebView that is initiating the callback. 405 * @param event The key event. 406 */ onUnhandledKeyEvent(WebView view, KeyEvent event)407 public void onUnhandledKeyEvent(WebView view, KeyEvent event) { 408 onUnhandledInputEventInternal(view, event); 409 } 410 411 /** 412 * Notify the host application that a input event was not handled by the WebView. 413 * Except system keys, WebView always consumes input events in the normal flow 414 * or if shouldOverrideKeyEvent returns true. This is called asynchronously 415 * from where the event is dispatched. It gives the host application a chance 416 * to handle the unhandled input events. 417 * 418 * Note that if the event is a {@link android.view.MotionEvent}, then it's lifetime is only 419 * that of the function call. If the WebViewClient wishes to use the event beyond that, then it 420 * <i>must</i> create a copy of the event. 421 * 422 * It is the responsibility of overriders of this method to call 423 * {@link #onUnhandledKeyEvent(WebView, KeyEvent)} 424 * when appropriate if they wish to continue receiving events through it. 425 * 426 * @param view The WebView that is initiating the callback. 427 * @param event The input event. 428 * @removed 429 */ onUnhandledInputEvent(WebView view, InputEvent event)430 public void onUnhandledInputEvent(WebView view, InputEvent event) { 431 if (event instanceof KeyEvent) { 432 onUnhandledKeyEvent(view, (KeyEvent) event); 433 return; 434 } 435 onUnhandledInputEventInternal(view, event); 436 } 437 onUnhandledInputEventInternal(WebView view, InputEvent event)438 private void onUnhandledInputEventInternal(WebView view, InputEvent event) { 439 ViewRootImpl root = view.getViewRootImpl(); 440 if (root != null) { 441 root.dispatchUnhandledInputEvent(event); 442 } 443 } 444 445 /** 446 * Notify the host application that the scale applied to the WebView has 447 * changed. 448 * 449 * @param view The WebView that is initiating the callback. 450 * @param oldScale The old scale factor 451 * @param newScale The new scale factor 452 */ onScaleChanged(WebView view, float oldScale, float newScale)453 public void onScaleChanged(WebView view, float oldScale, float newScale) { 454 } 455 456 /** 457 * Notify the host application that a request to automatically log in the 458 * user has been processed. 459 * @param view The WebView requesting the login. 460 * @param realm The account realm used to look up accounts. 461 * @param account An optional account. If not null, the account should be 462 * checked against accounts on the device. If it is a valid 463 * account, it should be used to log in the user. 464 * @param args Authenticator specific arguments used to log in the user. 465 */ onReceivedLoginRequest(WebView view, String realm, String account, String args)466 public void onReceivedLoginRequest(WebView view, String realm, 467 String account, String args) { 468 } 469 } 470