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

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

Fix an off-by-one bug in EditableInputConnection#endBatchEdit() return value

This is a follow up CL to our previous CL [1], which had an off-by-one
bug when determining the return value of

   EditableInputConnection#endBatchEdit().

According to the API document of InputConnection#endBatchEdit(), the
following test should pass.

   EditText editText = new EditText(context);
   EditorInfo editorInfo = new EditorInfo();
   InputConnection editableInputConnection =
           editText.onCreateInputConnection(editorInfo);
   assertThat(editableInputConnection.beginBatchEdit()).isTrue();
   assertThat(editableInputConnection.beginBatchEdit()).isTrue();
   assertThat(editableInputConnection.endBatchEdit()).isTrue();
   assertThat(editableInputConnection.endBatchEdit()).isFalse(); // (*)
   assertThat(editableInputConnection.endBatchEdit()).isFalse();

However, the last assertion marked with (*) actually fails due to an
off-by-one bug.  This CL finally fixes it.

The risk of app compat breakages because of fixing this long standing
bug is supposed to be low, mainly because:

 * the system has not relied on this return value yet.
 * Widgets like WebView have correctly implemented this API.
 * IME has always received true no matter what the app returned, which
   is the same behavior as other async InputConnection APIs.

This CL adds several notes to InputConnection#endBatchEdit() document
to help developers correctly implement and use this API.

 [1]: I1ec5518fdc16fb0551fbce9d13f5d92eb4bc78c0
      c478c171

Fix: 209958658
Fix: 210165648
Test: atest -c CtsInputMethodTestCases:EditTextImeSupportTest
Change-Id: Ibc40072fa11a4d6e3c24b8d7860c914ccdbcbc8a
parent e30a7ed5
Loading
Loading
Loading
Loading
+18 −13
Original line number Original line Diff line number Diff line
@@ -836,20 +836,25 @@ public interface InputConnection {
    boolean beginBatchEdit();
    boolean beginBatchEdit();


    /**
    /**
     * Tell the editor that you are done with a batch edit previously
     * Tell the editor that you are done with a batch edit previously initiated with
     * initiated with {@link #beginBatchEdit}. This ends the latest
     * {@link #beginBatchEdit()}. This ends the latest batch only.
     * batch only.
     *
     *
     * <p><strong>IME authors:</strong> make sure you call this exactly once for each call to
     * <p><strong>IME authors:</strong> make sure you call this
     * {@link #beginBatchEdit()}.</p>
     * exactly once for each call to {@link #beginBatchEdit}.</p>
     *
     *
     * <p><strong>Editor authors:</strong> please be careful about batch edit nesting. Updates still
     * <p><strong>Editor authors:</strong> please be careful about
     * to be held back until the end of the last batch edit.  In case you are delegating this API
     * batch edit nesting. Updates still to be held back until the end
     * call to the one obtained from
     * of the last batch edit.</p>
     * {@link android.widget.EditText#onCreateInputConnection(EditorInfo)}, there was an off-by-one
     * that had returned {@code true} when its nested batch edit count becomes {@code 0} as a result
     * of invoking this API.  This bug is fixed in {@link android.os.Build.VERSION_CODES#TIRAMISU}.
     * </p>
     *
     *
     * @return true if there is still a batch edit in progress after closing
     * @return For editor authors, you must return {@code true} if a batch edit is still in progress
     * the latest one (in other words, if the nesting count is > 0), false
     *         after closing the latest one (in other words, if the nesting count is still a
     * otherwise or if the input connection is no longer valid.
     *         positive number). Return {@code false} otherwise.  For IME authors, you will
     *         always receive {@code true} as long as the request was sent to the editor, and
     *         receive {@code false} only if the input connection is no longer valid.
     */
     */
    boolean endBatchEdit();
    boolean endBatchEdit();


+1 −1
Original line number Original line Diff line number Diff line
@@ -89,7 +89,7 @@ public final class EditableInputConnection extends BaseInputConnection
                // contribution to mTextView's nested batch edit count is zero.
                // contribution to mTextView's nested batch edit count is zero.
                mTextView.endBatchEdit();
                mTextView.endBatchEdit();
                mBatchEditNesting--;
                mBatchEditNesting--;
                return true;
                return mBatchEditNesting > 0;
            }
            }
        }
        }
        return false;
        return false;