1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 package org.chromium.android_webview;
7 import android.content.pm.ActivityInfo;
8 import android.graphics.Bitmap;
9 import android.graphics.Picture;
10 import android.net.http.SslError;
11 import android.os.Looper;
12 import android.os.Message;
13 import android.view.KeyEvent;
14 import android.view.View;
15 import android.webkit.ConsoleMessage;
16 import android.webkit.GeolocationPermissions;
17 import android.webkit.ValueCallback;
18 import android.webkit.WebChromeClient;
20 import org.chromium.content.browser.ContentViewCore;
21 import org.chromium.content.browser.WebContentsObserverAndroid;
22 import org.chromium.net.NetError;
25 * Base-class that an AwContents embedder derives from to receive callbacks.
26 * This extends ContentViewClient, as in many cases we want to pass-thru ContentViewCore
27 * callbacks right to our embedder, and this setup facilities that.
28 * For any other callbacks we need to make transformations of (e.g. adapt parameters
29 * or perform filtering) we can provide final overrides for methods here, and then introduce
30 * new abstract methods that the our own client must implement.
31 * i.e.: all methods in this class should either be final, or abstract.
33 public abstract class AwContentsClient {
35 private final AwContentsClientCallbackHelper mCallbackHelper;
37 private AwWebContentsObserver mWebContentsObserver;
39 // Last background color reported from the renderer. Holds the sentinal value INVALID_COLOR
41 private int mCachedRendererBackgroundColor = INVALID_COLOR;
43 private static final int INVALID_COLOR = 0;
45 public AwContentsClient() {
46 this(Looper.myLooper());
49 // Alllow injection of the callback thread, for testing.
50 public AwContentsClient(Looper looper) {
51 mCallbackHelper = new AwContentsClientCallbackHelper(looper, this);
54 class AwWebContentsObserver extends WebContentsObserverAndroid {
55 public AwWebContentsObserver(ContentViewCore contentViewCore) {
56 super(contentViewCore);
60 public void didFinishLoad(long frameId, String validatedUrl, boolean isMainFrame) {
62 AwContentsClient.this.onPageFinished(validatedUrl);
67 public void didFailLoad(boolean isProvisionalLoad,
68 boolean isMainFrame, int errorCode, String description, String failingUrl) {
70 if (errorCode != NetError.ERR_ABORTED) {
71 // This error code is generated for the following reasons:
72 // - WebView.stopLoading is called,
73 // - the navigation is intercepted by the embedder via shouldOverrideNavigation.
75 // The Android WebView does not notify the embedder of these situations using
76 // this error code with the WebViewClient.onReceivedError callback.
77 AwContentsClient.this.onReceivedError(
78 ErrorCodeConversionHelper.convertErrorCode(errorCode), description,
81 // Need to call onPageFinished after onReceivedError (if there is an error) for
82 // backwards compatibility with the classic webview.
83 AwContentsClient.this.onPageFinished(failingUrl);
88 public void didNavigateMainFrame(String url, String baseUrl,
89 boolean isNavigationToDifferentPage, boolean isNavigationInPage) {
90 // This is here to emulate the Classic WebView firing onPageFinished for main frame
91 // navigations where only the hash fragment changes.
92 if (isNavigationInPage) {
93 AwContentsClient.this.onPageFinished(url);
98 public void didNavigateAnyFrame(String url, String baseUrl, boolean isReload) {
99 AwContentsClient.this.doUpdateVisitedHistory(url, isReload);
104 final void installWebContentsObserver(ContentViewCore contentViewCore) {
105 if (mWebContentsObserver != null) {
106 mWebContentsObserver.detachFromWebContents();
108 mWebContentsObserver = new AwWebContentsObserver(contentViewCore);
111 final AwContentsClientCallbackHelper getCallbackHelper() {
112 return mCallbackHelper;
115 final int getCachedRendererBackgroundColor() {
116 assert isCachedRendererBackgroundColorValid();
117 return mCachedRendererBackgroundColor;
120 final boolean isCachedRendererBackgroundColorValid() {
121 return mCachedRendererBackgroundColor != INVALID_COLOR;
124 final void onBackgroundColorChanged(int color) {
125 // Avoid storing the sentinal INVALID_COLOR (note that both 0 and 1 are both
126 // fully transparent so this transpose makes no visible difference).
127 mCachedRendererBackgroundColor = color == INVALID_COLOR ? 1 : color;
130 //--------------------------------------------------------------------------------------------
131 // WebView specific methods that map directly to WebViewClient / WebChromeClient
132 //--------------------------------------------------------------------------------------------
135 * Parameters for the {@link AwContentsClient#showFileChooser} method.
137 public static class FileChooserParams {
139 public String acceptTypes;
141 public String defaultFilename;
142 public boolean capture;
145 public abstract void getVisitedHistory(ValueCallback<String[]> callback);
147 public abstract void doUpdateVisitedHistory(String url, boolean isReload);
149 public abstract void onProgressChanged(int progress);
151 public abstract InterceptedRequestData shouldInterceptRequest(String url);
153 public abstract boolean shouldOverrideKeyEvent(KeyEvent event);
155 public abstract boolean shouldOverrideUrlLoading(String url);
157 public abstract void onLoadResource(String url);
159 public abstract void onUnhandledKeyEvent(KeyEvent event);
161 public abstract boolean onConsoleMessage(ConsoleMessage consoleMessage);
163 public abstract void onReceivedHttpAuthRequest(AwHttpAuthHandler handler,
164 String host, String realm);
166 public abstract void onReceivedSslError(ValueCallback<Boolean> callback, SslError error);
168 public abstract void onReceivedLoginRequest(String realm, String account, String args);
170 public abstract void onFormResubmission(Message dontResend, Message resend);
172 public abstract void onDownloadStart(String url, String userAgent, String contentDisposition,
173 String mimeType, long contentLength);
175 // TODO(joth): Make abstract once this has rolled in downstream.
176 public /*abstract*/ void showFileChooser(ValueCallback<String[]> uploadFilePathsCallback,
177 FileChooserParams fileChooserParams) { }
179 public abstract void onGeolocationPermissionsShowPrompt(String origin,
180 GeolocationPermissions.Callback callback);
182 public abstract void onGeolocationPermissionsHidePrompt();
184 public abstract void onScaleChangedScaled(float oldScale, float newScale);
186 protected abstract void handleJsAlert(String url, String message, JsResultReceiver receiver);
188 protected abstract void handleJsBeforeUnload(String url, String message,
189 JsResultReceiver receiver);
191 protected abstract void handleJsConfirm(String url, String message, JsResultReceiver receiver);
193 protected abstract void handleJsPrompt(String url, String message, String defaultValue,
194 JsPromptResultReceiver receiver);
196 protected abstract boolean onCreateWindow(boolean isDialog, boolean isUserGesture);
198 protected abstract void onCloseWindow();
200 public abstract void onReceivedTouchIconUrl(String url, boolean precomposed);
202 public abstract void onReceivedIcon(Bitmap bitmap);
204 public abstract void onReceivedTitle(String title);
206 protected abstract void onRequestFocus();
208 protected abstract View getVideoLoadingProgressView();
210 public abstract void onPageStarted(String url);
212 public abstract void onPageFinished(String url);
214 public abstract void onReceivedError(int errorCode, String description, String failingUrl);
216 // TODO (michaelbai): Remove this method once the same method remove from
217 // WebViewContentsClientAdapter.
218 public void onShowCustomView(View view,
219 int requestedOrientation, WebChromeClient.CustomViewCallback callback) {
222 // TODO (michaelbai): This method should be abstract, having empty body here
223 // makes the merge to the Android easy.
224 public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
225 onShowCustomView(view, ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED, callback);
228 public abstract void onHideCustomView();
230 public abstract Bitmap getDefaultVideoPoster();
232 //--------------------------------------------------------------------------------------------
233 // Other WebView-specific methods
234 //--------------------------------------------------------------------------------------------
236 public abstract void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches,
237 boolean isDoneCounting);
240 * Called whenever there is a new content picture available.
241 * @param picture New picture.
243 public abstract void onNewPicture(Picture picture);