diff --git a/core/api/current.txt b/core/api/current.txt index d83aa10dd78df..58f7fdbfa373f 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -18831,6 +18831,8 @@ package android.inputmethodservice { method @Deprecated public int getInputMethodWindowRecommendedHeight(); method public android.view.LayoutInflater getLayoutInflater(); method public int getMaxWidth(); + method @NonNull public static final java.time.Duration getStylusHandwritingIdleTimeoutMax(); + method @NonNull public final java.time.Duration getStylusHandwritingSessionTimeout(); method @Nullable public final android.view.Window getStylusHandwritingWindow(); method public CharSequence getTextForImeAction(int); method public android.app.Dialog getWindow(); @@ -18897,6 +18899,7 @@ package android.inputmethodservice { method public void setExtractView(android.view.View); method public void setExtractViewShown(boolean); method public void setInputView(android.view.View); + method public final void setStylusHandwritingSessionTimeout(@NonNull java.time.Duration); method public final boolean shouldOfferSwitchingToNextInputMethod(); method public void showStatusIcon(@DrawableRes int); method public void showWindow(boolean); diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index a1664d8ba47ff..4869516123335 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -157,6 +157,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.time.Duration; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -351,7 +352,13 @@ public class InputMethodService extends AbstractInputMethodService { * @see #onStartStylusHandwriting() * @see #onFinishStylusHandwriting() */ - private static final int STYLUS_HANDWRITING_IDLE_TIMEOUT_MS = 10000; + private static final long STYLUS_HANDWRITING_IDLE_TIMEOUT_MS = 10000; + + /** + * Max allowed stylus handwriting session idle-timeout. + */ + private static final long STYLUS_HANDWRITING_IDLE_TIMEOUT_MAX_MS = + STYLUS_HANDWRITING_IDLE_TIMEOUT_MS * 3; /** * A circular buffer of size MAX_EVENTS_BUFFER in case IME is taking too long to add ink view. @@ -362,6 +369,7 @@ public class InputMethodService extends AbstractInputMethodService { private final OnBackInvokedCallback mCompatBackCallback = this::compatHandleBack; private Runnable mImeSurfaceRemoverRunnable; private Runnable mFinishHwRunnable; + private long mStylusHwSessionsTimeout = STYLUS_HANDWRITING_IDLE_TIMEOUT_MS; /** * Returns whether {@link InputMethodService} is responsible for rendering the back button and @@ -2474,7 +2482,8 @@ public class InputMethodService extends AbstractInputMethodService { * * Note for IME developers: Call this method at any time to finish current handwriting session. * Generally, this should be invoked after a short timeout, giving the user enough time - * to start the next stylus stroke, if any. + * to start the next stylus stroke, if any. By default, system will time-out after few seconds. + * To override default timeout, use {@link #setStylusHandwritingSessionTimeout(Duration)}. * * Handwriting session will be finished by framework on next {@link #onFinishInput()}. */ @@ -2503,6 +2512,59 @@ public class InputMethodService extends AbstractInputMethodService { onFinishStylusHandwriting(); } + /** + * Sets the duration after which an ongoing stylus handwriting session that hasn't received new + * {@link MotionEvent}s will time out and {@link #finishStylusHandwriting()} will be called. + * + * The maximum allowed duration is returned by + * {@link #getStylusHandwritingIdleTimeoutMax()}, larger values will be clamped. + * + * Note: this value is bound to the {@link InputMethodService} instance and resets to the + * default whenever a new instance is constructed. + * @param duration timeout to set. + * @see #onStartStylusHandwriting() + * @see #onFinishStylusHandwriting() + * @see #getStylusHandwritingSessionTimeout() + */ + public final void setStylusHandwritingSessionTimeout(@NonNull Duration duration) { + long timeoutMs = duration.toMillis(); + if (timeoutMs <= 0) { + throw new IllegalStateException( + "A positive value should be set for Stylus handwriting session timeout."); + } + if (timeoutMs > STYLUS_HANDWRITING_IDLE_TIMEOUT_MAX_MS) { + timeoutMs = STYLUS_HANDWRITING_IDLE_TIMEOUT_MAX_MS; + } + mStylusHwSessionsTimeout = timeoutMs; + scheduleHandwritingSessionTimeout(); + } + + /** + * Returns the maximum stylus handwriting session idle-timeout for use with + * {@link #setStylusHandwritingSessionTimeout(Duration)}. + * @see #onStartStylusHandwriting() + * @see #onFinishStylusHandwriting() + * @see #getStylusHandwritingSessionTimeout() + */ + @NonNull + public static final Duration getStylusHandwritingIdleTimeoutMax() { + return Duration.ofMillis(STYLUS_HANDWRITING_IDLE_TIMEOUT_MAX_MS); + } + + /** + * Returns the duration after which an ongoing stylus handwriting session that hasn't received + * new {@link MotionEvent}s will time out and {@link #finishStylusHandwriting()} will be called. + * The current timeout can be changed using + * {@link #setStylusHandwritingSessionTimeout(Duration)}. + * @see #getStylusHandwritingIdleTimeoutMax + * @see #onStartStylusHandwriting() + * @see #onFinishStylusHandwriting() + */ + @NonNull + public final Duration getStylusHandwritingSessionTimeout() { + return Duration.ofMillis(mStylusHwSessionsTimeout); + } + private Runnable getFinishHandwritingRunnable() { if (mFinishHwRunnable != null) { return mFinishHwRunnable; @@ -2524,7 +2586,7 @@ public class InputMethodService extends AbstractInputMethodService { if (mFinishHwRunnable != null) { mHandler.removeCallbacks(mFinishHwRunnable); } - mHandler.postDelayed(getFinishHandwritingRunnable(), STYLUS_HANDWRITING_IDLE_TIMEOUT_MS); + mHandler.postDelayed(getFinishHandwritingRunnable(), mStylusHwSessionsTimeout); } /**