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.annotation.Nullable; 20 import android.annotation.SystemApi; 21 import android.content.Intent; 22 import android.content.pm.ActivityInfo; 23 import android.graphics.Bitmap; 24 import android.net.Uri; 25 import android.os.Message; 26 import android.view.View; 27 28 public class WebChromeClient { 29 30 /** 31 * Tell the host application the current progress of loading a page. 32 * @param view The WebView that initiated the callback. 33 * @param newProgress Current page loading progress, represented by 34 * an integer between 0 and 100. 35 */ onProgressChanged(WebView view, int newProgress)36 public void onProgressChanged(WebView view, int newProgress) {} 37 38 /** 39 * Notify the host application of a change in the document title. 40 * @param view The WebView that initiated the callback. 41 * @param title A String containing the new title of the document. 42 */ onReceivedTitle(WebView view, String title)43 public void onReceivedTitle(WebView view, String title) {} 44 45 /** 46 * Notify the host application of a new favicon for the current page. 47 * @param view The WebView that initiated the callback. 48 * @param icon A Bitmap containing the favicon for the current page. 49 */ onReceivedIcon(WebView view, Bitmap icon)50 public void onReceivedIcon(WebView view, Bitmap icon) {} 51 52 /** 53 * Notify the host application of the url for an apple-touch-icon. 54 * @param view The WebView that initiated the callback. 55 * @param url The icon url. 56 * @param precomposed {@code true} if the url is for a precomposed touch icon. 57 */ onReceivedTouchIconUrl(WebView view, String url, boolean precomposed)58 public void onReceivedTouchIconUrl(WebView view, String url, 59 boolean precomposed) {} 60 61 /** 62 * A callback interface used by the host application to notify 63 * the current page that its custom view has been dismissed. 64 */ 65 public interface CustomViewCallback { 66 /** 67 * Invoked when the host application dismisses the 68 * custom view. 69 */ onCustomViewHidden()70 public void onCustomViewHidden(); 71 } 72 73 /** 74 * Notify the host application that the current page has entered full screen mode. After this 75 * call, web content will no longer be rendered in the WebView, but will instead be rendered 76 * in {@code view}. The host application should add this View to a Window which is configured 77 * with {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN} flag in order to 78 * actually display this web content full screen. 79 * 80 * <p>The application may explicitly exit fullscreen mode by invoking {@code callback} (ex. when 81 * the user presses the back button). However, this is generally not necessary as the web page 82 * will often show its own UI to close out of fullscreen. Regardless of how the WebView exits 83 * fullscreen mode, WebView will invoke {@link #onHideCustomView()}, signaling for the 84 * application to remove the custom View. 85 * 86 * <p>If this method is not overridden, WebView will report to the web page it does not support 87 * fullscreen mode and will not honor the web page's request to run in fullscreen mode. 88 * 89 * <p class="note"><b>Note:</b> if overriding this method, the application must also override 90 * {@link #onHideCustomView()}. 91 * 92 * @param view is the View object to be shown. 93 * @param callback invoke this callback to request the page to exit 94 * full screen mode. 95 */ onShowCustomView(View view, CustomViewCallback callback)96 public void onShowCustomView(View view, CustomViewCallback callback) {}; 97 98 /** 99 * Notify the host application that the current page would 100 * like to show a custom View in a particular orientation. 101 * @param view is the View object to be shown. 102 * @param requestedOrientation An orientation constant as used in 103 * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}. 104 * @param callback is the callback to be invoked if and when the view 105 * is dismissed. 106 * @deprecated This method supports the obsolete plugin mechanism, 107 * and will not be invoked in future 108 */ 109 @Deprecated onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback)110 public void onShowCustomView(View view, int requestedOrientation, 111 CustomViewCallback callback) {}; 112 113 /** 114 * Notify the host application that the current page has exited full screen mode. The host 115 * application must hide the custom View (the View which was previously passed to {@link 116 * #onShowCustomView(View, CustomViewCallback) onShowCustomView()}). After this call, web 117 * content will render in the original WebView again. 118 * 119 * <p class="note"><b>Note:</b> if overriding this method, the application must also override 120 * {@link #onShowCustomView(View, CustomViewCallback) onShowCustomView()}. 121 */ onHideCustomView()122 public void onHideCustomView() {} 123 124 /** 125 * Request the host application to create a new window. If the host 126 * application chooses to honor this request, it should return {@code true} from 127 * this method, create a new WebView to host the window, insert it into the 128 * View system and send the supplied resultMsg message to its target with 129 * the new WebView as an argument. If the host application chooses not to 130 * honor the request, it should return {@code false} from this method. The default 131 * implementation of this method does nothing and hence returns {@code false}. 132 * <p> 133 * Applications should typically not allow windows to be created when the 134 * {@code isUserGesture} flag is false, as this may be an unwanted popup. 135 * <p> 136 * Applications should be careful how they display the new window: don't simply 137 * overlay it over the existing WebView as this may mislead the user about which 138 * site they are viewing. If your application displays the URL of the main page, 139 * make sure to also display the URL of the new window in a similar fashion. If 140 * your application does not display URLs, consider disallowing the creation of 141 * new windows entirely. 142 * <p class="note"><b>Note:</b> There is no trustworthy way to tell which page 143 * requested the new window: the request might originate from a third-party iframe 144 * inside the WebView. 145 * 146 * @param view The WebView from which the request for a new window 147 * originated. 148 * @param isDialog {@code true} if the new window should be a dialog, rather than 149 * a full-size window. 150 * @param isUserGesture {@code true} if the request was initiated by a user gesture, 151 * such as the user clicking a link. 152 * @param resultMsg The message to send when once a new WebView has been 153 * created. resultMsg.obj is a 154 * {@link WebView.WebViewTransport} object. This should be 155 * used to transport the new WebView, by calling 156 * {@link WebView.WebViewTransport#setWebView(WebView) 157 * WebView.WebViewTransport.setWebView(WebView)}. 158 * @return This method should return {@code true} if the host application will 159 * create a new window, in which case resultMsg should be sent to 160 * its target. Otherwise, this method should return {@code false}. Returning 161 * {@code false} from this method but also sending resultMsg will result in 162 * undefined behavior. 163 */ onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg)164 public boolean onCreateWindow(WebView view, boolean isDialog, 165 boolean isUserGesture, Message resultMsg) { 166 return false; 167 } 168 169 /** 170 * Request display and focus for this WebView. This may happen due to 171 * another WebView opening a link in this WebView and requesting that this 172 * WebView be displayed. 173 * @param view The WebView that needs to be focused. 174 */ onRequestFocus(WebView view)175 public void onRequestFocus(WebView view) {} 176 177 /** 178 * Notify the host application to close the given WebView and remove it 179 * from the view system if necessary. At this point, WebCore has stopped 180 * any loading in this window and has removed any cross-scripting ability 181 * in javascript. 182 * <p> 183 * As with {@link #onCreateWindow}, the application should ensure that any 184 * URL or security indicator displayed is updated so that the user can tell 185 * that the page they were interacting with has been closed. 186 * 187 * @param window The WebView that needs to be closed. 188 */ onCloseWindow(WebView window)189 public void onCloseWindow(WebView window) {} 190 191 /** 192 * Notify the host application that the web page wants to display a 193 * JavaScript {@code alert()} dialog. 194 * <p>The default behavior if this method returns {@code false} or is not 195 * overridden is to show a dialog containing the alert message and suspend 196 * JavaScript execution until the dialog is dismissed. 197 * <p>To show a custom dialog, the app should return {@code true} from this 198 * method, in which case the default dialog will not be shown and JavaScript 199 * execution will be suspended. The app should call 200 * {@code JsResult.confirm()} when the custom dialog is dismissed such that 201 * JavaScript execution can be resumed. 202 * <p>To suppress the dialog and allow JavaScript execution to 203 * continue, call {@code JsResult.confirm()} immediately and then return 204 * {@code true}. 205 * <p>Note that if the {@link WebChromeClient} is set to be {@code null}, 206 * or if {@link WebChromeClient} is not set at all, the default dialog will 207 * be suppressed and Javascript execution will continue immediately. 208 * <p>Note that the default dialog does not inherit the {@link 209 * android.view.Display#FLAG_SECURE} flag from the parent window. 210 * 211 * @param view The WebView that initiated the callback. 212 * @param url The url of the page requesting the dialog. 213 * @param message Message to be displayed in the window. 214 * @param result A JsResult to confirm that the user closed the window. 215 * @return boolean {@code true} if the request is handled or ignored. 216 * {@code false} if WebView needs to show the default dialog. 217 */ onJsAlert(WebView view, String url, String message, JsResult result)218 public boolean onJsAlert(WebView view, String url, String message, 219 JsResult result) { 220 return false; 221 } 222 223 /** 224 * Notify the host application that the web page wants to display a 225 * JavaScript {@code confirm()} dialog. 226 * <p>The default behavior if this method returns {@code false} or is not 227 * overridden is to show a dialog containing the message and suspend 228 * JavaScript execution until the dialog is dismissed. The default dialog 229 * will return {@code true} to the JavaScript {@code confirm()} code when 230 * the user presses the 'confirm' button, and will return {@code false} to 231 * the JavaScript code when the user presses the 'cancel' button or 232 * dismisses the dialog. 233 * <p>To show a custom dialog, the app should return {@code true} from this 234 * method, in which case the default dialog will not be shown and JavaScript 235 * execution will be suspended. The app should call 236 * {@code JsResult.confirm()} or {@code JsResult.cancel()} when the custom 237 * dialog is dismissed. 238 * <p>To suppress the dialog and allow JavaScript execution to continue, 239 * call {@code JsResult.confirm()} or {@code JsResult.cancel()} immediately 240 * and then return {@code true}. 241 * <p>Note that if the {@link WebChromeClient} is set to be {@code null}, 242 * or if {@link WebChromeClient} is not set at all, the default dialog will 243 * be suppressed and the default value of {@code false} will be returned to 244 * the JavaScript code immediately. 245 * <p>Note that the default dialog does not inherit the {@link 246 * android.view.Display#FLAG_SECURE} flag from the parent window. 247 * 248 * @param view The WebView that initiated the callback. 249 * @param url The url of the page requesting the dialog. 250 * @param message Message to be displayed in the window. 251 * @param result A JsResult used to send the user's response to 252 * javascript. 253 * @return boolean {@code true} if the request is handled or ignored. 254 * {@code false} if WebView needs to show the default dialog. 255 */ onJsConfirm(WebView view, String url, String message, JsResult result)256 public boolean onJsConfirm(WebView view, String url, String message, 257 JsResult result) { 258 return false; 259 } 260 261 /** 262 * Notify the host application that the web page wants to display a 263 * JavaScript {@code prompt()} dialog. 264 * <p>The default behavior if this method returns {@code false} or is not 265 * overridden is to show a dialog containing the message and suspend 266 * JavaScript execution until the dialog is dismissed. Once the dialog is 267 * dismissed, JavaScript {@code prompt()} will return the string that the 268 * user typed in, or null if the user presses the 'cancel' button. 269 * <p>To show a custom dialog, the app should return {@code true} from this 270 * method, in which case the default dialog will not be shown and JavaScript 271 * execution will be suspended. The app should call 272 * {@code JsPromptResult.confirm(result)} when the custom dialog is 273 * dismissed. 274 * <p>To suppress the dialog and allow JavaScript execution to continue, 275 * call {@code JsPromptResult.confirm(result)} immediately and then 276 * return {@code true}. 277 * <p>Note that if the {@link WebChromeClient} is set to be {@code null}, 278 * or if {@link WebChromeClient} is not set at all, the default dialog will 279 * be suppressed and {@code null} will be returned to the JavaScript code 280 * immediately. 281 * <p>Note that the default dialog does not inherit the {@link 282 * android.view.Display#FLAG_SECURE} flag from the parent window. 283 * 284 * @param view The WebView that initiated the callback. 285 * @param url The url of the page requesting the dialog. 286 * @param message Message to be displayed in the window. 287 * @param defaultValue The default value displayed in the prompt dialog. 288 * @param result A JsPromptResult used to send the user's reponse to 289 * javascript. 290 * @return boolean {@code true} if the request is handled or ignored. 291 * {@code false} if WebView needs to show the default dialog. 292 */ onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result)293 public boolean onJsPrompt(WebView view, String url, String message, 294 String defaultValue, JsPromptResult result) { 295 return false; 296 } 297 298 /** 299 * Notify the host application that the web page wants to confirm navigation 300 * from JavaScript {@code onbeforeunload}. 301 * <p>The default behavior if this method returns {@code false} or is not 302 * overridden is to show a dialog containing the message and suspend 303 * JavaScript execution until the dialog is dismissed. The default dialog 304 * will continue the navigation if the user confirms the navigation, and 305 * will stop the navigation if the user wants to stay on the current page. 306 * <p>To show a custom dialog, the app should return {@code true} from this 307 * method, in which case the default dialog will not be shown and JavaScript 308 * execution will be suspended. When the custom dialog is dismissed, the 309 * app should call {@code JsResult.confirm()} to continue the navigation or, 310 * {@code JsResult.cancel()} to stay on the current page. 311 * <p>To suppress the dialog and allow JavaScript execution to continue, 312 * call {@code JsResult.confirm()} or {@code JsResult.cancel()} immediately 313 * and then return {@code true}. 314 * <p>Note that if the {@link WebChromeClient} is set to be {@code null}, 315 * or if {@link WebChromeClient} is not set at all, the default dialog will 316 * be suppressed and the navigation will be resumed immediately. 317 * <p>Note that the default dialog does not inherit the {@link 318 * android.view.Display#FLAG_SECURE} flag from the parent window. 319 * 320 * @param view The WebView that initiated the callback. 321 * @param url The url of the page requesting the dialog. 322 * @param message Message to be displayed in the window. 323 * @param result A JsResult used to send the user's response to 324 * javascript. 325 * @return boolean {@code true} if the request is handled or ignored. 326 * {@code false} if WebView needs to show the default dialog. 327 */ onJsBeforeUnload(WebView view, String url, String message, JsResult result)328 public boolean onJsBeforeUnload(WebView view, String url, String message, 329 JsResult result) { 330 return false; 331 } 332 333 /** 334 * Tell the client that the quota has been exceeded for the Web SQL Database 335 * API for a particular origin and request a new quota. The client must 336 * respond by invoking the 337 * {@link WebStorage.QuotaUpdater#updateQuota(long) updateQuota(long)} 338 * method of the supplied {@link WebStorage.QuotaUpdater} instance. The 339 * minimum value that can be set for the new quota is the current quota. The 340 * default implementation responds with the current quota, so the quota will 341 * not be increased. 342 * @param url The URL of the page that triggered the notification 343 * @param databaseIdentifier The identifier of the database where the quota 344 * was exceeded. 345 * @param quota The quota for the origin, in bytes 346 * @param estimatedDatabaseSize The estimated size of the offending 347 * database, in bytes 348 * @param totalQuota The total quota for all origins, in bytes 349 * @param quotaUpdater An instance of {@link WebStorage.QuotaUpdater} which 350 * must be used to inform the WebView of the new quota. 351 * @deprecated This method is no longer called; WebView now uses the HTML5 / JavaScript Quota 352 * Management API. 353 */ 354 @Deprecated onExceededDatabaseQuota(String url, String databaseIdentifier, long quota, long estimatedDatabaseSize, long totalQuota, WebStorage.QuotaUpdater quotaUpdater)355 public void onExceededDatabaseQuota(String url, String databaseIdentifier, 356 long quota, long estimatedDatabaseSize, long totalQuota, 357 WebStorage.QuotaUpdater quotaUpdater) { 358 // This default implementation passes the current quota back to WebCore. 359 // WebCore will interpret this that new quota was declined. 360 quotaUpdater.updateQuota(quota); 361 } 362 363 /** 364 * Notify the host application that the Application Cache has reached the 365 * maximum size. The client must respond by invoking the 366 * {@link WebStorage.QuotaUpdater#updateQuota(long) updateQuota(long)} 367 * method of the supplied {@link WebStorage.QuotaUpdater} instance. The 368 * minimum value that can be set for the new quota is the current quota. The 369 * default implementation responds with the current quota, so the quota will 370 * not be increased. 371 * @param requiredStorage The amount of storage required by the Application 372 * Cache operation that triggered this notification, 373 * in bytes. 374 * @param quota the current maximum Application Cache size, in bytes 375 * @param quotaUpdater An instance of {@link WebStorage.QuotaUpdater} which 376 * must be used to inform the WebView of the new quota. 377 * @deprecated This method is no longer called; WebView now uses the HTML5 / JavaScript Quota 378 * Management API. 379 * @removed This method is no longer called; WebView now uses the HTML5 / JavaScript Quota 380 * Management API. 381 */ 382 @Deprecated onReachedMaxAppCacheSize(long requiredStorage, long quota, WebStorage.QuotaUpdater quotaUpdater)383 public void onReachedMaxAppCacheSize(long requiredStorage, long quota, 384 WebStorage.QuotaUpdater quotaUpdater) { 385 quotaUpdater.updateQuota(quota); 386 } 387 388 /** 389 * Notify the host application that web content from the specified origin 390 * is attempting to use the Geolocation API, but no permission state is 391 * currently set for that origin. The host application should invoke the 392 * specified callback with the desired permission state. See 393 * {@link GeolocationPermissions} for details. 394 * 395 * <p>Note that for applications targeting Android N and later SDKs 396 * (API level > {@link android.os.Build.VERSION_CODES#M}) 397 * this method is only called for requests originating from secure 398 * origins such as https. On non-secure origins geolocation requests 399 * are automatically denied. 400 * 401 * @param origin The origin of the web content attempting to use the 402 * Geolocation API. 403 * @param callback The callback to use to set the permission state for the 404 * origin. 405 */ onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback)406 public void onGeolocationPermissionsShowPrompt(String origin, 407 GeolocationPermissions.Callback callback) {} 408 409 /** 410 * Notify the host application that a request for Geolocation permissions, 411 * made with a previous call to 412 * {@link #onGeolocationPermissionsShowPrompt(String,GeolocationPermissions.Callback) onGeolocationPermissionsShowPrompt()} 413 * has been canceled. Any related UI should therefore be hidden. 414 */ onGeolocationPermissionsHidePrompt()415 public void onGeolocationPermissionsHidePrompt() {} 416 417 /** 418 * Notify the host application that web content is requesting permission to 419 * access the specified resources and the permission currently isn't granted 420 * or denied. The host application must invoke {@link PermissionRequest#grant(String[])} 421 * or {@link PermissionRequest#deny()}. 422 * 423 * If this method isn't overridden, the permission is denied. 424 * 425 * @param request the PermissionRequest from current web content. 426 */ onPermissionRequest(PermissionRequest request)427 public void onPermissionRequest(PermissionRequest request) { 428 request.deny(); 429 } 430 431 /** 432 * Notify the host application that the given permission request 433 * has been canceled. Any related UI should therefore be hidden. 434 * 435 * @param request the PermissionRequest that needs be canceled. 436 */ onPermissionRequestCanceled(PermissionRequest request)437 public void onPermissionRequestCanceled(PermissionRequest request) {} 438 439 /** 440 * Tell the client that a JavaScript execution timeout has occured. And the 441 * client may decide whether or not to interrupt the execution. If the 442 * client returns {@code true}, the JavaScript will be interrupted. If the client 443 * returns {@code false}, the execution will continue. Note that in the case of 444 * continuing execution, the timeout counter will be reset, and the callback 445 * will continue to occur if the script does not finish at the next check 446 * point. 447 * @return boolean Whether the JavaScript execution should be interrupted. 448 * @deprecated This method is no longer supported and will not be invoked. 449 */ 450 // This method was only called when using the JSC javascript engine. V8 became 451 // the default JS engine with Froyo and support for building with JSC was 452 // removed in b/5495373. V8 does not have a mechanism for making a callback such 453 // as this. 454 @Deprecated onJsTimeout()455 public boolean onJsTimeout() { 456 return true; 457 } 458 459 /** 460 * Report a JavaScript error message to the host application. The ChromeClient 461 * should override this to process the log message as they see fit. 462 * @param message The error message to report. 463 * @param lineNumber The line number of the error. 464 * @param sourceID The name of the source file that caused the error. 465 * @deprecated Use {@link #onConsoleMessage(ConsoleMessage) onConsoleMessage(ConsoleMessage)} 466 * instead. 467 */ 468 @Deprecated onConsoleMessage(String message, int lineNumber, String sourceID)469 public void onConsoleMessage(String message, int lineNumber, String sourceID) { } 470 471 /** 472 * Report a JavaScript console message to the host application. The ChromeClient 473 * should override this to process the log message as they see fit. 474 * @param consoleMessage Object containing details of the console message. 475 * @return {@code true} if the message is handled by the client. 476 */ onConsoleMessage(ConsoleMessage consoleMessage)477 public boolean onConsoleMessage(ConsoleMessage consoleMessage) { 478 // Call the old version of this function for backwards compatability. 479 onConsoleMessage(consoleMessage.message(), consoleMessage.lineNumber(), 480 consoleMessage.sourceId()); 481 return false; 482 } 483 484 /** 485 * When not playing, video elements are represented by a 'poster' image. The 486 * image to use can be specified by the poster attribute of the video tag in 487 * HTML. If the attribute is absent, then a default poster will be used. This 488 * method allows the ChromeClient to provide that default image. 489 * 490 * @return Bitmap The image to use as a default poster, or {@code null} if no such image is 491 * available. 492 */ 493 @Nullable getDefaultVideoPoster()494 public Bitmap getDefaultVideoPoster() { 495 return null; 496 } 497 498 /** 499 * Obtains a View to be displayed while buffering of full screen video is taking 500 * place. The host application can override this method to provide a View 501 * containing a spinner or similar. 502 * 503 * @return View The View to be displayed whilst the video is loading. 504 */ 505 @Nullable getVideoLoadingProgressView()506 public View getVideoLoadingProgressView() { 507 return null; 508 } 509 510 /** Obtains a list of all visited history items, used for link coloring 511 */ getVisitedHistory(ValueCallback<String[]> callback)512 public void getVisitedHistory(ValueCallback<String[]> callback) { 513 } 514 515 /** 516 * Tell the client to show a file chooser. 517 * 518 * This is called to handle HTML forms with 'file' input type, in response to the 519 * user pressing the "Select File" button. 520 * To cancel the request, call <code>filePathCallback.onReceiveValue(null)</code> and 521 * return {@code true}. 522 * 523 * <p class="note"><b>Note:</b> WebView does not enforce any restrictions on 524 * the chosen file(s). WebView can access all files that your app can access. 525 * In case the file(s) are chosen through an untrusted source such as a third-party 526 * app, it is your own app's responsibility to check what the returned Uris 527 * refer to before calling the <code>filePathCallback</code>. See 528 * {@link #createIntent} and {@link #parseResult} for more details.</p> 529 * 530 * @param webView The WebView instance that is initiating the request. 531 * @param filePathCallback Invoke this callback to supply the list of paths to files to upload, 532 * or {@code null} to cancel. Must only be called if the 533 * {@link #onShowFileChooser} implementation returns {@code true}. 534 * @param fileChooserParams Describes the mode of file chooser to be opened, and options to be 535 * used with it. 536 * @return {@code true} if filePathCallback will be invoked, {@code false} to use default 537 * handling. 538 * 539 * @see FileChooserParams 540 */ onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams)541 public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, 542 FileChooserParams fileChooserParams) { 543 return false; 544 } 545 546 /** 547 * Parameters used in the {@link #onShowFileChooser} method. 548 */ 549 public static abstract class FileChooserParams { 550 /** Open single file. Requires that the file exists before allowing the user to pick it. */ 551 public static final int MODE_OPEN = 0; 552 /** Like Open but allows multiple files to be selected. */ 553 public static final int MODE_OPEN_MULTIPLE = 1; 554 /** Like Open but allows a folder to be selected. The implementation should enumerate 555 all files selected by this operation. 556 This feature is not supported at the moment. 557 @hide */ 558 public static final int MODE_OPEN_FOLDER = 2; 559 /** Allows picking a nonexistent file and saving it. */ 560 public static final int MODE_SAVE = 3; 561 562 /** 563 * Parse the result returned by the file picker activity. This method should be used with 564 * {@link #createIntent}. Refer to {@link #createIntent} for how to use it. 565 * 566 * <p class="note"><b>Note:</b> The intent returned by the file picker activity 567 * should be treated as untrusted. A third-party app handling the implicit 568 * intent created by {@link #createIntent} might return Uris that the third-party 569 * app itself does not have access to, such as your own app's sensitive data files. 570 * WebView does not enforce any restrictions on the returned Uris. It is the 571 * app's responsibility to ensure that the untrusted source (such as a third-party 572 * app) has access the Uris it has returned and that the Uris are not pointing 573 * to any sensitive data files.</p> 574 * 575 * @param resultCode the integer result code returned by the file picker activity. 576 * @param data the intent returned by the file picker activity. 577 * @return the Uris of selected file(s) or {@code null} if the resultCode indicates 578 * activity canceled or any other error. 579 */ 580 @Nullable parseResult(int resultCode, Intent data)581 public static Uri[] parseResult(int resultCode, Intent data) { 582 return WebViewFactory.getProvider().getStatics().parseFileChooserResult(resultCode, data); 583 } 584 585 /** 586 * Returns file chooser mode. 587 */ getMode()588 public abstract int getMode(); 589 590 /** 591 * Returns an array of acceptable MIME types. The returned MIME type 592 * could be partial such as audio/*. The array will be empty if no 593 * acceptable types are specified. 594 */ getAcceptTypes()595 public abstract String[] getAcceptTypes(); 596 597 /** 598 * Returns preference for a live media captured value (e.g. Camera, Microphone). 599 * True indicates capture is enabled, {@code false} disabled. 600 * 601 * Use <code>getAcceptTypes</code> to determine suitable capture devices. 602 */ isCaptureEnabled()603 public abstract boolean isCaptureEnabled(); 604 605 /** 606 * Returns the title to use for this file selector. If {@code null} a default title should 607 * be used. 608 */ 609 @Nullable getTitle()610 public abstract CharSequence getTitle(); 611 612 /** 613 * The file name of a default selection if specified, or {@code null}. 614 */ 615 @Nullable getFilenameHint()616 public abstract String getFilenameHint(); 617 618 /** 619 * Creates an intent that would start a file picker for file selection. 620 * The Intent supports choosing files from simple file sources available 621 * on the device. Some advanced sources (for example, live media capture) 622 * may not be supported and applications wishing to support these sources 623 * or more advanced file operations should build their own Intent. 624 * 625 * <p>How to use: 626 * <ol> 627 * <li>Build an intent using {@link #createIntent}</li> 628 * <li>Fire the intent using {@link android.app.Activity#startActivityForResult}.</li> 629 * <li>Check for ActivityNotFoundException and take a user friendly action if thrown.</li> 630 * <li>Listen the result using {@link android.app.Activity#onActivityResult}</li> 631 * <li>Parse the result using {@link #parseResult} only if media capture was not 632 * requested.</li> 633 * <li>Send the result using filePathCallback of {@link 634 * WebChromeClient#onShowFileChooser}</li> 635 * </ol> 636 * 637 * <p class="note"><b>Note:</b> The created intent may be handled by 638 * third-party applications on device. The received result must be treated 639 * as untrusted as it can contain Uris pointing to your own app's sensitive 640 * data files. Your app should check the resultant Uris in {@link #parseResult} 641 * before calling the <code>filePathCallback</code>.</p> 642 * 643 * @return an Intent that supports basic file chooser sources. 644 */ createIntent()645 public abstract Intent createIntent(); 646 } 647 648 /** 649 * Tell the client to open a file chooser. 650 * @param uploadFile A ValueCallback to set the URI of the file to upload. 651 * onReceiveValue must be called to wake up the thread.a 652 * @param acceptType The value of the 'accept' attribute of the input tag 653 * associated with this file picker. 654 * @param capture The value of the 'capture' attribute of the input tag 655 * associated with this file picker. 656 * 657 * @deprecated Use {@link #onShowFileChooser} instead. 658 * @hide This method was not published in any SDK version. 659 */ 660 @SystemApi 661 @Deprecated openFileChooser(ValueCallback<Uri> uploadFile, String acceptType, String capture)662 public void openFileChooser(ValueCallback<Uri> uploadFile, String acceptType, String capture) { 663 uploadFile.onReceiveValue(null); 664 } 665 } 666