• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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