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