/*
 * Copyright (C) 2008 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.cts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import android.content.ClipDescription;
import android.net.Uri;
import android.os.Bundle;
import android.text.Editable;
import android.text.Selection;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.view.View;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputContentInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.cts.util.InputConnectionTestUtils;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

@MediumTest
@RunWith(AndroidJUnit4.class)
public class BaseInputConnectionTest {

    private static BaseInputConnection createBaseInputConnection() {
        final View view = new View(InstrumentationRegistry.getTargetContext());
        return new BaseInputConnection(view, true);
    }

    @Test
    public void testDefaultMethods() {
        // These methods are default to return fixed result.
        final BaseInputConnection connection = createBaseInputConnection();

        assertFalse(connection.beginBatchEdit());
        assertFalse(connection.endBatchEdit());

        // only fit for test default implementation of commitCompletion.
        int completionId = 1;
        String completionString = "commitCompletion test";
        assertFalse(connection.commitCompletion(new CompletionInfo(completionId,
                0, completionString)));

        assertNull(connection.getExtractedText(new ExtractedTextRequest(), 0));

        // only fit for test default implementation of performEditorAction.
        int actionCode = 1;
        int actionId = 2;
        String action = "android.intent.action.MAIN";
        assertTrue(connection.performEditorAction(actionCode));
        assertFalse(connection.performContextMenuAction(actionId));
        assertFalse(connection.performPrivateCommand(action, new Bundle()));
    }

    @Test
    public void testOpComposingSpans() {
        Spannable text = new SpannableString("Test ComposingSpans");
        BaseInputConnection.setComposingSpans(text);
        assertTrue(BaseInputConnection.getComposingSpanStart(text) > -1);
        assertTrue(BaseInputConnection.getComposingSpanEnd(text) > -1);
        BaseInputConnection.removeComposingSpans(text);
        assertTrue(BaseInputConnection.getComposingSpanStart(text) == -1);
        assertTrue(BaseInputConnection.getComposingSpanEnd(text) == -1);
    }

    /**
     * getEditable: Return the target of edit operations. The default implementation
     *              returns its own fake editable that is just used for composing text.
     * clearMetaKeyStates: Default implementation uses
     *              MetaKeyKeyListener#clearMetaKeyState(long, int) to clear the state.
     *              BugId:1738511
     * commitText: Default implementation replaces any existing composing text with the given
     *             text.
     * deleteSurroundingText: The default implementation performs the deletion around the current
     *              selection position of the editable text.
     * getCursorCapsMode: The default implementation uses TextUtils.getCapsMode to get the
     *                  cursor caps mode for the current selection position in the editable text.
     *                  TextUtils.getCapsMode is tested fully in TextUtilsTest#testGetCapsMode.
     * getTextBeforeCursor, getTextAfterCursor: The default implementation performs the deletion
     *                          around the current selection position of the editable text.
     * setSelection: changes the selection position in the current editable text.
     */
    @Test
    public void testOpTextMethods() {
        final BaseInputConnection connection = createBaseInputConnection();

        // return is an default Editable instance with empty source
        final Editable text = connection.getEditable();
        assertNotNull(text);
        assertEquals(0, text.length());

        // Test commitText, not default fake mode
        CharSequence str = "TestCommit ";
        Editable inputText = Editable.Factory.getInstance().newEditable(str);
        connection.commitText(inputText, inputText.length());
        final Editable text2 = connection.getEditable();
        int strLength = str.length();
        assertEquals(strLength, text2.length());
        assertEquals(str.toString(), text2.toString());
        assertEquals(TextUtils.CAP_MODE_WORDS,
                connection.getCursorCapsMode(TextUtils.CAP_MODE_WORDS));
        int offLength = 3;
        CharSequence expected = str.subSequence(strLength - offLength, strLength);
        assertEquals(expected.toString(), connection.getTextBeforeCursor(offLength,
                BaseInputConnection.GET_TEXT_WITH_STYLES).toString());
        connection.setSelection(0, 0);
        expected = str.subSequence(0, offLength);
        assertEquals(expected.toString(), connection.getTextAfterCursor(offLength,
                BaseInputConnection.GET_TEXT_WITH_STYLES).toString());

        // Test deleteSurroundingText
        int end = text2.length();
        connection.setSelection(end, end);
        // Delete the ending space
        assertTrue(connection.deleteSurroundingText(1, 2));
        Editable text3 = connection.getEditable();
        assertEquals(strLength - 1, text3.length());
        String expectedDelString = "TestCommit";
        assertEquals(expectedDelString, text3.toString());
    }

    /**
     * finishComposingText: The default implementation removes the composing state from the
     *                      current editable text.
     * setComposingText: The default implementation places the given text into the editable,
     *                  replacing any existing composing text
     */
    @Test
    public void testFinishComposingText() {
        final BaseInputConnection connection = createBaseInputConnection();
        CharSequence str = "TestFinish";
        Editable inputText = Editable.Factory.getInstance().newEditable(str);
        connection.commitText(inputText, inputText.length());
        final Editable text = connection.getEditable();
        // Test finishComposingText, not default fake mode
        BaseInputConnection.setComposingSpans(text);
        assertTrue(BaseInputConnection.getComposingSpanStart(text) > -1);
        assertTrue(BaseInputConnection.getComposingSpanEnd(text) > -1);
        connection.finishComposingText();
        assertTrue(BaseInputConnection.getComposingSpanStart(text) == -1);
        assertTrue(BaseInputConnection.getComposingSpanEnd(text) == -1);
    }

    /**
     * Updates InputMethodManager with the current fullscreen mode.
     */
    @Test
    public void testReportFullscreenMode() {
        final InputMethodManager imm = InstrumentationRegistry.getInstrumentation()
                .getTargetContext().getSystemService(InputMethodManager.class);
        final BaseInputConnection connection = createBaseInputConnection();
        connection.reportFullscreenMode(false);
        assertFalse(imm.isFullscreenMode());
        connection.reportFullscreenMode(true);
        // Only IMEs are allowed to report full-screen mode.  Calling this method from the
        // application should have no effect.
        assertFalse(imm.isFullscreenMode());
    }

    /**
     * An utility method to create an instance of {@link BaseInputConnection} in the full editor
     * mode with an initial text and selection range.
     *
     * @param source the initial text.
     * @return {@link BaseInputConnection} instantiated in the full editor mode with {@code source}
     *         and selection range from {@code selectionStart} to {@code selectionEnd}
     */
    private static BaseInputConnection createConnectionWithSelection(CharSequence source) {
        final int selectionStart = Selection.getSelectionStart(source);
        final int selectionEnd = Selection.getSelectionEnd(source);
        final Editable editable = Editable.Factory.getInstance().newEditable(source);
        Selection.setSelection(editable, selectionStart, selectionEnd);
        final View view = new View(InstrumentationRegistry.getTargetContext());
        return new BaseInputConnection(view, true) {
            @Override
            public Editable getEditable() {
                return editable;
            }
        };
    }

    private static void verifyDeleteSurroundingTextMain(final String initialState,
            final int deleteBefore, final int deleteAfter, final String expectedState) {
        final CharSequence source = InputConnectionTestUtils.formatString(initialState);
        final BaseInputConnection ic = createConnectionWithSelection(source);
        ic.deleteSurroundingText(deleteBefore, deleteAfter);

        final CharSequence expectedString = InputConnectionTestUtils.formatString(expectedState);
        final int expectedSelectionStart = Selection.getSelectionStart(expectedString);
        final int expectedSelectionEnd = Selection.getSelectionEnd(expectedString);

        // It is sufficient to check the surrounding text up to source.length() characters, because
        // InputConnection.deleteSurroundingText() is not supposed to increase the text length.
        final int retrievalLength = source.length();
        if (expectedSelectionStart == 0) {
            assertTrue(TextUtils.isEmpty(ic.getTextBeforeCursor(retrievalLength, 0)));
        } else {
            assertEquals(expectedString.subSequence(0, expectedSelectionStart).toString(),
                    ic.getTextBeforeCursor(retrievalLength, 0).toString());
        }
        if (expectedSelectionStart == expectedSelectionEnd) {
            assertTrue(TextUtils.isEmpty(ic.getSelectedText(0)));  // null is allowed.
        } else {
            assertEquals(expectedString.subSequence(expectedSelectionStart,
                    expectedSelectionEnd).toString(), ic.getSelectedText(0).toString());
        }
        if (expectedSelectionEnd == expectedString.length()) {
            assertTrue(TextUtils.isEmpty(ic.getTextAfterCursor(retrievalLength, 0)));
        } else {
            assertEquals(expectedString.subSequence(expectedSelectionEnd,
                    expectedString.length()).toString(),
                    ic.getTextAfterCursor(retrievalLength, 0).toString());
        }
    }

    /**
     * Tests {@link BaseInputConnection#deleteSurroundingText(int, int)} comprehensively.
     */
    @Test
    public void testDeleteSurroundingText() {
        verifyDeleteSurroundingTextMain("012[]3456789", 0, 0, "012[]3456789");
        verifyDeleteSurroundingTextMain("012[]3456789", -1, -1, "012[]3456789");
        verifyDeleteSurroundingTextMain("012[]3456789", 1, 2, "01[]56789");
        verifyDeleteSurroundingTextMain("012[]3456789", 10, 1, "[]456789");
        verifyDeleteSurroundingTextMain("012[]3456789", 1, 10, "01[]");
        verifyDeleteSurroundingTextMain("[]0123456789", 3, 3, "[]3456789");
        verifyDeleteSurroundingTextMain("0123456789[]", 3, 3, "0123456[]");
        verifyDeleteSurroundingTextMain("012[345]6789", 0, 0, "012[345]6789");
        verifyDeleteSurroundingTextMain("012[345]6789", -1, -1, "012[345]6789");
        verifyDeleteSurroundingTextMain("012[345]6789", 1, 2, "01[345]89");
        verifyDeleteSurroundingTextMain("012[345]6789", 10, 1, "[345]789");
        verifyDeleteSurroundingTextMain("012[345]6789", 1, 10, "01[345]");
        verifyDeleteSurroundingTextMain("[012]3456789", 3, 3, "[012]6789");
        verifyDeleteSurroundingTextMain("0123456[789]", 3, 3, "0123[789]");
        verifyDeleteSurroundingTextMain("[0123456789]", 0, 0, "[0123456789]");
        verifyDeleteSurroundingTextMain("[0123456789]", 1, 1, "[0123456789]");

        // Surrogate characters do not have any special meanings.  Validating the character sequence
        // is beyond the goal of this API.
        verifyDeleteSurroundingTextMain("0<>[]3456789", 1, 0, "0<[]3456789");
        verifyDeleteSurroundingTextMain("0<>[]3456789", 2, 0, "0[]3456789");
        verifyDeleteSurroundingTextMain("0<>[]3456789", 3, 0, "[]3456789");
        verifyDeleteSurroundingTextMain("012[]<>56789", 0, 1, "012[]>56789");
        verifyDeleteSurroundingTextMain("012[]<>56789", 0, 2, "012[]56789");
        verifyDeleteSurroundingTextMain("012[]<>56789", 0, 3, "012[]6789");
        verifyDeleteSurroundingTextMain("0<<[]3456789", 1, 0, "0<[]3456789");
        verifyDeleteSurroundingTextMain("0<<[]3456789", 2, 0, "0[]3456789");
        verifyDeleteSurroundingTextMain("0<<[]3456789", 3, 0, "[]3456789");
        verifyDeleteSurroundingTextMain("012[]<<56789", 0, 1, "012[]<56789");
        verifyDeleteSurroundingTextMain("012[]<<56789", 0, 2, "012[]56789");
        verifyDeleteSurroundingTextMain("012[]<<56789", 0, 3, "012[]6789");
        verifyDeleteSurroundingTextMain("0>>[]3456789", 1, 0, "0>[]3456789");
        verifyDeleteSurroundingTextMain("0>>[]3456789", 2, 0, "0[]3456789");
        verifyDeleteSurroundingTextMain("0>>[]3456789", 3, 0, "[]3456789");
        verifyDeleteSurroundingTextMain("012[]>>56789", 0, 1, "012[]>56789");
        verifyDeleteSurroundingTextMain("012[]>>56789", 0, 2, "012[]56789");
        verifyDeleteSurroundingTextMain("012[]>>56789", 0, 3, "012[]6789");
    }

    private static void verifyDeleteSurroundingTextInCodePointsMain(String initialState,
            int deleteBeforeInCodePoints, int deleteAfterInCodePoints, String expectedState) {
        final CharSequence source = InputConnectionTestUtils.formatString(initialState);
        final BaseInputConnection ic = createConnectionWithSelection(source);
        ic.deleteSurroundingTextInCodePoints(deleteBeforeInCodePoints, deleteAfterInCodePoints);

        final CharSequence expectedString = InputConnectionTestUtils.formatString(expectedState);
        final int expectedSelectionStart = Selection.getSelectionStart(expectedString);
        final int expectedSelectionEnd = Selection.getSelectionEnd(expectedString);

        // It is sufficient to check the surrounding text up to source.length() characters, because
        // InputConnection.deleteSurroundingTextInCodePoints() is not supposed to increase the text
        // length.
        final int retrievalLength = source.length();
        if (expectedSelectionStart == 0) {
            assertTrue(TextUtils.isEmpty(ic.getTextBeforeCursor(retrievalLength, 0)));
        } else {
            assertEquals(expectedString.subSequence(0, expectedSelectionStart).toString(),
                    ic.getTextBeforeCursor(retrievalLength, 0).toString());
        }
        if (expectedSelectionStart == expectedSelectionEnd) {
            assertTrue(TextUtils.isEmpty(ic.getSelectedText(0)));  // null is allowed.
        } else {
            assertEquals(expectedString.subSequence(expectedSelectionStart,
                    expectedSelectionEnd).toString(), ic.getSelectedText(0).toString());
        }
        if (expectedSelectionEnd == expectedString.length()) {
            assertTrue(TextUtils.isEmpty(ic.getTextAfterCursor(retrievalLength, 0)));
        } else {
            assertEquals(expectedString.subSequence(expectedSelectionEnd,
                    expectedString.length()).toString(),
                    ic.getTextAfterCursor(retrievalLength, 0).toString());
        }
    }

    /**
     * Tests {@link BaseInputConnection#deleteSurroundingTextInCodePoints(int, int)}
     * comprehensively.
     */
    @Test
    public void testDeleteSurroundingTextInCodePoints() {
        verifyDeleteSurroundingTextInCodePointsMain("012[]3456789", 0, 0, "012[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]3456789", -1, -1, "012[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]3456789", 1, 2, "01[]56789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]3456789", 10, 1, "[]456789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]3456789", 1, 10, "01[]");
        verifyDeleteSurroundingTextInCodePointsMain("[]0123456789", 3, 3, "[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("0123456789[]", 3, 3, "0123456[]");
        verifyDeleteSurroundingTextInCodePointsMain("012[345]6789", 0, 0, "012[345]6789");
        verifyDeleteSurroundingTextInCodePointsMain("012[345]6789", -1, -1, "012[345]6789");
        verifyDeleteSurroundingTextInCodePointsMain("012[345]6789", 1, 2, "01[345]89");
        verifyDeleteSurroundingTextInCodePointsMain("012[345]6789", 10, 1, "[345]789");
        verifyDeleteSurroundingTextInCodePointsMain("012[345]6789", 1, 10, "01[345]");
        verifyDeleteSurroundingTextInCodePointsMain("[012]3456789", 3, 3, "[012]6789");
        verifyDeleteSurroundingTextInCodePointsMain("0123456[789]", 3, 3, "0123[789]");
        verifyDeleteSurroundingTextInCodePointsMain("[0123456789]", 0, 0, "[0123456789]");
        verifyDeleteSurroundingTextInCodePointsMain("[0123456789]", 1, 1, "[0123456789]");

        verifyDeleteSurroundingTextInCodePointsMain("0<>[]3456789", 1, 0, "0[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("0<>[]3456789", 2, 0, "[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("0<>[]3456789", 3, 0, "[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]<>56789", 0, 1, "012[]56789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]<>56789", 0, 2, "012[]6789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]<>56789", 0, 3, "012[]789");

        verifyDeleteSurroundingTextInCodePointsMain("[]<><><><><>", 0, 0, "[]<><><><><>");
        verifyDeleteSurroundingTextInCodePointsMain("[]<><><><><>", 0, 1, "[]<><><><>");
        verifyDeleteSurroundingTextInCodePointsMain("[]<><><><><>", 0, 2, "[]<><><>");
        verifyDeleteSurroundingTextInCodePointsMain("[]<><><><><>", 0, 3, "[]<><>");
        verifyDeleteSurroundingTextInCodePointsMain("[]<><><><><>", 0, 4, "[]<>");
        verifyDeleteSurroundingTextInCodePointsMain("[]<><><><><>", 0, 5, "[]");
        verifyDeleteSurroundingTextInCodePointsMain("[]<><><><><>", 0, 6, "[]");
        verifyDeleteSurroundingTextInCodePointsMain("[]<><><><><>", 0, 1000, "[]");
        verifyDeleteSurroundingTextInCodePointsMain("<><><><><>[]", 0, 0, "<><><><><>[]");
        verifyDeleteSurroundingTextInCodePointsMain("<><><><><>[]", 1, 0, "<><><><>[]");
        verifyDeleteSurroundingTextInCodePointsMain("<><><><><>[]", 2, 0, "<><><>[]");
        verifyDeleteSurroundingTextInCodePointsMain("<><><><><>[]", 3, 0, "<><>[]");
        verifyDeleteSurroundingTextInCodePointsMain("<><><><><>[]", 4, 0, "<>[]");
        verifyDeleteSurroundingTextInCodePointsMain("<><><><><>[]", 5, 0, "[]");
        verifyDeleteSurroundingTextInCodePointsMain("<><><><><>[]", 6, 0, "[]");
        verifyDeleteSurroundingTextInCodePointsMain("<><><><><>[]", 1000, 0, "[]");

        verifyDeleteSurroundingTextInCodePointsMain("0<<[]3456789", 1, 0, "0<<[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("0<<[]3456789", 2, 0, "0<<[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("0<<[]3456789", 3, 0, "0<<[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]<<56789", 0, 1, "012[]<<56789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]<<56789", 0, 2, "012[]<<56789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]<<56789", 0, 3, "012[]<<56789");
        verifyDeleteSurroundingTextInCodePointsMain("0>>[]3456789", 1, 0, "0>>[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("0>>[]3456789", 2, 0, "0>>[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("0>>[]3456789", 3, 0, "0>>[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]>>56789", 0, 1, "012[]>>56789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]>>56789", 0, 2, "012[]>>56789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]>>56789", 0, 3, "012[]>>56789");
        verifyDeleteSurroundingTextInCodePointsMain("01<[]>456789", 1, 0, "01<[]>456789");
        verifyDeleteSurroundingTextInCodePointsMain("01<[]>456789", 0, 1, "01<[]>456789");
        verifyDeleteSurroundingTextInCodePointsMain("<12[]3456789", 1, 0, "<1[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("<12[]3456789", 2, 0, "<[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("<12[]3456789", 3, 0, "<12[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("<<>[]3456789", 1, 0, "<[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("<<>[]3456789", 2, 0, "<<>[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("<<>[]3456789", 3, 0, "<<>[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]34>6789", 0, 1, "012[]4>6789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]34>6789", 0, 2, "012[]>6789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]34>6789", 0, 3, "012[]34>6789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]<>>6789", 0, 1, "012[]>6789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]<>>6789", 0, 2, "012[]<>>6789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]<>>6789", 0, 3, "012[]<>>6789");

        // Atomicity test.
        verifyDeleteSurroundingTextInCodePointsMain("0<<[]3456789", 1, 1, "0<<[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("0<<[]3456789", 2, 1, "0<<[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("0<<[]3456789", 3, 1, "0<<[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]<<56789", 1, 1, "012[]<<56789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]<<56789", 1, 2, "012[]<<56789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]<<56789", 1, 3, "012[]<<56789");
        verifyDeleteSurroundingTextInCodePointsMain("0>>[]3456789", 1, 1, "0>>[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("0>>[]3456789", 2, 1, "0>>[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("0>>[]3456789", 3, 1, "0>>[]3456789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]>>56789", 1, 1, "012[]>>56789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]>>56789", 1, 2, "012[]>>56789");
        verifyDeleteSurroundingTextInCodePointsMain("012[]>>56789", 1, 3, "012[]>>56789");
        verifyDeleteSurroundingTextInCodePointsMain("01<[]>456789", 1, 1, "01<[]>456789");

        // Do not verify the character sequences in the selected region.
        verifyDeleteSurroundingTextInCodePointsMain("01[><]456789", 1, 0, "0[><]456789");
        verifyDeleteSurroundingTextInCodePointsMain("01[><]456789", 0, 1, "01[><]56789");
        verifyDeleteSurroundingTextInCodePointsMain("01[><]456789", 1, 1, "0[><]56789");
    }

    @Test
    public void testCloseConnection() {
        final BaseInputConnection connection = createBaseInputConnection();

        final CharSequence source = "0123456789";
        connection.commitText(source, source.length());
        connection.setComposingRegion(2, 5);
        final Editable text = connection.getEditable();
        assertEquals(2, BaseInputConnection.getComposingSpanStart(text));
        assertEquals(5, BaseInputConnection.getComposingSpanEnd(text));

        // BaseInputConnection#closeConnection() must clear the on-going composition.
        connection.closeConnection();
        assertEquals(-1, BaseInputConnection.getComposingSpanStart(text));
        assertEquals(-1, BaseInputConnection.getComposingSpanEnd(text));
    }

    @Test
    public void testGetHandler() {
        final BaseInputConnection connection = createBaseInputConnection();

        // BaseInputConnection must not implement getHandler().
        assertNull(connection.getHandler());
    }

    @Test
    public void testCommitContent() {
        final BaseInputConnection connection = createBaseInputConnection();

        final InputContentInfo inputContentInfo = new InputContentInfo(
                Uri.parse("content://com.example/path"),
                new ClipDescription("sample content", new String[]{"image/png"}),
                Uri.parse("https://example.com"));
        // The default implementation should do nothing and just return false.
        assertFalse(connection.commitContent(inputContentInfo, 0 /* flags */, null /* opts */));
    }

    @Test
    public void testGetSelectedText_wrongSelection() {
        final BaseInputConnection connection = createBaseInputConnection();
        Editable editable = connection.getEditable();
        editable.append("hello");
        editable.setSpan(Selection.SELECTION_START, 4, 4, Spanned.SPAN_POINT_POINT);
        editable.removeSpan(Selection.SELECTION_END);

        // Should not crash.
        connection.getSelectedText(0);
    }
}
