Merge "Incorporate API feedback: CAI requestCursorUpdates()" into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
33a2b4bacd
@@ -52951,6 +52951,7 @@ package android.view.inputmethod {
|
||||
method public default boolean performSpellCheck();
|
||||
method public boolean reportFullscreenMode(boolean);
|
||||
method public boolean requestCursorUpdates(int);
|
||||
method public default boolean requestCursorUpdates(int, int);
|
||||
method public boolean sendKeyEvent(android.view.KeyEvent);
|
||||
method public boolean setComposingRegion(int, int);
|
||||
method public default boolean setComposingRegion(int, int, @Nullable android.view.inputmethod.TextAttribute);
|
||||
|
||||
@@ -433,6 +433,26 @@ public final class RemoteInputConnection implements InputConnection {
|
||||
mCancellationGroup, MAX_WAIT_TIME_MILLIS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@AnyThread
|
||||
public boolean requestCursorUpdates(@CursorUpdateMode int cursorUpdateMode,
|
||||
@CursorUpdateFilter int cursorUpdateFilter) {
|
||||
if (mCancellationGroup.isCanceled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final InputMethodServiceInternal ims = mImsInternal.getAndWarnIfNull();
|
||||
if (ims == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int displayId = ims.getContext().getDisplayId();
|
||||
final CompletableFuture<Boolean> value =
|
||||
mInvoker.requestCursorUpdates(cursorUpdateMode, cursorUpdateFilter, displayId);
|
||||
return CompletableFutureUtil.getResultOrFalse(value, TAG, "requestCursorUpdates()",
|
||||
mCancellationGroup, MAX_WAIT_TIME_MILLIS);
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
public Handler getHandler() {
|
||||
// Nothing should happen when called from input method.
|
||||
|
||||
@@ -575,7 +575,9 @@ public final class CursorAnchorInfo implements Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link EditorBoundsInfo} editor related bounds.
|
||||
* Returns {@link EditorBoundsInfo} for the current editor, or {@code null} if IME is not
|
||||
* subscribed with {@link InputConnection#CURSOR_UPDATE_FILTER_EDITOR_BOUNDS}
|
||||
* or {@link InputConnection#CURSOR_UPDATE_MONITOR}.
|
||||
*/
|
||||
@Nullable
|
||||
public EditorBoundsInfo getEditorBoundsInfo() {
|
||||
|
||||
@@ -30,13 +30,13 @@ import java.util.Objects;
|
||||
public final class EditorBoundsInfo implements Parcelable {
|
||||
|
||||
/**
|
||||
* Container of rectangular position of Editor in the current window.
|
||||
* The bounding box of the of currently focused text editor in local coordinates.
|
||||
*/
|
||||
private final RectF mEditorBounds;
|
||||
|
||||
/**
|
||||
* Container of rectangular position of Editor with additional padding around for initiating
|
||||
* Stylus Handwriting in the current window.
|
||||
* The bounding box of the of currently focused text editor with additional padding around it
|
||||
* for initiating Stylus Handwriting in the current window.
|
||||
*/
|
||||
private final RectF mHandwritingBounds;
|
||||
|
||||
|
||||
@@ -1042,6 +1042,23 @@ public interface InputConnection {
|
||||
*/
|
||||
int CURSOR_UPDATE_FILTER_INSERTION_MARKER = 1 << 4;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {CURSOR_UPDATE_IMMEDIATE, CURSOR_UPDATE_MONITOR}, flag = true,
|
||||
prefix = { "CURSOR_UPDATE_" })
|
||||
@interface CursorUpdateMode{}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {CURSOR_UPDATE_FILTER_EDITOR_BOUNDS, CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS,
|
||||
CURSOR_UPDATE_FILTER_INSERTION_MARKER}, flag = true,
|
||||
prefix = { "CURSOR_UPDATE_FILTER_" })
|
||||
@interface CursorUpdateFilter{}
|
||||
|
||||
/**
|
||||
* Called by the input method to ask the editor for calling back
|
||||
* {@link InputMethodManager#updateCursorAnchorInfo(android.view.View, CursorAnchorInfo)} to
|
||||
@@ -1062,6 +1079,34 @@ public interface InputConnection {
|
||||
*/
|
||||
boolean requestCursorUpdates(int cursorUpdateMode);
|
||||
|
||||
/**
|
||||
* Called by the input method to ask the editor for calling back
|
||||
* {@link InputMethodManager#updateCursorAnchorInfo(android.view.View, CursorAnchorInfo)} to
|
||||
* notify cursor/anchor locations.
|
||||
*
|
||||
* @param cursorUpdateMode combination of update modes:
|
||||
* {@link #CURSOR_UPDATE_IMMEDIATE}, {@link #CURSOR_UPDATE_MONITOR}
|
||||
* @param cursorUpdateFilter any combination of data filters:
|
||||
* {@link #CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS}, {@link #CURSOR_UPDATE_FILTER_EDITOR_BOUNDS},
|
||||
* {@link #CURSOR_UPDATE_FILTER_INSERTION_MARKER}.
|
||||
*
|
||||
* <p>Pass {@code 0} to disable them. However, if an unknown flag is provided, request will be
|
||||
* rejected and method will return {@code false}.</p>
|
||||
* @return {@code true} if the request is scheduled. {@code false} to indicate that when the
|
||||
* application will not call {@link InputMethodManager#updateCursorAnchorInfo(
|
||||
* android.view.View, CursorAnchorInfo)}.
|
||||
* Since Android {@link android.os.Build.VERSION_CODES#N} until
|
||||
* {@link android.os.Build.VERSION_CODES#TIRAMISU}, this API returned {@code false} when
|
||||
* the target application does not implement this method.
|
||||
*/
|
||||
default boolean requestCursorUpdates(@CursorUpdateMode int cursorUpdateMode,
|
||||
@CursorUpdateFilter int cursorUpdateFilter) {
|
||||
if (cursorUpdateFilter == 0) {
|
||||
return requestCursorUpdates(cursorUpdateMode);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the system to enable application developers to specify a dedicated thread on which
|
||||
* {@link InputConnection} methods are called back.
|
||||
|
||||
@@ -1936,8 +1936,8 @@ public final class InputMethodManager {
|
||||
// TODO (b/210039666): Pipe IME displayId from InputBindResult and use it here.
|
||||
// instead of mDisplayId.
|
||||
mServedInputConnection.requestCursorUpdatesFromImm(
|
||||
CURSOR_UPDATE_IMMEDIATE | CURSOR_UPDATE_MONITOR
|
||||
| CURSOR_UPDATE_FILTER_EDITOR_BOUNDS,
|
||||
CURSOR_UPDATE_IMMEDIATE | CURSOR_UPDATE_MONITOR,
|
||||
CURSOR_UPDATE_FILTER_EDITOR_BOUNDS,
|
||||
mDisplayId);
|
||||
}
|
||||
|
||||
|
||||
@@ -6179,6 +6179,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
return getTarget().requestCursorUpdates(cursorUpdateMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requestCursorUpdates(int cursorUpdateMode, int cursorUpdateFilter) {
|
||||
return getTarget().requestCursorUpdates(cursorUpdateMode, cursorUpdateFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Handler getHandler() {
|
||||
return getTarget().getHandler();
|
||||
|
||||
@@ -204,6 +204,13 @@ public final class EditableInputConnection extends BaseInputConnection
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requestCursorUpdates(
|
||||
@CursorUpdateMode int cursorUpdateMode, @CursorUpdateFilter int cursorUpdateFilter) {
|
||||
// TODO(b/210039666): use separate attrs for updateMode and updateFilter.
|
||||
return requestCursorUpdates(cursorUpdateMode | cursorUpdateFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requestCursorUpdates(int cursorUpdateMode) {
|
||||
if (DEBUG) Log.v(TAG, "requestUpdateCursorAnchorInfo " + cursorUpdateMode);
|
||||
|
||||
@@ -602,6 +602,30 @@ public final class IInputContextInvoker {
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes {@link IInputContext#requestCursorUpdatesWithFilter(InputConnectionCommandHeader,
|
||||
* int, int, int, AndroidFuture)}.
|
||||
*
|
||||
* @param cursorUpdateMode {@code cursorUpdateMode} parameter to be passed.
|
||||
* @param cursorUpdateFilter {@code cursorUpdateFilter} parameter to be passed.
|
||||
* @param imeDisplayId the display ID that is associated with the IME.
|
||||
* @return {@link AndroidFuture<Boolean>} that can be used to retrieve the invocation
|
||||
* result. {@link RemoteException} will be treated as an error.
|
||||
*/
|
||||
@AnyThread
|
||||
@NonNull
|
||||
public AndroidFuture<Boolean> requestCursorUpdates(int cursorUpdateMode, int cursorUpdateFilter,
|
||||
int imeDisplayId) {
|
||||
final AndroidFuture<Boolean> future = new AndroidFuture<>();
|
||||
try {
|
||||
mIInputContext.requestCursorUpdatesWithFilter(createHeader(), cursorUpdateMode,
|
||||
cursorUpdateFilter, imeDisplayId, future);
|
||||
} catch (RemoteException e) {
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes {@link IInputContext#commitContent(InputConnectionCommandHeader, InputContentInfo,
|
||||
* int, Bundle, AndroidFuture)}.
|
||||
|
||||
@@ -935,17 +935,20 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
* Dispatches {@link InputConnection#requestCursorUpdates(int)}.
|
||||
*
|
||||
* <p>This method is intended to be called only from {@link InputMethodManager}.</p>
|
||||
* @param cursorUpdateMode the mode for {@link InputConnection#requestCursorUpdates(int)}
|
||||
* @param cursorUpdateMode the mode for {@link InputConnection#requestCursorUpdates(int, int)}
|
||||
* @param cursorUpdateFilter the filter for
|
||||
* {@link InputConnection#requestCursorUpdates(int, int)}
|
||||
* @param imeDisplayId displayId on which IME is displayed.
|
||||
*/
|
||||
@Dispatching(cancellable = true)
|
||||
public void requestCursorUpdatesFromImm(int cursorUpdateMode, int imeDisplayId) {
|
||||
public void requestCursorUpdatesFromImm(int cursorUpdateMode, int cursorUpdateFilter,
|
||||
int imeDisplayId) {
|
||||
final int currentSessionId = mCurrentSessionId.get();
|
||||
dispatchWithTracing("requestCursorUpdatesFromImm", () -> {
|
||||
if (currentSessionId != mCurrentSessionId.get()) {
|
||||
return; // cancelled
|
||||
}
|
||||
requestCursorUpdatesInternal(cursorUpdateMode, imeDisplayId);
|
||||
requestCursorUpdatesInternal(cursorUpdateMode, cursorUpdateFilter, imeDisplayId);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -957,11 +960,28 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return false; // cancelled
|
||||
}
|
||||
return requestCursorUpdatesInternal(cursorUpdateMode, imeDisplayId);
|
||||
return requestCursorUpdatesInternal(
|
||||
cursorUpdateMode, 0 /* cursorUpdateFilter */, imeDisplayId);
|
||||
});
|
||||
}
|
||||
|
||||
private boolean requestCursorUpdatesInternal(int cursorUpdateMode, int imeDisplayId) {
|
||||
@Dispatching(cancellable = true)
|
||||
@Override
|
||||
public void requestCursorUpdatesWithFilter(InputConnectionCommandHeader header,
|
||||
int cursorUpdateMode, int cursorUpdateFilter, int imeDisplayId,
|
||||
AndroidFuture future /* T=Boolean */) {
|
||||
dispatchWithTracing("requestCursorUpdates", future, () -> {
|
||||
if (header.mSessionId != mCurrentSessionId.get()) {
|
||||
return false; // cancelled
|
||||
}
|
||||
return requestCursorUpdatesInternal(
|
||||
cursorUpdateMode, cursorUpdateFilter, imeDisplayId);
|
||||
});
|
||||
}
|
||||
|
||||
private boolean requestCursorUpdatesInternal(
|
||||
@InputConnection.CursorUpdateMode int cursorUpdateMode,
|
||||
@InputConnection.CursorUpdateFilter int cursorUpdateFilter, int imeDisplayId) {
|
||||
final InputConnection ic = getInputConnection();
|
||||
if (ic == null || !isActive()) {
|
||||
Log.w(TAG, "requestCursorAnchorInfo on inactive InputConnection");
|
||||
@@ -972,7 +992,7 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return ic.requestCursorUpdates(cursorUpdateMode);
|
||||
return ic.requestCursorUpdates(cursorUpdateMode, cursorUpdateFilter);
|
||||
} catch (AbstractMethodError ignored) {
|
||||
// TODO(b/199934664): See if we can remove this by providing a default impl.
|
||||
return false;
|
||||
|
||||
@@ -98,6 +98,10 @@ import com.android.internal.inputmethod.InputConnectionCommandHeader;
|
||||
void requestCursorUpdates(in InputConnectionCommandHeader header, int cursorUpdateMode,
|
||||
int imeDisplayId, in AndroidFuture future /* T=Boolean */);
|
||||
|
||||
void requestCursorUpdatesWithFilter(in InputConnectionCommandHeader header,
|
||||
int cursorUpdateMode, int cursorUpdateFilter, int imeDisplayId,
|
||||
in AndroidFuture future /* T=Boolean */);
|
||||
|
||||
void commitContent(in InputConnectionCommandHeader header, in InputContentInfo inputContentInfo,
|
||||
int flags, in Bundle opts, in AndroidFuture future /* T=Boolean */);
|
||||
|
||||
|
||||
@@ -548,6 +548,11 @@ public class ViewInputConnectionTest {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requestCursorUpdates(int cursorUpdateMode, int cursorUpdateFilter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Handler getHandler() {
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user