diff options
author | John Reck <jreck@google.com> | 2012-03-06 17:05:48 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-03-06 17:05:48 -0800 |
commit | e6725bcba58146688960631b0d925a1fe1f39772 (patch) | |
tree | 380588006a778c4fa15c02bf35f9c5e08de07c23 /core | |
parent | ff8025b994c2c7ba3bf13aebd93a74c67e6a6f3c (diff) | |
parent | 4fa40371b3d284e9112838ac64cb4b44e0627f55 (diff) | |
download | frameworks_base-e6725bcba58146688960631b0d925a1fe1f39772.zip frameworks_base-e6725bcba58146688960631b0d925a1fe1f39772.tar.gz frameworks_base-e6725bcba58146688960631b0d925a1fe1f39772.tar.bz2 |
Merge "Fix unhandled navigation path"
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/webkit/WebViewClassic.java | 66 | ||||
-rw-r--r-- | core/java/android/webkit/WebViewCore.java | 79 |
2 files changed, 112 insertions, 33 deletions
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java index c9a3ff1..2926cd5 100644 --- a/core/java/android/webkit/WebViewClassic.java +++ b/core/java/android/webkit/WebViewClassic.java @@ -1121,7 +1121,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc static final int WEBCORE_INITIALIZED_MSG_ID = 107; static final int UPDATE_TEXTFIELD_TEXT_MSG_ID = 108; static final int UPDATE_ZOOM_RANGE = 109; - static final int UNHANDLED_NAV_KEY = 110; + static final int TAKE_FOCUS = 110; static final int CLEAR_TEXT_ENTRY = 111; static final int UPDATE_TEXT_SELECTION_MSG_ID = 112; static final int SHOW_RECT_MSG_ID = 113; @@ -5309,8 +5309,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc if (keyCode >= KeyEvent.KEYCODE_DPAD_UP && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) { switchOutDrawHistory(); - letPageHandleNavKey(keyCode, event.getEventTime(), true, event.getMetaState()); - return true; } if (isEnterActionKey(keyCode)) { @@ -5342,7 +5340,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } // pass the key to DOM - mWebViewCore.sendMessage(EventHub.KEY_DOWN, event); + sendKeyEvent(event); // return true as DOM handles the key return true; } @@ -5405,12 +5403,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } } - if (keyCode >= KeyEvent.KEYCODE_DPAD_UP - && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) { - letPageHandleNavKey(keyCode, event.getEventTime(), false, event.getMetaState()); - return true; - } - if (isEnterActionKey(keyCode)) { // remove the long press message first mPrivateHandler.removeMessages(LONG_PRESS_CENTER); @@ -5424,7 +5416,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } // pass the key to DOM - mWebViewCore.sendMessage(EventHub.KEY_UP, event); + sendKeyEvent(event); // return true as DOM handles the key return true; } @@ -6956,9 +6948,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc case KeyEvent.KEYCODE_DPAD_LEFT: return SoundEffectConstants.NAVIGATION_LEFT; } - throw new IllegalArgumentException("keyCode must be one of " + - "{KEYCODE_DPAD_UP, KEYCODE_DPAD_RIGHT, KEYCODE_DPAD_DOWN, " + - "KEYCODE_DPAD_LEFT}."); + return 0; } private void doTrackball(long time, int metaState) { @@ -8232,8 +8222,12 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc case FORM_DID_BLUR: // TODO: Figure out if this is needed for something (b/6111763) break; - case UNHANDLED_NAV_KEY: - // TODO: Support this (b/6109044) + case TAKE_FOCUS: + int direction = msg.arg1; + View focusSearch = mWebView.focusSearch(direction); + if (focusSearch != null && focusSearch != mWebView) { + focusSearch.requestFocus(); + } break; case CLEAR_TEXT_ENTRY: hideSoftKeyboard(); @@ -9129,14 +9123,10 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc */ private void letPageHandleNavKey(int keyCode, long time, boolean down, int metaState) { int keyEventAction; - int eventHubAction; if (down) { keyEventAction = KeyEvent.ACTION_DOWN; - eventHubAction = EventHub.KEY_DOWN; - mWebView.playSoundEffect(keyCodeToSoundsEffect(keyCode)); } else { keyEventAction = KeyEvent.ACTION_UP; - eventHubAction = EventHub.KEY_UP; } KeyEvent event = new KeyEvent(time, time, keyEventAction, keyCode, @@ -9144,7 +9134,41 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc | (metaState & KeyEvent.META_ALT_ON) | (metaState & KeyEvent.META_SYM_ON) , KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0); - mWebViewCore.sendMessage(eventHubAction, event); + sendKeyEvent(event); + } + + private void sendKeyEvent(KeyEvent event) { + int direction = 0; + switch (event.getKeyCode()) { + case KeyEvent.KEYCODE_DPAD_DOWN: + direction = View.FOCUS_DOWN; + break; + case KeyEvent.KEYCODE_DPAD_UP: + direction = View.FOCUS_UP; + break; + case KeyEvent.KEYCODE_DPAD_LEFT: + direction = View.FOCUS_LEFT; + break; + case KeyEvent.KEYCODE_DPAD_RIGHT: + direction = View.FOCUS_RIGHT; + break; + case KeyEvent.KEYCODE_TAB: + direction = event.isShiftPressed() ? View.FOCUS_BACKWARD : View.FOCUS_FORWARD; + break; + } + if (direction != 0 && mWebView.focusSearch(direction) == null) { + // Can't take focus in that direction + direction = 0; + } + int eventHubAction = EventHub.KEY_UP; + if (event.getAction() == KeyEvent.ACTION_DOWN) { + eventHubAction = EventHub.KEY_DOWN; + int sound = keyCodeToSoundsEffect(event.getKeyCode()); + if (sound != 0) { + mWebView.playSoundEffect(sound); + } + } + mWebViewCore.sendMessage(eventHubAction, direction, event); } /** diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 65356f5..09aa286 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -139,6 +139,8 @@ public final class WebViewCore { private int mHighMemoryUsageThresholdMb; private int mHighUsageDeltaMb; + private int mChromeCanFocusDirection; + // The thread name used to identify the WebCore thread and for use in // debugging other classes that require operation within the WebCore thread. /* package */ static final String THREAD_NAME = "WebViewCoreThread"; @@ -344,6 +346,58 @@ public final class WebViewCore { } /** + * Called by JNI to advance focus to the next view. + */ + private void chromeTakeFocus(int webkitDirection) { + if (mWebView == null) return; + Message m = mWebView.mPrivateHandler.obtainMessage( + WebViewClassic.TAKE_FOCUS); + m.arg1 = mapDirection(webkitDirection); + m.sendToTarget(); + } + + /** + * Called by JNI to see if we can take focus in the given direction. + */ + private boolean chromeCanTakeFocus(int webkitDirection) { + int direction = mapDirection(webkitDirection); + return direction == mChromeCanFocusDirection && direction != 0; + } + + /** + * Maps a Webkit focus direction to a framework one + */ + private int mapDirection(int webkitDirection) { + /* + * This is WebKit's FocusDirection enum (from FocusDirection.h) + enum FocusDirection { + FocusDirectionNone = 0, + FocusDirectionForward, + FocusDirectionBackward, + FocusDirectionUp, + FocusDirectionDown, + FocusDirectionLeft, + FocusDirectionRight + }; + */ + switch (webkitDirection) { + case 1: + return View.FOCUS_FORWARD; + case 2: + return View.FOCUS_BACKWARD; + case 3: + return View.FOCUS_UP; + case 4: + return View.FOCUS_DOWN; + case 5: + return View.FOCUS_LEFT; + case 6: + return View.FOCUS_RIGHT; + } + return 0; + } + + /** * Called by JNI. Open a file chooser to upload a file. * @param acceptType The value of the 'accept' attribute of the * input tag associated with this file picker. @@ -1311,11 +1365,11 @@ public final class WebViewCore { break; case KEY_DOWN: - key((KeyEvent) msg.obj, true); + key((KeyEvent) msg.obj, msg.arg1, true); break; case KEY_UP: - key((KeyEvent) msg.obj, false); + key((KeyEvent) msg.obj, msg.arg1, false); break; case KEY_PRESS: @@ -1950,11 +2004,12 @@ public final class WebViewCore { return mBrowserFrame.saveWebArchive(filename, autoname); } - private void key(KeyEvent evt, boolean isDown) { + private void key(KeyEvent evt, int canTakeFocusDirection, boolean isDown) { if (DebugFlags.WEB_VIEW_CORE) { Log.v(LOGTAG, "CORE key at " + System.currentTimeMillis() + ", " + evt); } + mChromeCanFocusDirection = canTakeFocusDirection; int keyCode = evt.getKeyCode(); int unicodeChar = evt.getUnicodeChar(); @@ -1964,18 +2019,18 @@ public final class WebViewCore { unicodeChar = evt.getCharacters().codePointAt(0); } - if (!nativeKey(mNativeClass, keyCode, unicodeChar, evt.getRepeatCount(), + boolean handled = nativeKey(mNativeClass, keyCode, unicodeChar, evt.getRepeatCount(), evt.isShiftPressed(), evt.isAltPressed(), - evt.isSymPressed(), isDown) && keyCode != KeyEvent.KEYCODE_ENTER) { + evt.isSymPressed(), isDown); + mChromeCanFocusDirection = 0; + if (!handled && keyCode != KeyEvent.KEYCODE_ENTER) { if (keyCode >= KeyEvent.KEYCODE_DPAD_UP && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) { - if (DebugFlags.WEB_VIEW_CORE) { - Log.v(LOGTAG, "key: arrow unused by page: " + keyCode); - } - if (mWebView != null && evt.isDown()) { - Message.obtain(mWebView.mPrivateHandler, - WebViewClassic.UNHANDLED_NAV_KEY, keyCode, - 0).sendToTarget(); + if (canTakeFocusDirection != 0 && isDown) { + Message m = mWebView.mPrivateHandler.obtainMessage( + WebViewClassic.TAKE_FOCUS); + m.arg1 = canTakeFocusDirection; + m.sendToTarget(); } return; } |