Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a277db28 authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

Remove CursorAnchorInfoRequest and related stuff

This CL removes CursorAnchorInfoRequest and related stuff
in favor of InputConnection.requestUpdateCursorAnchorInfo,
which is more easy to understand. This CL also deprecates
InputMethodManager#updateCursor and related stuff.

Rationale:
1. The spec of #updateCursor says that it provides the cursor
   position in local coordinates, while the input method
   requires it in the screen coordinates.
2. #updateCursor has never been enabled in AOSP, because
   InputMethodManager#isWatchingCursor always returned false.
3. There has been no way to let
   InputMethodManager#isWatchingCursor return true.
4. In L, InputMethodManager#updateCursorAnchorInfo is
   introduced to address all the issues above.

Given that we no longer need to support #updateCursor,
CursorAnchorInfoRequest is overkill when we need to convey
just a couple of parameters.

BUG: 17185263
BUG: 17182367

Change-Id: I4a577bfd02b37b9e56c80b8b41bb25afa95dd8ef
parent 97a50add
Loading
Loading
Loading
Loading
+8 −25
Original line number Diff line number Diff line
@@ -13574,7 +13574,7 @@ package android.inputmethodservice {
    method public void onStartInput(android.view.inputmethod.EditorInfo, boolean);
    method public void onStartInputView(android.view.inputmethod.EditorInfo, boolean);
    method public void onUnbindInput();
    method public void onUpdateCursor(android.graphics.Rect);
    method public deprecated void onUpdateCursor(android.graphics.Rect);
    method public void onUpdateCursorAnchorInfo(android.view.inputmethod.CursorAnchorInfo);
    method public void onUpdateExtractedText(int, android.view.inputmethod.ExtractedText);
    method public void onUpdateExtractingViews(android.view.inputmethod.EditorInfo);
@@ -36187,7 +36187,7 @@ package android.view.inputmethod {
    method public boolean performPrivateCommand(java.lang.String, android.os.Bundle);
    method public static final void removeComposingSpans(android.text.Spannable);
    method public boolean reportFullscreenMode(boolean);
    method public int requestCursorAnchorInfo(android.view.inputmethod.CursorAnchorInfoRequest);
    method public boolean requestUpdateCursorAnchorInfo(int);
    method public boolean sendKeyEvent(android.view.KeyEvent);
    method public boolean setComposingRegion(int, int);
    method public static void setComposingSpans(android.text.Spannable);
@@ -36253,25 +36253,6 @@ package android.view.inputmethod {
    method public android.view.inputmethod.CursorAnchorInfo.Builder setSelectionRange(int, int);
  }
  public final class CursorAnchorInfoRequest implements android.os.Parcelable {
    ctor public CursorAnchorInfoRequest(int, int);
    ctor public CursorAnchorInfoRequest(android.os.Parcel);
    method public int describeContents();
    method public int getRequestFlags();
    method public int getRequestType();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator CREATOR;
    field public static final int FLAG_CURSOR_ANCHOR_INFO_IMMEDIATE = 2; // 0x2
    field public static final int FLAG_CURSOR_ANCHOR_INFO_MONITOR = 1; // 0x1
    field public static final int FLAG_CURSOR_RECT_IN_SCREEN_COORDINATES = 2; // 0x2
    field public static final int FLAG_CURSOR_RECT_MONITOR = 1; // 0x1
    field public static final int FLAG_CURSOR_RECT_WITH_VIEW_MATRIX = 4; // 0x4
    field public static final int RESULT_NOT_HANDLED = 0; // 0x0
    field public static final int RESULT_SCHEDULED = 1; // 0x1
    field public static final int TYPE_CURSOR_ANCHOR_INFO = 1; // 0x1
    field public static final int TYPE_CURSOR_RECT = 2; // 0x2
  }
  public class EditorInfo implements android.text.InputType android.os.Parcelable {
    ctor public EditorInfo();
    method public int describeContents();
@@ -36369,13 +36350,15 @@ package android.view.inputmethod {
    method public abstract boolean performEditorAction(int);
    method public abstract boolean performPrivateCommand(java.lang.String, android.os.Bundle);
    method public abstract boolean reportFullscreenMode(boolean);
    method public abstract int requestCursorAnchorInfo(android.view.inputmethod.CursorAnchorInfoRequest);
    method public abstract boolean requestUpdateCursorAnchorInfo(int);
    method public abstract boolean sendKeyEvent(android.view.KeyEvent);
    method public abstract boolean setComposingRegion(int, int);
    method public abstract boolean setComposingText(java.lang.CharSequence, int);
    method public abstract boolean setSelection(int, int);
    field public static final int GET_EXTRACTED_TEXT_MONITOR = 1; // 0x1
    field public static final int GET_TEXT_WITH_STYLES = 1; // 0x1
    field public static final int REQUEST_UPDATE_CURSOR_ANCHOR_INFO_IMMEDIATE = 1; // 0x1
    field public static final int REQUEST_UPDATE_CURSOR_ANCHOR_INFO_MONITOR = 2; // 0x2
  }
  public class InputConnectionWrapper implements android.view.inputmethod.InputConnection {
@@ -36397,7 +36380,7 @@ package android.view.inputmethod {
    method public boolean performEditorAction(int);
    method public boolean performPrivateCommand(java.lang.String, android.os.Bundle);
    method public boolean reportFullscreenMode(boolean);
    method public int requestCursorAnchorInfo(android.view.inputmethod.CursorAnchorInfoRequest);
    method public boolean requestUpdateCursorAnchorInfo(int);
    method public boolean sendKeyEvent(android.view.KeyEvent);
    method public boolean setComposingRegion(int, int);
    method public boolean setComposingText(java.lang.CharSequence, int);
@@ -36463,7 +36446,7 @@ package android.view.inputmethod {
    method public boolean isActive(android.view.View);
    method public boolean isActive();
    method public boolean isFullscreenMode();
    method public boolean isWatchingCursor(android.view.View);
    method public deprecated boolean isWatchingCursor(android.view.View);
    method public void restartInput(android.view.View);
    method public void sendAppPrivateCommand(android.view.View, java.lang.String, android.os.Bundle);
    method public void setAdditionalInputMethodSubtypes(java.lang.String, android.view.inputmethod.InputMethodSubtype[]);
@@ -36481,7 +36464,7 @@ package android.view.inputmethod {
    method public boolean switchToNextInputMethod(android.os.IBinder, boolean);
    method public void toggleSoftInput(int, int);
    method public void toggleSoftInputFromWindow(android.os.IBinder, int, int);
    method public void updateCursor(android.view.View, int, int, int, int);
    method public deprecated void updateCursor(android.view.View, int, int, int, int);
    method public void updateCursorAnchorInfo(android.view.View, android.view.inputmethod.CursorAnchorInfo);
    method public void updateExtractedText(android.view.View, int, android.view.inputmethod.ExtractedText);
    method public void updateSelection(android.view.View, int, int, int, int);
+5 −7
Original line number Diff line number Diff line
@@ -53,7 +53,6 @@ import android.view.WindowManager.BadTokenException;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.CursorAnchorInfoRequest;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
@@ -1711,13 +1710,12 @@ public class InputMethodService extends AbstractInputMethodService {
    }

    /**
     * Called when the application has reported a new location of its text cursor.  This is only
     * called if explicitly requested by the input method.  The default implementation does nothing.
     * @param newCursor The new cursor position, in screen coordinates if the input method calls
     * {@link InputConnection#requestCursorAnchorInfo(CursorAnchorInfoRequest)} with
     * {@link CursorAnchorInfoRequest#FLAG_CURSOR_RECT_IN_SCREEN_COORDINATES}. Otherwise,
     * this is in local coordinates.
     * Called when the application has reported a new location of its text
     * cursor.  This is only called if explicitly requested by the input method.
     * The default implementation does nothing.
     * @deprecated Use {#link onUpdateCursorAnchorInfo(CursorAnchorInfo)} instead.
     */
    @Deprecated
    public void onUpdateCursor(Rect newCursor) {
        // Intentionally empty
    }
+3 −18
Original line number Diff line number Diff line
@@ -429,25 +429,10 @@ public class BaseInputConnection implements InputConnection {
    }

    /**
     * The default implementation is responsible for handling
     * {@link CursorAnchorInfoRequest#TYPE_CURSOR_RECT}. In fact, for derived classes, calling
     * {@code super.requestCursorAnchorInfo(request)} is the only way to handle
     * {@link CursorAnchorInfoRequest#TYPE_CURSOR_RECT}.
     * The default implementation does nothing.
     */
    public int requestCursorAnchorInfo(CursorAnchorInfoRequest request) {
        // This implementation supports TYPE_CURSOR_RECT only.
        if (request == null ||
                request.getRequestType() != CursorAnchorInfoRequest.TYPE_CURSOR_RECT) {
            return CursorAnchorInfoRequest.RESULT_NOT_HANDLED;
        }
        if (mIMM == null) {
            // In this case, TYPE_CURSOR_RECT is not handled.
            // TODO: Return some notification code for the input method that indicates
            // Cursor rect information is temporarily unavailable.
            return CursorAnchorInfoRequest.RESULT_NOT_HANDLED;
        }
        mIMM.setCursorRectMonitorMode(request.getRequestFlags());
        return CursorAnchorInfoRequest.RESULT_SCHEDULED;
    public boolean requestUpdateCursorAnchorInfo(int cursorUpdateMode) {
        return false;
    }

    /**
+0 −19
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view.inputmethod;

parcelable CursorAnchorInfoRequest;
+0 −203
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package android.view.inputmethod;

import android.inputmethodservice.InputMethodService;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.View;

/**
 * Used to enable or disable event notification for
 * {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)}. This class is also used to
 * enable {@link InputMethodService#onUpdateCursor(android.graphics.Rect)} for existing editors
 * that have not supported {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)}.
 */
public final class CursorAnchorInfoRequest implements Parcelable {
    private final int mRequestType;
    private final int mRequestFlags;

    /**
     * Not handled by the editor.
     */
    public static final int RESULT_NOT_HANDLED = 0x00;
    /**
     * Request is scheduled in the editor task queue.
     */
    public static final int RESULT_SCHEDULED = 0x01;

    /**
     * The request is for {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)}.
     * This mechanism is powerful enough to retrieve fine-grained positional information of
     * characters in the editor.
     */
    public static final int TYPE_CURSOR_ANCHOR_INFO = 0x01;
    /**
     * The editor is requested to call
     * {@link InputMethodManager#updateCursorAnchorInfo(android.view.View, CursorAnchorInfo)}
     * whenever cursor/anchor position is changed. To disable monitoring, call
     * {@link InputConnection#requestCursorAnchorInfo(CursorAnchorInfoRequest)} again with
     * {@link #TYPE_CURSOR_ANCHOR_INFO} and this flag off.
     * <p>
     * This flag can be used together with {@link #FLAG_CURSOR_ANCHOR_INFO_IMMEDIATE}.
     * </p>
     */
    public static final int FLAG_CURSOR_ANCHOR_INFO_MONITOR = 0x01;
    /**
     * The editor is requested to call
     * {@link InputMethodManager#updateCursorAnchorInfo(android.view.View, CursorAnchorInfo)} at
     * once, as soon as possible, regardless of cursor/anchor position changes. This flag can be
     * used together with {@link #FLAG_CURSOR_ANCHOR_INFO_MONITOR}.
     */
    public static final int FLAG_CURSOR_ANCHOR_INFO_IMMEDIATE = 0x02;

    /**
     * The request is for {@link InputMethodService#onUpdateCursor(android.graphics.Rect)}. This
     * mechanism has been available since API Level 3 (CUPCAKE) but only the cursor rectangle can
     * be retrieved with this mechanism.
     */
    public static final int TYPE_CURSOR_RECT = 0x02;
    /**
     * The editor is requested to call
     * {@link InputMethodManager#updateCursor(android.view.View, int, int, int, int)}
     * whenever the cursor position is changed. To disable monitoring, call
     * {@link InputConnection#requestCursorAnchorInfo(CursorAnchorInfoRequest)} again with
     * {@link #TYPE_CURSOR_RECT} and this flag off.
     * <p>
     * This flag can be used together with {@link #FLAG_CURSOR_RECT_IN_SCREEN_COORDINATES}.
     * </p>
     */
    public static final int FLAG_CURSOR_RECT_MONITOR = 0x01;
    /**
     * {@link InputMethodManager#updateCursor(android.view.View, int, int, int, int)} should be
     * called back in screen coordinates. To receive cursor position in local coordinates, call
     * {@link InputConnection#requestCursorAnchorInfo(CursorAnchorInfoRequest)} again with
     * {@link #TYPE_CURSOR_RECT} and this flag off.
     */
    public static final int FLAG_CURSOR_RECT_IN_SCREEN_COORDINATES = 0x02;
    /**
     * {@link InputMethodManager#updateCursor(android.view.View, int, int, int, int)} should be
     * called back in screen coordinates after coordinate conversion with {@link View#getMatrix()}.
     * To disable coordinate conversion with {@link View#getMatrix()} again, call
     * {@link InputConnection#requestCursorAnchorInfo(CursorAnchorInfoRequest)} with
     * {@link #TYPE_CURSOR_RECT} and this flag off.
     *
     * <p>
     * The flag is ignored if {@link #FLAG_CURSOR_RECT_IN_SCREEN_COORDINATES} is off.
     * </p>
     */
    public static final int FLAG_CURSOR_RECT_WITH_VIEW_MATRIX = 0x04;

    /**
     * Constructs the object with request type and type-specific flags.
     *
     * @param requestType the type of this request. Currently {@link #TYPE_CURSOR_ANCHOR_INFO} or
     * {@link #TYPE_CURSOR_RECT} is supported.
     * @param requestFlags the flags for the given request type.
     */
    public CursorAnchorInfoRequest(int requestType, int requestFlags) {
        mRequestType = requestType;
        mRequestFlags = requestFlags;
    }

    /**
     * Used to make this class parcelable.
     *
     * @param source the parcel from which the object is unmarshalled.
     */
    public CursorAnchorInfoRequest(Parcel source) {
        mRequestType = source.readInt();
        mRequestFlags = source.readInt();
    }

    /**
     * @return the type of this request.
     */
    public int getRequestType() {
        return mRequestType;
    }

    /**
     * @return the flags that are specific to the type of this request.
     */
    public int getRequestFlags() {
        return mRequestFlags;
    }

    /**
     * Used to package this object into a {@link Parcel}.
     *
     * @param dest The {@link Parcel} to be written.
     * @param flags The flags used for parceling.
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mRequestType);
        dest.writeInt(mRequestFlags);
    }

    @Override
    public int hashCode(){
        return mRequestType * 31 + mRequestFlags;
    }

    @Override
    public boolean equals(Object obj){
        if (obj == null) {
            return false;
        }
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof CursorAnchorInfoRequest)) {
            return false;
        }
        final CursorAnchorInfoRequest that = (CursorAnchorInfoRequest) obj;
        if (hashCode() != that.hashCode()) {
            return false;
        }
        return mRequestType != that.mRequestType && mRequestFlags == that.mRequestFlags;
    }

    @Override
    public String toString() {
        return "CursorAnchorInfoRequest{mRequestType=" + mRequestType
                + " mRequestFlags=" + mRequestFlags
                + "}";
    }

    /**
     * Used to make this class parcelable.
     */
    public static final Parcelable.Creator<CursorAnchorInfoRequest> CREATOR =
            new Parcelable.Creator<CursorAnchorInfoRequest>() {
        @Override
        public CursorAnchorInfoRequest createFromParcel(Parcel source) {
            return new CursorAnchorInfoRequest(source);
        }

        @Override
        public CursorAnchorInfoRequest[] newArray(int size) {
            return new CursorAnchorInfoRequest[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }
}
Loading