summaryrefslogtreecommitdiff
path: root/core/java/android/inputmethodservice/InputMethodService.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/inputmethodservice/InputMethodService.java')
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java49
1 files changed, 45 insertions, 4 deletions
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 656aea18fe50..b46bb3257c86 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -143,6 +143,7 @@ import com.android.internal.inputmethod.ImeTracing;
import com.android.internal.inputmethod.InputMethodNavButtonFlags;
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;
@@ -334,6 +335,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.
*
@@ -954,7 +966,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,
@@ -963,11 +976,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
@@ -2357,7 +2370,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() {
@@ -2366,6 +2380,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()}.
*