blob: 15ed6f7b257544142cb9142f48aa3769454a166a [file] [log] [blame]
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001// 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.
4
5package org.chromium.android_webview;
6
7import android.graphics.Rect;
8import android.os.Handler;
9import android.os.Looper;
10import android.os.Message;
11import android.util.Log;
12import android.view.KeyEvent;
Torne (Richard Coles)58537e22013-09-12 12:10:22 +010013import android.view.View;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010014import android.webkit.ConsoleMessage;
Ben Murdochba5b9a62013-08-12 14:20:17 +010015import android.webkit.ValueCallback;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010016
17import org.chromium.content.browser.ContentViewCore;
18
19/**
20 * Adapts the AwWebContentsDelegate interface to the AwContentsClient interface.
21 * This class also serves a secondary function of routing certain callbacks from the content layer
22 * to specific listener interfaces.
23 */
24class AwWebContentsDelegateAdapter extends AwWebContentsDelegate {
25 private static final String TAG = "AwWebContentsDelegateAdapter";
26
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010027 final AwContentsClient mContentsClient;
Torne (Richard Coles)58537e22013-09-12 12:10:22 +010028 final View mContainerView;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010029
30 public AwWebContentsDelegateAdapter(AwContentsClient contentsClient,
Torne (Richard Coles)58537e22013-09-12 12:10:22 +010031 View containerView) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010032 mContentsClient = contentsClient;
Torne (Richard Coles)58537e22013-09-12 12:10:22 +010033 mContainerView = containerView;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010034 }
35
36 @Override
37 public void onLoadProgressChanged(int progress) {
38 mContentsClient.onProgressChanged(progress);
39 }
40
41 @Override
42 public void handleKeyboardEvent(KeyEvent event) {
Torne (Richard Coles)58537e22013-09-12 12:10:22 +010043 if (event.getAction() == KeyEvent.ACTION_DOWN) {
44 int direction;
45 switch (event.getKeyCode()) {
46 case KeyEvent.KEYCODE_DPAD_DOWN:
47 direction = View.FOCUS_DOWN;
48 break;
49 case KeyEvent.KEYCODE_DPAD_UP:
50 direction = View.FOCUS_UP;
51 break;
52 case KeyEvent.KEYCODE_DPAD_LEFT:
53 direction = View.FOCUS_LEFT;
54 break;
55 case KeyEvent.KEYCODE_DPAD_RIGHT:
56 direction = View.FOCUS_RIGHT;
57 break;
58 default:
59 direction = 0;
60 break;
61 }
62 if (direction != 0 && tryToMoveFocus(direction)) return;
63 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010064 mContentsClient.onUnhandledKeyEvent(event);
65 }
66
67 @Override
Torne (Richard Coles)58537e22013-09-12 12:10:22 +010068 public boolean takeFocus(boolean reverse) {
69 int direction =
70 (reverse == (mContainerView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL)) ?
71 View.FOCUS_RIGHT : View.FOCUS_LEFT;
72 if (tryToMoveFocus(direction)) return true;
73 direction = reverse ? View.FOCUS_UP : View.FOCUS_DOWN;
74 return tryToMoveFocus(direction);
75 }
76
77 private boolean tryToMoveFocus(int direction) {
78 View focus = mContainerView.focusSearch(direction);
79 return focus != null && focus != mContainerView && focus.requestFocus();
80 }
81
82 @Override
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010083 public boolean addMessageToConsole(int level, String message, int lineNumber,
84 String sourceId) {
85 ConsoleMessage.MessageLevel messageLevel = ConsoleMessage.MessageLevel.DEBUG;
86 switch(level) {
87 case LOG_LEVEL_TIP:
88 messageLevel = ConsoleMessage.MessageLevel.TIP;
89 break;
90 case LOG_LEVEL_LOG:
91 messageLevel = ConsoleMessage.MessageLevel.LOG;
92 break;
93 case LOG_LEVEL_WARNING:
94 messageLevel = ConsoleMessage.MessageLevel.WARNING;
95 break;
96 case LOG_LEVEL_ERROR:
97 messageLevel = ConsoleMessage.MessageLevel.ERROR;
98 break;
99 default:
100 Log.w(TAG, "Unknown message level, defaulting to DEBUG");
101 break;
102 }
103
104 return mContentsClient.onConsoleMessage(
105 new ConsoleMessage(message, sourceId, lineNumber, messageLevel));
106 }
107
108 @Override
109 public void onUpdateUrl(String url) {
110 // TODO: implement
111 }
112
113 @Override
Ben Murdoch32409262013-08-07 11:04:47 +0100114 public void openNewTab(String url, String extraHeaders, byte[] postData, int disposition) {
Ben Murdochba5b9a62013-08-12 14:20:17 +0100115 // This is only called in chrome layers.
116 assert false;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100117 }
118
119 @Override
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100120 public void closeContents() {
121 mContentsClient.onCloseWindow();
122 }
123
124 @Override
125 public void showRepostFormWarningDialog(final ContentViewCore contentViewCore) {
126 // TODO(mkosiba) We should be using something akin to the JsResultReceiver as the
127 // callback parameter (instead of ContentViewCore) and implement a way of converting
128 // that to a pair of messages.
129 final int MSG_CONTINUE_PENDING_RELOAD = 1;
130 final int MSG_CANCEL_PENDING_RELOAD = 2;
131
132 // TODO(sgurun) Remember the URL to cancel the reload behavior
133 // if it is different than the most recent NavigationController entry.
134 final Handler handler = new Handler(Looper.getMainLooper()) {
135 @Override
136 public void handleMessage(Message msg) {
137 switch(msg.what) {
138 case MSG_CONTINUE_PENDING_RELOAD: {
139 contentViewCore.continuePendingReload();
140 break;
141 }
142 case MSG_CANCEL_PENDING_RELOAD: {
143 contentViewCore.cancelPendingReload();
144 break;
145 }
146 default:
147 throw new IllegalStateException(
148 "WebContentsDelegateAdapter: unhandled message " + msg.what);
149 }
150 }
151 };
152
153 Message resend = handler.obtainMessage(MSG_CONTINUE_PENDING_RELOAD);
154 Message dontResend = handler.obtainMessage(MSG_CANCEL_PENDING_RELOAD);
155 mContentsClient.onFormResubmission(dontResend, resend);
156 }
157
158 @Override
Ben Murdochba5b9a62013-08-12 14:20:17 +0100159 public void runFileChooser(final int processId, final int renderId, final int mode_flags,
160 String acceptTypes, String title, String defaultFilename, boolean capture) {
161 AwContentsClient.FileChooserParams params = new AwContentsClient.FileChooserParams();
162 params.mode = mode_flags;
163 params.acceptTypes = acceptTypes;
164 params.title = title;
165 params.defaultFilename = defaultFilename;
166 params.capture = capture;
167
168 mContentsClient.showFileChooser(new ValueCallback<String[]>() {
169 boolean completed = false;
170 @Override
171 public void onReceiveValue(String[] results) {
172 if (completed) {
173 throw new IllegalStateException("Duplicate showFileChooser result");
174 }
175 completed = true;
176 nativeFilesSelectedInChooser(processId, renderId, mode_flags, results);
177 }
178 }, params);
179 }
180
181 @Override
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100182 public boolean addNewContents(boolean isDialog, boolean isUserGesture) {
183 return mContentsClient.onCreateWindow(isDialog, isUserGesture);
184 }
185
186 @Override
187 public void activateContents() {
188 mContentsClient.onRequestFocus();
189 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100190}