Introduce IME API for adjusting handwriting idle timeout

The API allows IME developers to override default system idle-timeout
for stylus handwriting sessions. The system default may be too long or
too short for certain use-cases and it makes sense to let IME change it.

Bug: 233811329
Test: atest StylusHandwritingTest
Change-Id: I9e869658ad57b2ec91b882ab9e003e7f60f95c7c
This commit is contained in:
Taran Singh
2022-05-25 18:13:04 +00:00
parent 5a9aeacc08
commit f42da45849
2 changed files with 68 additions and 3 deletions

View File

@@ -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);

View File

@@ -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);
}
/**