Loading core/java/android/webkit/WebViewClassic.java +45 −21 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)) { Loading Loading @@ -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; } Loading Loading @@ -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); Loading @@ -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; } Loading Loading @@ -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) { Loading Loading @@ -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(); Loading Loading @@ -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, Loading @@ -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); } /** Loading core/java/android/webkit/WebViewCore.java +67 −12 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -343,6 +345,58 @@ public final class WebViewCore { .sendToTarget(); } /** * 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 Loading Loading @@ -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: Loading Loading @@ -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(); Loading @@ -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; } Loading Loading
core/java/android/webkit/WebViewClassic.java +45 −21 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)) { Loading Loading @@ -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; } Loading Loading @@ -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); Loading @@ -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; } Loading Loading @@ -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) { Loading Loading @@ -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(); Loading Loading @@ -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, Loading @@ -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); } /** Loading
core/java/android/webkit/WebViewCore.java +67 −12 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -343,6 +345,58 @@ public final class WebViewCore { .sendToTarget(); } /** * 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 Loading Loading @@ -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: Loading Loading @@ -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(); Loading @@ -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; } Loading