diff options
| author | Taran Singh <tarandeep@google.com> | 2022-03-02 10:43:55 +0000 |
|---|---|---|
| committer | Taran Singh <tarandeep@google.com> | 2022-03-09 18:35:21 +0000 |
| commit | 467fd168d5480e8c93b4f947fc9ce3216f887b2e (patch) | |
| tree | 4f97a6dabd1f044896d7ca2cb257e6cb16e27a55 /core/java/android/inputmethodservice/InputMethodService.java | |
| parent | e2722fe948b428ccc4679ce9466618a773225ebb (diff) | |
Introduce new IMS method for Stylus events and dispatch
As of today we show the InkWindow and dispatch Stylus events without
waiting. At the time of dispatch, InkWindow is not added and first stylus gesture
is skipped. In order to deliver the first gesture to IME, we should wait until
InkWindow is added and IME's Inking View is attached.
However, waiting for it will introduce latency in the system. To counter
that, we introduce a new API method to listen for Stylus MotionEvent.
IME can override the API method to listen to MotionEvents sooner.
By default, the stylus MotionEvents are buffered until Ink view is visible.
Change-Id: I3a18067da45fd15bf0f6e377da0a82cdd6df1d41
Fix: 222081673
Test: atest StylusHandwriting
Diffstat (limited to 'core/java/android/inputmethodservice/InputMethodService.java')
| -rw-r--r-- | core/java/android/inputmethodservice/InputMethodService.java | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index fbc0732affe1..4970d445b34d 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -142,6 +142,7 @@ import com.android.internal.inputmethod.IInputMethodPrivilegedOperations; import com.android.internal.inputmethod.ImeTracing; import com.android.internal.inputmethod.InputMethodPrivilegedOperations; import com.android.internal.inputmethod.InputMethodPrivilegedOperationsRegistry; +import com.android.internal.util.RingBuffer; import com.android.internal.view.IInlineSuggestionsRequestCallback; import com.android.internal.view.IInputContext; import com.android.internal.view.InlineSuggestionsRequestInfo; @@ -333,6 +334,17 @@ public class InputMethodService extends AbstractInputMethodService { "persist.sys.ime.can_render_gestural_nav_buttons"; /** + * Number of {@link MotionEvent} to buffer if IME is not ready with Ink view. + * This number may be configured eventually based on device's touch sampling frequency. + */ + private static final int MAX_EVENTS_BUFFER = 500; + + /** + * A circular buffer of size MAX_EVENTS_BUFFER in case IME is taking too long to add ink view. + **/ + private RingBuffer<MotionEvent> mPendingEvents; + + /** * Returns whether {@link InputMethodService} is responsible for rendering the back button and * the IME switcher button or not when the gestural navigation is enabled. * @@ -957,7 +969,8 @@ public class InputMethodService extends AbstractInputMethodService { mInkWindow.show(); // deliver previous @param stylusEvents - stylusEvents.forEach(mInkWindow.getDecorView()::dispatchTouchEvent); + stylusEvents.forEach(InputMethodService.this::onStylusHandwritingMotionEvent); + // create receiver for channel mHandwritingEventReceiver = new SimpleBatchedInputEventReceiver( channel, @@ -966,11 +979,11 @@ public class InputMethodService extends AbstractInputMethodService { if (!(event instanceof MotionEvent)) { return false; } - return mInkWindow.getDecorView().dispatchTouchEvent((MotionEvent) event); + onStylusHandwritingMotionEvent((MotionEvent) event); + return true; }); } - /** * {@inheritDoc} * @hide @@ -2360,7 +2373,8 @@ public class InputMethodService extends AbstractInputMethodService { * * If the IME supports handwriting for the current input, it should return {@code true}, * ensure its inking views are attached to the {@link #getStylusHandwritingWindow()}, and handle - * stylus input received on the ink window via {@link #getCurrentInputConnection()}. + * stylus input received from {@link #onStylusHandwritingMotionEvent(MotionEvent)} on the + * {@link #getStylusHandwritingWindow()} via {@link #getCurrentInputConnection()}. * @return {@code true} if IME can honor the request, {@code false} if IME cannot at this time. */ public boolean onStartStylusHandwriting() { @@ -2369,6 +2383,33 @@ public class InputMethodService extends AbstractInputMethodService { } /** + * Called after {@link #onStartStylusHandwriting()} returns {@code true} for every Stylus + * {@link MotionEvent}. + * By default, this method forwards all {@link MotionEvent}s to the + * {@link #getStylusHandwritingWindow()} once its visible, however IME can override it to + * receive them sooner. + * @param motionEvent {@link MotionEvent} from stylus. + */ + public void onStylusHandwritingMotionEvent(@NonNull MotionEvent motionEvent) { + if (mInkWindow.isInkViewVisible()) { + mInkWindow.getDecorView().dispatchTouchEvent(motionEvent); + } else { + if (mPendingEvents == null) { + mPendingEvents = new RingBuffer(MotionEvent.class, MAX_EVENTS_BUFFER); + } + mPendingEvents.append(motionEvent); + mInkWindow.setInkViewVisibilityListener(() -> { + if (mPendingEvents != null && !mPendingEvents.isEmpty()) { + for (MotionEvent event : mPendingEvents.toArray()) { + mInkWindow.getDecorView().dispatchTouchEvent(event); + } + mPendingEvents.clear(); + } + }); + } + } + + /** * Called when the current stylus handwriting session was finished (either by the system or * via {@link #finishStylusHandwriting()}. * |
