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