Loading core/java/android/inputmethodservice/InputMethodService.java +32 −3 Original line number Diff line number Diff line Loading @@ -765,6 +765,7 @@ public class InputMethodService extends AbstractInputMethodService { private boolean mSystemCallingShowSoftInput; private boolean mSystemCallingHideSoftInput; private boolean mSimultaneousStylusAndTouchEnabled; /** * {@inheritDoc} Loading Loading @@ -1129,9 +1130,11 @@ public class InputMethodService extends AbstractInputMethodService { mShowInputRequested = false; mInkWindow.show(); mSimultaneousStylusAndTouchEnabled = com.android.input.flags.Flags.enableMultiDeviceInput(); // deliver previous @param stylusEvents stylusEvents.forEach(InputMethodService.this::onStylusHandwritingMotionEvent); stylusEvents.forEach(this::deliverStylusHandwritingMotionEvent); // create receiver for channel mHandwritingEventReceiver = new InputEventReceiver(channel, Looper.getMainLooper()) { Loading @@ -1139,10 +1142,15 @@ public class InputMethodService extends AbstractInputMethodService { public void onInputEvent(InputEvent event) { boolean handled = false; try { if (!(event instanceof MotionEvent)) { if (!(event instanceof MotionEvent motionEvent)) { return; } onStylusHandwritingMotionEvent((MotionEvent) event); if (!motionEvent.isStylusPointer()) { // Handwriting surface is touchable, we don't want these touch events // to get to the IME. return; } deliverStylusHandwritingMotionEvent(motionEvent); scheduleHandwritingSessionTimeout(); handled = true; } finally { Loading @@ -1153,6 +1161,27 @@ public class InputMethodService extends AbstractInputMethodService { scheduleHandwritingSessionTimeout(); } private void deliverStylusHandwritingMotionEvent(MotionEvent motionEvent) { onStylusHandwritingMotionEvent(motionEvent); if (!mSimultaneousStylusAndTouchEnabled) { return; } switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: // Consume and ignore all touches while stylus is down to prevent // accidental touches from going to the app while writing. mPrivOps.setHandwritingSurfaceNotTouchable(false); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: // Go back to only consuming stylus events so that the user // can continue to interact with the app using touch // when the stylus is not down. mPrivOps.setHandwritingSurfaceNotTouchable(true); break; } } /** * {@inheritDoc} * @hide Loading core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -49,4 +49,5 @@ oneway interface IInputMethodPrivilegedOperations { void onStylusHandwritingReady(int requestId, int pid); void resetStylusHandwriting(int requestId); void switchKeyboardLayoutAsync(int direction); void setHandwritingSurfaceNotTouchable(boolean notTouchable); } core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java +18 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,24 @@ public final class InputMethodPrivilegedOperations { } } /** * Calls {@link IInputMethodPrivilegedOperations#setHandwritingSurfaceNotTouchable(boolean)}. * * @param notTouchable {@code true} to make handwriting surface not-touchable (pass-through). */ @AnyThread public void setHandwritingSurfaceNotTouchable(boolean notTouchable) { final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull(); if (ops == null) { return; } try { ops.setHandwritingSurfaceNotTouchable(notTouchable); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Calls {@link IInputMethodPrivilegedOperations#createInputContentUriToken(Uri, String, * AndroidFuture)}. Loading services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java +11 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,17 @@ final class HandwritingEventReceiverSurface { mIsIntercepting = true; } void setNotTouchable(boolean notTouchable) { if (notTouchable) { mWindowHandle.inputConfig |= InputConfig.NOT_TOUCHABLE; } else { mWindowHandle.inputConfig &= ~InputConfig.NOT_TOUCHABLE; } new SurfaceControl.Transaction() .setInputWindowInfo(mInputSurface, mWindowHandle) .apply(); } boolean isIntercepting() { return mIsIntercepting; } Loading services/core/java/com/android/server/inputmethod/HandwritingModeController.java +7 −0 Original line number Diff line number Diff line Loading @@ -159,6 +159,13 @@ final class HandwritingModeController { return OptionalInt.of(mCurrentRequestId); } void setNotTouchable(boolean notTouchable) { if (!getCurrentRequestId().isPresent()) { return; } mHandwritingSurface.setNotTouchable(notTouchable); } boolean isStylusGestureOngoing() { if (mRecordingGestureAfterStylusUp && !mHandwritingBuffer.isEmpty()) { // If it is less than AFTER_STYLUS_UP_ALLOW_PERIOD_MS after the stylus up event, return Loading Loading
core/java/android/inputmethodservice/InputMethodService.java +32 −3 Original line number Diff line number Diff line Loading @@ -765,6 +765,7 @@ public class InputMethodService extends AbstractInputMethodService { private boolean mSystemCallingShowSoftInput; private boolean mSystemCallingHideSoftInput; private boolean mSimultaneousStylusAndTouchEnabled; /** * {@inheritDoc} Loading Loading @@ -1129,9 +1130,11 @@ public class InputMethodService extends AbstractInputMethodService { mShowInputRequested = false; mInkWindow.show(); mSimultaneousStylusAndTouchEnabled = com.android.input.flags.Flags.enableMultiDeviceInput(); // deliver previous @param stylusEvents stylusEvents.forEach(InputMethodService.this::onStylusHandwritingMotionEvent); stylusEvents.forEach(this::deliverStylusHandwritingMotionEvent); // create receiver for channel mHandwritingEventReceiver = new InputEventReceiver(channel, Looper.getMainLooper()) { Loading @@ -1139,10 +1142,15 @@ public class InputMethodService extends AbstractInputMethodService { public void onInputEvent(InputEvent event) { boolean handled = false; try { if (!(event instanceof MotionEvent)) { if (!(event instanceof MotionEvent motionEvent)) { return; } onStylusHandwritingMotionEvent((MotionEvent) event); if (!motionEvent.isStylusPointer()) { // Handwriting surface is touchable, we don't want these touch events // to get to the IME. return; } deliverStylusHandwritingMotionEvent(motionEvent); scheduleHandwritingSessionTimeout(); handled = true; } finally { Loading @@ -1153,6 +1161,27 @@ public class InputMethodService extends AbstractInputMethodService { scheduleHandwritingSessionTimeout(); } private void deliverStylusHandwritingMotionEvent(MotionEvent motionEvent) { onStylusHandwritingMotionEvent(motionEvent); if (!mSimultaneousStylusAndTouchEnabled) { return; } switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: // Consume and ignore all touches while stylus is down to prevent // accidental touches from going to the app while writing. mPrivOps.setHandwritingSurfaceNotTouchable(false); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: // Go back to only consuming stylus events so that the user // can continue to interact with the app using touch // when the stylus is not down. mPrivOps.setHandwritingSurfaceNotTouchable(true); break; } } /** * {@inheritDoc} * @hide Loading
core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -49,4 +49,5 @@ oneway interface IInputMethodPrivilegedOperations { void onStylusHandwritingReady(int requestId, int pid); void resetStylusHandwriting(int requestId); void switchKeyboardLayoutAsync(int direction); void setHandwritingSurfaceNotTouchable(boolean notTouchable); }
core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java +18 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,24 @@ public final class InputMethodPrivilegedOperations { } } /** * Calls {@link IInputMethodPrivilegedOperations#setHandwritingSurfaceNotTouchable(boolean)}. * * @param notTouchable {@code true} to make handwriting surface not-touchable (pass-through). */ @AnyThread public void setHandwritingSurfaceNotTouchable(boolean notTouchable) { final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull(); if (ops == null) { return; } try { ops.setHandwritingSurfaceNotTouchable(notTouchable); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Calls {@link IInputMethodPrivilegedOperations#createInputContentUriToken(Uri, String, * AndroidFuture)}. Loading
services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java +11 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,17 @@ final class HandwritingEventReceiverSurface { mIsIntercepting = true; } void setNotTouchable(boolean notTouchable) { if (notTouchable) { mWindowHandle.inputConfig |= InputConfig.NOT_TOUCHABLE; } else { mWindowHandle.inputConfig &= ~InputConfig.NOT_TOUCHABLE; } new SurfaceControl.Transaction() .setInputWindowInfo(mInputSurface, mWindowHandle) .apply(); } boolean isIntercepting() { return mIsIntercepting; } Loading
services/core/java/com/android/server/inputmethod/HandwritingModeController.java +7 −0 Original line number Diff line number Diff line Loading @@ -159,6 +159,13 @@ final class HandwritingModeController { return OptionalInt.of(mCurrentRequestId); } void setNotTouchable(boolean notTouchable) { if (!getCurrentRequestId().isPresent()) { return; } mHandwritingSurface.setNotTouchable(notTouchable); } boolean isStylusGestureOngoing() { if (mRecordingGestureAfterStylusUp && !mHandwritingBuffer.isEmpty()) { // If it is less than AFTER_STYLUS_UP_ALLOW_PERIOD_MS after the stylus up event, return Loading