Loading api/current.txt +2 −1 Original line number Diff line number Diff line Loading @@ -33183,7 +33183,8 @@ package android.webkit { method public void onReceivedSslError(android.webkit.WebView, android.webkit.SslErrorHandler, android.net.http.SslError); method public void onScaleChanged(android.webkit.WebView, float, float); method public deprecated void onTooManyRedirects(android.webkit.WebView, android.os.Message, android.os.Message); method public void onUnhandledKeyEvent(android.webkit.WebView, android.view.KeyEvent); method public void onUnhandledInputEvent(android.webkit.WebView, android.view.InputEvent); method public deprecated void onUnhandledKeyEvent(android.webkit.WebView, android.view.KeyEvent); method public android.webkit.WebResourceResponse shouldInterceptRequest(android.webkit.WebView, java.lang.String); method public boolean shouldOverrideKeyEvent(android.webkit.WebView, android.view.KeyEvent); method public boolean shouldOverrideUrlLoading(android.webkit.WebView, java.lang.String); core/java/android/view/ViewRootImpl.java +75 −33 Original line number Diff line number Diff line Loading @@ -234,6 +234,7 @@ public final class ViewRootImpl implements ViewParent, InputStage mFirstInputStage; InputStage mFirstPostImeInputStage; InputStage mSyntheticInputStage; boolean mWindowAttributesChanged = false; int mWindowAttributesChangesFlag = 0; Loading Loading @@ -599,8 +600,8 @@ public final class ViewRootImpl implements ViewParent, // Set up the input pipeline. CharSequence counterSuffix = attrs.getTitle(); InputStage syntheticInputStage = new SyntheticInputStage(); InputStage viewPostImeStage = new ViewPostImeInputStage(syntheticInputStage); mSyntheticInputStage = new SyntheticInputStage(); InputStage viewPostImeStage = new ViewPostImeInputStage(mSyntheticInputStage); InputStage nativePostImeStage = new NativePostImeInputStage(viewPostImeStage, "aq:native-post-ime:" + counterSuffix); InputStage earlyPostImeStage = new EarlyPostImeInputStage(nativePostImeStage); Loading Loading @@ -3007,6 +3008,7 @@ public final class ViewRootImpl implements ViewParent, private final static int MSG_INVALIDATE_WORLD = 23; private final static int MSG_WINDOW_MOVED = 24; private final static int MSG_FLUSH_LAYER_UPDATES = 25; private final static int MSG_SYNTHESIZE_INPUT_EVENT = 26; final class ViewRootHandler extends Handler { @Override Loading Loading @@ -3056,6 +3058,8 @@ public final class ViewRootImpl implements ViewParent, return "MSG_WINDOW_MOVED"; case MSG_FLUSH_LAYER_UPDATES: return "MSG_FLUSH_LAYER_UPDATES"; case MSG_SYNTHESIZE_INPUT_EVENT: return "MSG_SYNTHESIZE_INPUT_EVENT"; } return super.getMessageName(message); } Loading Loading @@ -3218,6 +3222,10 @@ public final class ViewRootImpl implements ViewParent, enqueueInputEvent(event, receiver, 0, true); args.recycle(); } break; case MSG_SYNTHESIZE_INPUT_EVENT: { InputEvent event = (InputEvent)msg.obj; enqueueInputEvent(event, null, QueuedInputEvent.FLAG_UNHANDLED, true); } break; case MSG_DISPATCH_KEY_FROM_IME: { if (LOCAL_LOGV) Log.v( TAG, "Dispatching key " Loading @@ -3227,7 +3235,8 @@ public final class ViewRootImpl implements ViewParent, // The IME is trying to say this event is from the // system! Bad bad bad! //noinspection UnusedAssignment event = KeyEvent.changeFlags(event, event.getFlags() & ~KeyEvent.FLAG_FROM_SYSTEM); event = KeyEvent.changeFlags(event, event.getFlags() & ~KeyEvent.FLAG_FROM_SYSTEM); } enqueueInputEvent(event, null, QueuedInputEvent.FLAG_DELIVER_POST_IME, true); } break; Loading Loading @@ -4023,6 +4032,7 @@ public final class ViewRootImpl implements ViewParent, private final SyntheticJoystickHandler mJoystick = new SyntheticJoystickHandler(); private final SyntheticTouchNavigationHandler mTouchNavigation = new SyntheticTouchNavigationHandler(); private final SyntheticKeyboardHandler mKeyboard = new SyntheticKeyboardHandler(); public SyntheticInputStage() { super(null); Loading @@ -4045,7 +4055,11 @@ public final class ViewRootImpl implements ViewParent, mTouchNavigation.process(event); return FINISH_HANDLED; } } else if ((q.mFlags & QueuedInputEvent.FLAG_UNHANDLED) != 0) { mKeyboard.process((KeyEvent)q.mEvent); return FINISH_HANDLED; } return FORWARD; } Loading Loading @@ -4882,6 +4896,33 @@ public final class ViewRootImpl implements ViewParent, }; } final class SyntheticKeyboardHandler { public void process(KeyEvent event) { if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) != 0) { return; } final KeyCharacterMap kcm = event.getKeyCharacterMap(); final int keyCode = event.getKeyCode(); final int metaState = event.getMetaState(); // Check for fallback actions specified by the key character map. KeyCharacterMap.FallbackAction fallbackAction = kcm.getFallbackAction(keyCode, metaState); if (fallbackAction != null) { final int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK; KeyEvent fallbackEvent = KeyEvent.obtain( event.getDownTime(), event.getEventTime(), event.getAction(), fallbackAction.keyCode, event.getRepeatCount(), fallbackAction.metaState, event.getDeviceId(), event.getScanCode(), flags, event.getSource(), null); fallbackAction.recycle(); enqueueInputEvent(fallbackEvent); } } } /** * Returns true if the key is used for keyboard navigation. * @param keyEvent The key event. Loading Loading @@ -5461,6 +5502,7 @@ public final class ViewRootImpl implements ViewParent, public static final int FLAG_FINISHED = 1 << 2; public static final int FLAG_FINISHED_HANDLED = 1 << 3; public static final int FLAG_RESYNTHESIZED = 1 << 4; public static final int FLAG_UNHANDLED = 1 << 5; public QueuedInputEvent mNext; Loading @@ -5475,6 +5517,14 @@ public final class ViewRootImpl implements ViewParent, return mEvent instanceof MotionEvent && mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER); } public boolean shouldSendToSynthesizer() { if ((mFlags & FLAG_UNHANDLED) != 0) { return true; } return false; } } private QueuedInputEvent obtainQueuedInputEvent(InputEvent event, Loading Loading @@ -5578,7 +5628,13 @@ public final class ViewRootImpl implements ViewParent, mInputEventConsistencyVerifier.onInputEvent(q.mEvent, 0); } InputStage stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage; InputStage stage; if (q.shouldSendToSynthesizer()) { stage = mSyntheticInputStage; } else { stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage; } if (stage != null) { stage.deliver(q); } else { Loading Loading @@ -5810,43 +5866,29 @@ public final class ViewRootImpl implements ViewParent, mHandler.sendMessage(msg); } public void dispatchKeyFromIme(KeyEvent event) { Message msg = mHandler.obtainMessage(MSG_DISPATCH_KEY_FROM_IME, event); public void synthesizeInputEvent(InputEvent event) { Message msg = mHandler.obtainMessage(MSG_SYNTHESIZE_INPUT_EVENT, event); msg.setAsynchronous(true); mHandler.sendMessage(msg); } public void dispatchUnhandledKey(KeyEvent event) { if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { // Some fallback keys are decided by the ViewRoot as they might have special // properties (e.g. are locale aware). These take precedence over fallbacks defined by // the kcm. final KeyCharacterMap kcm = event.getKeyCharacterMap(); final int keyCode = event.getKeyCode(); final int metaState = event.getMetaState(); // Check for fallback actions specified by the key character map. KeyCharacterMap.FallbackAction fallbackAction = kcm.getFallbackAction(keyCode, metaState); if (fallbackAction != null) { final int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK; KeyEvent fallbackEvent = KeyEvent.obtain( event.getDownTime(), event.getEventTime(), event.getAction(), fallbackAction.keyCode, event.getRepeatCount(), fallbackAction.metaState, event.getDeviceId(), event.getScanCode(), flags, event.getSource(), null); fallbackAction.recycle(); dispatchInputEvent(fallbackEvent); } } public void dispatchKeyFromIme(KeyEvent event) { Message msg = mHandler.obtainMessage(MSG_DISPATCH_KEY_FROM_IME, event); msg.setAsynchronous(true); mHandler.sendMessage(msg); } /** * Reinject unhandled {@link InputEvent}s in order to synthesize fallbacks events. * * Note that it is the responsibility of the caller of this API to recycle the InputEvent it * passes in. */ public void dispatchUnhandledInputEvent(InputEvent event) { if (event instanceof KeyEvent) { dispatchUnhandledKey((KeyEvent) event); return; if (event instanceof MotionEvent) { event = MotionEvent.obtain((MotionEvent) event); } synthesizeInputEvent(event); } public void dispatchAppVisibility(boolean visible) { Loading core/java/android/webkit/WebViewClient.java +33 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.webkit; import android.graphics.Bitmap; import android.net.http.SslError; import android.os.Message; import android.view.InputEvent; import android.view.KeyEvent; import android.view.ViewRootImpl; Loading Loading @@ -272,11 +273,42 @@ public class WebViewClient { * * @param view The WebView that is initiating the callback. * @param event The key event. * @deprecated This method is subsumed by the more generic onUnhandledInputEvent. */ @Deprecated public void onUnhandledKeyEvent(WebView view, KeyEvent event) { onUnhandledInputEventInternal(view, event); } /** * Notify the host application that a input event was not handled by the WebView. * Except system keys, WebView always consumes input events in the normal flow * or if shouldOverrideKeyEvent returns true. This is called asynchronously * from where the event is dispatched. It gives the host application a chance * to handle the unhandled input events. * * Note that if the event is a {@link MotionEvent}, then it's lifetime is only that of the * function call. If the WebViewClient wishes to use the event beyond that, then it <i>must</i> * create a copy of the event. * * It is the responsibility of overriders of this method to call {@link onUnhandledKeyEvent} * when appropriate if they wish to continue receiving events through it. * * @param view The WebView that is initiating the callback. * @param event The input event. */ public void onUnhandledInputEvent(WebView view, InputEvent event) { if (event instanceof KeyEvent) { onUnhandledKeyEvent(view, (KeyEvent) event); return; } onUnhandledInputEventInternal(view, event); } private void onUnhandledInputEventInternal(WebView view, InputEvent event) { ViewRootImpl root = view.getViewRootImpl(); if (root != null) { root.dispatchUnhandledKey(event); root.dispatchUnhandledInputEvent(event); } } Loading Loading
api/current.txt +2 −1 Original line number Diff line number Diff line Loading @@ -33183,7 +33183,8 @@ package android.webkit { method public void onReceivedSslError(android.webkit.WebView, android.webkit.SslErrorHandler, android.net.http.SslError); method public void onScaleChanged(android.webkit.WebView, float, float); method public deprecated void onTooManyRedirects(android.webkit.WebView, android.os.Message, android.os.Message); method public void onUnhandledKeyEvent(android.webkit.WebView, android.view.KeyEvent); method public void onUnhandledInputEvent(android.webkit.WebView, android.view.InputEvent); method public deprecated void onUnhandledKeyEvent(android.webkit.WebView, android.view.KeyEvent); method public android.webkit.WebResourceResponse shouldInterceptRequest(android.webkit.WebView, java.lang.String); method public boolean shouldOverrideKeyEvent(android.webkit.WebView, android.view.KeyEvent); method public boolean shouldOverrideUrlLoading(android.webkit.WebView, java.lang.String);
core/java/android/view/ViewRootImpl.java +75 −33 Original line number Diff line number Diff line Loading @@ -234,6 +234,7 @@ public final class ViewRootImpl implements ViewParent, InputStage mFirstInputStage; InputStage mFirstPostImeInputStage; InputStage mSyntheticInputStage; boolean mWindowAttributesChanged = false; int mWindowAttributesChangesFlag = 0; Loading Loading @@ -599,8 +600,8 @@ public final class ViewRootImpl implements ViewParent, // Set up the input pipeline. CharSequence counterSuffix = attrs.getTitle(); InputStage syntheticInputStage = new SyntheticInputStage(); InputStage viewPostImeStage = new ViewPostImeInputStage(syntheticInputStage); mSyntheticInputStage = new SyntheticInputStage(); InputStage viewPostImeStage = new ViewPostImeInputStage(mSyntheticInputStage); InputStage nativePostImeStage = new NativePostImeInputStage(viewPostImeStage, "aq:native-post-ime:" + counterSuffix); InputStage earlyPostImeStage = new EarlyPostImeInputStage(nativePostImeStage); Loading Loading @@ -3007,6 +3008,7 @@ public final class ViewRootImpl implements ViewParent, private final static int MSG_INVALIDATE_WORLD = 23; private final static int MSG_WINDOW_MOVED = 24; private final static int MSG_FLUSH_LAYER_UPDATES = 25; private final static int MSG_SYNTHESIZE_INPUT_EVENT = 26; final class ViewRootHandler extends Handler { @Override Loading Loading @@ -3056,6 +3058,8 @@ public final class ViewRootImpl implements ViewParent, return "MSG_WINDOW_MOVED"; case MSG_FLUSH_LAYER_UPDATES: return "MSG_FLUSH_LAYER_UPDATES"; case MSG_SYNTHESIZE_INPUT_EVENT: return "MSG_SYNTHESIZE_INPUT_EVENT"; } return super.getMessageName(message); } Loading Loading @@ -3218,6 +3222,10 @@ public final class ViewRootImpl implements ViewParent, enqueueInputEvent(event, receiver, 0, true); args.recycle(); } break; case MSG_SYNTHESIZE_INPUT_EVENT: { InputEvent event = (InputEvent)msg.obj; enqueueInputEvent(event, null, QueuedInputEvent.FLAG_UNHANDLED, true); } break; case MSG_DISPATCH_KEY_FROM_IME: { if (LOCAL_LOGV) Log.v( TAG, "Dispatching key " Loading @@ -3227,7 +3235,8 @@ public final class ViewRootImpl implements ViewParent, // The IME is trying to say this event is from the // system! Bad bad bad! //noinspection UnusedAssignment event = KeyEvent.changeFlags(event, event.getFlags() & ~KeyEvent.FLAG_FROM_SYSTEM); event = KeyEvent.changeFlags(event, event.getFlags() & ~KeyEvent.FLAG_FROM_SYSTEM); } enqueueInputEvent(event, null, QueuedInputEvent.FLAG_DELIVER_POST_IME, true); } break; Loading Loading @@ -4023,6 +4032,7 @@ public final class ViewRootImpl implements ViewParent, private final SyntheticJoystickHandler mJoystick = new SyntheticJoystickHandler(); private final SyntheticTouchNavigationHandler mTouchNavigation = new SyntheticTouchNavigationHandler(); private final SyntheticKeyboardHandler mKeyboard = new SyntheticKeyboardHandler(); public SyntheticInputStage() { super(null); Loading @@ -4045,7 +4055,11 @@ public final class ViewRootImpl implements ViewParent, mTouchNavigation.process(event); return FINISH_HANDLED; } } else if ((q.mFlags & QueuedInputEvent.FLAG_UNHANDLED) != 0) { mKeyboard.process((KeyEvent)q.mEvent); return FINISH_HANDLED; } return FORWARD; } Loading Loading @@ -4882,6 +4896,33 @@ public final class ViewRootImpl implements ViewParent, }; } final class SyntheticKeyboardHandler { public void process(KeyEvent event) { if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) != 0) { return; } final KeyCharacterMap kcm = event.getKeyCharacterMap(); final int keyCode = event.getKeyCode(); final int metaState = event.getMetaState(); // Check for fallback actions specified by the key character map. KeyCharacterMap.FallbackAction fallbackAction = kcm.getFallbackAction(keyCode, metaState); if (fallbackAction != null) { final int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK; KeyEvent fallbackEvent = KeyEvent.obtain( event.getDownTime(), event.getEventTime(), event.getAction(), fallbackAction.keyCode, event.getRepeatCount(), fallbackAction.metaState, event.getDeviceId(), event.getScanCode(), flags, event.getSource(), null); fallbackAction.recycle(); enqueueInputEvent(fallbackEvent); } } } /** * Returns true if the key is used for keyboard navigation. * @param keyEvent The key event. Loading Loading @@ -5461,6 +5502,7 @@ public final class ViewRootImpl implements ViewParent, public static final int FLAG_FINISHED = 1 << 2; public static final int FLAG_FINISHED_HANDLED = 1 << 3; public static final int FLAG_RESYNTHESIZED = 1 << 4; public static final int FLAG_UNHANDLED = 1 << 5; public QueuedInputEvent mNext; Loading @@ -5475,6 +5517,14 @@ public final class ViewRootImpl implements ViewParent, return mEvent instanceof MotionEvent && mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER); } public boolean shouldSendToSynthesizer() { if ((mFlags & FLAG_UNHANDLED) != 0) { return true; } return false; } } private QueuedInputEvent obtainQueuedInputEvent(InputEvent event, Loading Loading @@ -5578,7 +5628,13 @@ public final class ViewRootImpl implements ViewParent, mInputEventConsistencyVerifier.onInputEvent(q.mEvent, 0); } InputStage stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage; InputStage stage; if (q.shouldSendToSynthesizer()) { stage = mSyntheticInputStage; } else { stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage; } if (stage != null) { stage.deliver(q); } else { Loading Loading @@ -5810,43 +5866,29 @@ public final class ViewRootImpl implements ViewParent, mHandler.sendMessage(msg); } public void dispatchKeyFromIme(KeyEvent event) { Message msg = mHandler.obtainMessage(MSG_DISPATCH_KEY_FROM_IME, event); public void synthesizeInputEvent(InputEvent event) { Message msg = mHandler.obtainMessage(MSG_SYNTHESIZE_INPUT_EVENT, event); msg.setAsynchronous(true); mHandler.sendMessage(msg); } public void dispatchUnhandledKey(KeyEvent event) { if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { // Some fallback keys are decided by the ViewRoot as they might have special // properties (e.g. are locale aware). These take precedence over fallbacks defined by // the kcm. final KeyCharacterMap kcm = event.getKeyCharacterMap(); final int keyCode = event.getKeyCode(); final int metaState = event.getMetaState(); // Check for fallback actions specified by the key character map. KeyCharacterMap.FallbackAction fallbackAction = kcm.getFallbackAction(keyCode, metaState); if (fallbackAction != null) { final int flags = event.getFlags() | KeyEvent.FLAG_FALLBACK; KeyEvent fallbackEvent = KeyEvent.obtain( event.getDownTime(), event.getEventTime(), event.getAction(), fallbackAction.keyCode, event.getRepeatCount(), fallbackAction.metaState, event.getDeviceId(), event.getScanCode(), flags, event.getSource(), null); fallbackAction.recycle(); dispatchInputEvent(fallbackEvent); } } public void dispatchKeyFromIme(KeyEvent event) { Message msg = mHandler.obtainMessage(MSG_DISPATCH_KEY_FROM_IME, event); msg.setAsynchronous(true); mHandler.sendMessage(msg); } /** * Reinject unhandled {@link InputEvent}s in order to synthesize fallbacks events. * * Note that it is the responsibility of the caller of this API to recycle the InputEvent it * passes in. */ public void dispatchUnhandledInputEvent(InputEvent event) { if (event instanceof KeyEvent) { dispatchUnhandledKey((KeyEvent) event); return; if (event instanceof MotionEvent) { event = MotionEvent.obtain((MotionEvent) event); } synthesizeInputEvent(event); } public void dispatchAppVisibility(boolean visible) { Loading
core/java/android/webkit/WebViewClient.java +33 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.webkit; import android.graphics.Bitmap; import android.net.http.SslError; import android.os.Message; import android.view.InputEvent; import android.view.KeyEvent; import android.view.ViewRootImpl; Loading Loading @@ -272,11 +273,42 @@ public class WebViewClient { * * @param view The WebView that is initiating the callback. * @param event The key event. * @deprecated This method is subsumed by the more generic onUnhandledInputEvent. */ @Deprecated public void onUnhandledKeyEvent(WebView view, KeyEvent event) { onUnhandledInputEventInternal(view, event); } /** * Notify the host application that a input event was not handled by the WebView. * Except system keys, WebView always consumes input events in the normal flow * or if shouldOverrideKeyEvent returns true. This is called asynchronously * from where the event is dispatched. It gives the host application a chance * to handle the unhandled input events. * * Note that if the event is a {@link MotionEvent}, then it's lifetime is only that of the * function call. If the WebViewClient wishes to use the event beyond that, then it <i>must</i> * create a copy of the event. * * It is the responsibility of overriders of this method to call {@link onUnhandledKeyEvent} * when appropriate if they wish to continue receiving events through it. * * @param view The WebView that is initiating the callback. * @param event The input event. */ public void onUnhandledInputEvent(WebView view, InputEvent event) { if (event instanceof KeyEvent) { onUnhandledKeyEvent(view, (KeyEvent) event); return; } onUnhandledInputEventInternal(view, event); } private void onUnhandledInputEventInternal(WebView view, InputEvent event) { ViewRootImpl root = view.getViewRootImpl(); if (root != null) { root.dispatchUnhandledKey(event); root.dispatchUnhandledInputEvent(event); } } Loading