1 // Copyright 2013 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.os.Handler;
8 import android.os.Message;
9 import android.util.Log;
10 import android.view.KeyEvent;
11 import android.view.View;
12 import android.webkit.ConsoleMessage;
13 import android.webkit.ValueCallback;
15 import org.chromium.base.ThreadUtils;
16 import org.chromium.content.browser.ContentViewCore;
19 * Adapts the AwWebContentsDelegate interface to the AwContentsClient interface.
20 * This class also serves a secondary function of routing certain callbacks from the content layer
21 * to specific listener interfaces.
23 class AwWebContentsDelegateAdapter extends AwWebContentsDelegate {
24 private static final String TAG = "AwWebContentsDelegateAdapter";
26 final AwContentsClient mContentsClient;
29 public AwWebContentsDelegateAdapter(AwContentsClient contentsClient,
31 mContentsClient = contentsClient;
32 setContainerView(containerView);
35 public void setContainerView(View containerView) {
36 mContainerView = containerView;
40 public void onLoadProgressChanged(int progress) {
41 mContentsClient.onProgressChanged(progress);
45 public void handleKeyboardEvent(KeyEvent event) {
46 if (event.getAction() == KeyEvent.ACTION_DOWN) {
48 switch (event.getKeyCode()) {
49 case KeyEvent.KEYCODE_DPAD_DOWN:
50 direction = View.FOCUS_DOWN;
52 case KeyEvent.KEYCODE_DPAD_UP:
53 direction = View.FOCUS_UP;
55 case KeyEvent.KEYCODE_DPAD_LEFT:
56 direction = View.FOCUS_LEFT;
58 case KeyEvent.KEYCODE_DPAD_RIGHT:
59 direction = View.FOCUS_RIGHT;
65 if (direction != 0 && tryToMoveFocus(direction)) return;
67 mContentsClient.onUnhandledKeyEvent(event);
71 public boolean takeFocus(boolean reverse) {
73 (reverse == (mContainerView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL)) ?
74 View.FOCUS_RIGHT : View.FOCUS_LEFT;
75 if (tryToMoveFocus(direction)) return true;
76 direction = reverse ? View.FOCUS_UP : View.FOCUS_DOWN;
77 return tryToMoveFocus(direction);
80 private boolean tryToMoveFocus(int direction) {
81 View focus = mContainerView.focusSearch(direction);
82 return focus != null && focus != mContainerView && focus.requestFocus();
86 public boolean addMessageToConsole(int level, String message, int lineNumber,
88 ConsoleMessage.MessageLevel messageLevel = ConsoleMessage.MessageLevel.DEBUG;
91 messageLevel = ConsoleMessage.MessageLevel.TIP;
94 messageLevel = ConsoleMessage.MessageLevel.LOG;
96 case LOG_LEVEL_WARNING:
97 messageLevel = ConsoleMessage.MessageLevel.WARNING;
100 messageLevel = ConsoleMessage.MessageLevel.ERROR;
103 Log.w(TAG, "Unknown message level, defaulting to DEBUG");
107 return mContentsClient.onConsoleMessage(
108 new ConsoleMessage(message, sourceId, lineNumber, messageLevel));
112 public void onUpdateUrl(String url) {
117 public void openNewTab(String url, String extraHeaders, byte[] postData, int disposition,
118 boolean isRendererInitiated) {
119 // This is only called in chrome layers.
124 public void closeContents() {
125 mContentsClient.onCloseWindow();
129 public void showRepostFormWarningDialog(final ContentViewCore contentViewCore) {
130 // TODO(mkosiba) We should be using something akin to the JsResultReceiver as the
131 // callback parameter (instead of ContentViewCore) and implement a way of converting
132 // that to a pair of messages.
133 final int MSG_CONTINUE_PENDING_RELOAD = 1;
134 final int MSG_CANCEL_PENDING_RELOAD = 2;
136 // TODO(sgurun) Remember the URL to cancel the reload behavior
137 // if it is different than the most recent NavigationController entry.
138 final Handler handler = new Handler(ThreadUtils.getUiThreadLooper()) {
140 public void handleMessage(Message msg) {
142 case MSG_CONTINUE_PENDING_RELOAD: {
143 contentViewCore.continuePendingReload();
146 case MSG_CANCEL_PENDING_RELOAD: {
147 contentViewCore.cancelPendingReload();
151 throw new IllegalStateException(
152 "WebContentsDelegateAdapter: unhandled message " + msg.what);
157 Message resend = handler.obtainMessage(MSG_CONTINUE_PENDING_RELOAD);
158 Message dontResend = handler.obtainMessage(MSG_CANCEL_PENDING_RELOAD);
159 mContentsClient.onFormResubmission(dontResend, resend);
163 public void runFileChooser(final int processId, final int renderId, final int mode_flags,
164 String acceptTypes, String title, String defaultFilename, boolean capture) {
165 AwContentsClient.FileChooserParams params = new AwContentsClient.FileChooserParams();
166 params.mode = mode_flags;
167 params.acceptTypes = acceptTypes;
168 params.title = title;
169 params.defaultFilename = defaultFilename;
170 params.capture = capture;
172 mContentsClient.showFileChooser(new ValueCallback<String[]>() {
173 boolean completed = false;
175 public void onReceiveValue(String[] results) {
177 throw new IllegalStateException("Duplicate showFileChooser result");
180 nativeFilesSelectedInChooser(processId, renderId, mode_flags, results);
186 public boolean addNewContents(boolean isDialog, boolean isUserGesture) {
187 return mContentsClient.onCreateWindow(isDialog, isUserGesture);
191 public void activateContents() {
192 mContentsClient.onRequestFocus();