/*
 * Copyright (C) 2007 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.annotation.NonNull;
import android.annotation.Nullable;
import android.inputmethodservice.InputMethodService;
import android.os.Bundle;
import android.os.Handler;
import android.os.LocaleList;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;

/**
 * The InputConnection interface is the communication channel from an
 * {@link InputMethod} back to the application that is receiving its
 * input. It is used to perform such things as reading text around the
 * cursor, committing text to the text box, and sending raw key events
 * to the application.
 *
 * <p>Starting from API Level {@link android.os.Build.VERSION_CODES#N},
 * the system can deal with the situation where the application directly
 * implements this class but one or more of the following methods are
 * not implemented.</p>
 * <ul>
 *     <li>{@link #getSelectedText(int)}, which was introduced in
 *     {@link android.os.Build.VERSION_CODES#GINGERBREAD}.</li>
 *     <li>{@link #setComposingRegion(int, int)}, which was introduced
 *     in {@link android.os.Build.VERSION_CODES#GINGERBREAD}.</li>
 *     <li>{@link #commitCorrection(CorrectionInfo)}, which was introduced
 *     in {@link android.os.Build.VERSION_CODES#HONEYCOMB}.</li>
 *     <li>{@link #requestCursorUpdates(int)}, which was introduced in
 *     {@link android.os.Build.VERSION_CODES#LOLLIPOP}.</li>
 *     <li>{@link #deleteSurroundingTextInCodePoints(int, int)}, which
 *     was introduced in {@link android.os.Build.VERSION_CODES#N}.</li>
 *     <li>{@link #getHandler()}, which was introduced in
 *     {@link android.os.Build.VERSION_CODES#N}.</li>
 *     <li>{@link #closeConnection()}, which was introduced in
 *     {@link android.os.Build.VERSION_CODES#N}.</li>
 *     <li>{@link #commitContent(InputContentInfo, int, Bundle)}, which was
 *     introduced in {@link android.os.Build.VERSION_CODES#N_MR1}.</li>
 * </ul>
 *
 * <h3>Implementing an IME or an editor</h3>
 * <p>Text input is the result of the synergy of two essential components:
 * an Input Method Engine (IME) and an editor. The IME can be a
 * software keyboard, a handwriting interface, an emoji palette, a
 * speech-to-text engine, and so on. There are typically several IMEs
 * installed on any given Android device. In Android, IMEs extend
 * {@link android.inputmethodservice.InputMethodService}.
 * For more information about how to create an IME, see the
 * <a href="{@docRoot}guide/topics/text/creating-input-method.html">
 * Creating an input method</a> guide.
 *
 * The editor is the component that receives text and displays it.
 * Typically, this is an {@link android.widget.EditText} instance, but
 * some applications may choose to implement their own editor for
 * various reasons. This is a large and complicated task, and an
 * application that does this needs to make sure the behavior is
 * consistent with standard EditText behavior in Android. An editor
 * needs to interact with the IME, receiving commands through
 * this InputConnection interface, and sending commands through
 * {@link android.view.inputmethod.InputMethodManager}. An editor
 * should start by implementing
 * {@link android.view.View#onCreateInputConnection(EditorInfo)}
 * to return its own input connection.</p>
 *
 * <p>If you are implementing your own IME, you will need to call the
 * methods in this interface to interact with the application. Be sure
 * to test your IME with a wide range of applications, including
 * browsers and rich text editors, as some may have peculiarities you
 * need to deal with. Remember your IME may not be the only source of
 * changes on the text, and try to be as conservative as possible in
 * the data you send and as liberal as possible in the data you
 * receive.</p>
 *
 * <p>If you are implementing your own editor, you will probably need
 * to provide your own subclass of {@link BaseInputConnection} to
 * answer to the commands from IMEs. Please be sure to test your
 * editor with as many IMEs as you can as their behavior can vary a
 * lot. Also be sure to test with various languages, including CJK
 * languages and right-to-left languages like Arabic, as these may
 * have different input requirements. When in doubt about the
 * behavior you should adopt for a particular call, please mimic the
 * default TextView implementation in the latest Android version, and
 * if you decide to drift from it, please consider carefully that
 * inconsistencies in text editor behavior is almost universally felt
 * as a bad thing by users.</p>
 *
 * <h3>Cursors, selections and compositions</h3>
 * <p>In Android, the cursor and the selection are one and the same
 * thing. A "cursor" is just the special case of a zero-sized
 * selection. As such, this documentation uses them
 * interchangeably. Any method acting "before the cursor" would act
 * before the start of the selection if there is one, and any method
 * acting "after the cursor" would act after the end of the
 * selection.</p>
 *
 * <p>An editor needs to be able to keep track of a currently
 * "composing" region, like the standard edition widgets do. The
 * composition is marked in a specific style: see
 * {@link android.text.Spanned#SPAN_COMPOSING}. IMEs use this to help
 * the user keep track of what part of the text they are currently
 * focusing on, and interact with the editor using
 * {@link InputConnection#setComposingText(CharSequence, int)},
 * {@link InputConnection#setComposingRegion(int, int)} and
 * {@link InputConnection#finishComposingText()}.
 * The composing region and the selection are completely independent
 * of each other, and the IME may use them however they see fit.</p>
 */
public interface InputConnection {
    /**
     * Flag for use with {@link #getTextAfterCursor} and
     * {@link #getTextBeforeCursor} to have style information returned
     * along with the text. If not set, {@link #getTextAfterCursor}
     * sends only the raw text, without style or other spans. If set,
     * it may return a complex CharSequence of both text and style
     * spans. <strong>Editor authors</strong>: you should strive to
     * send text with styles if possible, but it is not required.
     */
    int GET_TEXT_WITH_STYLES = 0x0001;

    /**
     * Flag for use with {@link #getExtractedText} to indicate you
     * would like to receive updates when the extracted text changes.
     */
    int GET_EXTRACTED_TEXT_MONITOR = 0x0001;

    /**
     * Get <var>n</var> characters of text before the current cursor
     * position.
     *
     * <p>This method may fail either if the input connection has
     * become invalid (such as its process crashing) or the editor is
     * taking too long to respond with the text (it is given a couple
     * seconds to return). In either case, null is returned. This
     * method does not affect the text in the editor in any way, nor
     * does it affect the selection or composing spans.</p>
     *
     * <p>If {@link #GET_TEXT_WITH_STYLES} is supplied as flags, the
     * editor should return a {@link android.text.SpannableString}
     * with all the spans set on the text.</p>
     *
     * <p><strong>IME authors:</strong> please consider this will
     * trigger an IPC round-trip that will take some time. Assume this
     * method consumes a lot of time. Also, please keep in mind the
     * Editor may choose to return less characters than requested even
     * if they are available for performance reasons.</p>
     *
     * <p><strong>Editor authors:</strong> please be careful of race
     * conditions in implementing this call. An IME can make a change
     * to the text and use this method right away; you need to make
     * sure the returned value is consistent with the result of the
     * latest edits. Also, you may return less than n characters if performance
     * dictates so, but keep in mind IMEs are relying on this for many
     * functions: you should not, for example, limit the returned value to
     * the current line, and specifically do not return 0 characters unless
     * the cursor is really at the start of the text.</p>
     *
     * @param n The expected length of the text.
     * @param flags Supplies additional options controlling how the text is
     * returned. May be either 0 or {@link #GET_TEXT_WITH_STYLES}.
     * @return the text before the cursor position; the length of the
     * returned text might be less than <var>n</var>.
     */
    CharSequence getTextBeforeCursor(int n, int flags);

    /**
     * Get <var>n</var> characters of text after the current cursor
     * position.
     *
     * <p>This method may fail either if the input connection has
     * become invalid (such as its process crashing) or the client is
     * taking too long to respond with the text (it is given a couple
     * seconds to return). In either case, null is returned.
     *
     * <p>This method does not affect the text in the editor in any
     * way, nor does it affect the selection or composing spans.</p>
     *
     * <p>If {@link #GET_TEXT_WITH_STYLES} is supplied as flags, the
     * editor should return a {@link android.text.SpannableString}
     * with all the spans set on the text.</p>
     *
     * <p><strong>IME authors:</strong> please consider this will
     * trigger an IPC round-trip that will take some time. Assume this
     * method consumes a lot of time.</p>
     *
     * <p><strong>Editor authors:</strong> please be careful of race
     * conditions in implementing this call. An IME can make a change
     * to the text and use this method right away; you need to make
     * sure the returned value is consistent with the result of the
     * latest edits. Also, you may return less than n characters if performance
     * dictates so, but keep in mind IMEs are relying on this for many
     * functions: you should not, for example, limit the returned value to
     * the current line, and specifically do not return 0 characters unless
     * the cursor is really at the end of the text.</p>
     *
     * @param n The expected length of the text.
     * @param flags Supplies additional options controlling how the text is
     * returned. May be either 0 or {@link #GET_TEXT_WITH_STYLES}.
     *
     * @return the text after the cursor position; the length of the
     * returned text might be less than <var>n</var>.
     */
    CharSequence getTextAfterCursor(int n, int flags);

    /**
     * Gets the selected text, if any.
     *
     * <p>This method may fail if either the input connection has
     * become invalid (such as its process crashing) or the client is
     * taking too long to respond with the text (it is given a couple
     * of seconds to return). In either case, null is returned.</p>
     *
     * <p>This method must not cause any changes in the editor's
     * state.</p>
     *
     * <p>If {@link #GET_TEXT_WITH_STYLES} is supplied as flags, the
     * editor should return a {@link android.text.SpannableString}
     * with all the spans set on the text.</p>
     *
     * <p><strong>IME authors:</strong> please consider this will
     * trigger an IPC round-trip that will take some time. Assume this
     * method consumes a lot of time.</p>
     *
     * <p><strong>Editor authors:</strong> please be careful of race
     * conditions in implementing this call. An IME can make a change
     * to the text or change the selection position and use this
     * method right away; you need to make sure the returned value is
     * consistent with the results of the latest edits.</p>
     *
     * @param flags Supplies additional options controlling how the text is
     * returned. May be either 0 or {@link #GET_TEXT_WITH_STYLES}.
     * @return the text that is currently selected, if any, or null if
     * no text is selected. In {@link android.os.Build.VERSION_CODES#N} and
     * later, returns false when the target application does not implement
     * this method.
     */
    CharSequence getSelectedText(int flags);

    /**
     * Retrieve the current capitalization mode in effect at the
     * current cursor position in the text. See
     * {@link android.text.TextUtils#getCapsMode TextUtils.getCapsMode}
     * for more information.
     *
     * <p>This method may fail either if the input connection has
     * become invalid (such as its process crashing) or the client is
     * taking too long to respond with the text (it is given a couple
     * seconds to return). In either case, 0 is returned.</p>
     *
     * <p>This method does not affect the text in the editor in any
     * way, nor does it affect the selection or composing spans.</p>
     *
     * <p><strong>Editor authors:</strong> please be careful of race
     * conditions in implementing this call. An IME can change the
     * cursor position and use this method right away; you need to make
     * sure the returned value is consistent with the results of the
     * latest edits and changes to the cursor position.</p>
     *
     * @param reqModes The desired modes to retrieve, as defined by
     * {@link android.text.TextUtils#getCapsMode TextUtils.getCapsMode}. These
     * constants are defined so that you can simply pass the current
     * {@link EditorInfo#inputType TextBoxAttribute.contentType} value
     * directly in to here.
     * @return the caps mode flags that are in effect at the current
     * cursor position. See TYPE_TEXT_FLAG_CAPS_* in {@link android.text.InputType}.
     */
    int getCursorCapsMode(int reqModes);

    /**
     * Retrieve the current text in the input connection's editor, and
     * monitor for any changes to it. This function returns with the
     * current text, and optionally the input connection can send
     * updates to the input method when its text changes.
     *
     * <p>This method may fail either if the input connection has
     * become invalid (such as its process crashing) or the client is
     * taking too long to respond with the text (it is given a couple
     * seconds to return). In either case, null is returned.</p>
     *
     * <p>Editor authors: as a general rule, try to comply with the
     * fields in <code>request</code> for how many chars to return,
     * but if performance or convenience dictates otherwise, please
     * feel free to do what is most appropriate for your case. Also,
     * if the
     * {@link #GET_EXTRACTED_TEXT_MONITOR} flag is set, you should be
     * calling
     * {@link InputMethodManager#updateExtractedText(View, int, ExtractedText)}
     * whenever you call
     * {@link InputMethodManager#updateSelection(View, int, int, int, int)}.</p>
     *
     * @param request Description of how the text should be returned.
     * {@link android.view.inputmethod.ExtractedTextRequest}
     * @param flags Additional options to control the client, either 0 or
     * {@link #GET_EXTRACTED_TEXT_MONITOR}.

     * @return an {@link android.view.inputmethod.ExtractedText}
     * object describing the state of the text view and containing the
     * extracted text itself, or null if the input connection is no
     * longer valid of the editor can't comply with the request for
     * some reason.
     */
    ExtractedText getExtractedText(ExtractedTextRequest request, int flags);

    /**
     * Delete <var>beforeLength</var> characters of text before the
     * current cursor position, and delete <var>afterLength</var>
     * characters of text after the current cursor position, excluding
     * the selection. Before and after refer to the order of the
     * characters in the string, not to their visual representation:
     * this means you don't have to figure out the direction of the
     * text and can just use the indices as-is.
     *
     * <p>The lengths are supplied in Java chars, not in code points
     * or in glyphs.</p>
     *
     * <p>Since this method only operates on text before and after the
     * selection, it can't affect the contents of the selection. This
     * may affect the composing span if the span includes characters
     * that are to be deleted, but otherwise will not change it. If
     * some characters in the composing span are deleted, the
     * composing span will persist but get shortened by however many
     * chars inside it have been removed.</p>
     *
     * <p><strong>IME authors:</strong> please be careful not to
     * delete only half of a surrogate pair. Also take care not to
     * delete more characters than are in the editor, as that may have
     * ill effects on the application. Calling this method will cause
     * the editor to call
     * {@link android.inputmethodservice.InputMethodService#onUpdateSelection(int, int, int, int,
     * int, int)} on your service after the batch input is over.</p>
     *
     * <p><strong>Editor authors:</strong> please be careful of race
     * conditions in implementing this call. An IME can make a change
     * to the text or change the selection position and use this
     * method right away; you need to make sure the effects are
     * consistent with the results of the latest edits. Also, although
     * the IME should not send lengths bigger than the contents of the
     * string, you should check the values for overflows and trim the
     * indices to the size of the contents to avoid crashes. Since
     * this changes the contents of the editor, you need to make the
     * changes known to the input method by calling
     * {@link InputMethodManager#updateSelection(View, int, int, int, int)},
     * but be careful to wait until the batch edit is over if one is
     * in progress.</p>
     *
     * @param beforeLength The number of characters before the cursor to be deleted, in code unit.
     *        If this is greater than the number of existing characters between the beginning of the
     *        text and the cursor, then this method does not fail but deletes all the characters in
     *        that range.
     * @param afterLength The number of characters after the cursor to be deleted, in code unit.
     *        If this is greater than the number of existing characters between the cursor and
     *        the end of the text, then this method does not fail but deletes all the characters in
     *        that range.
     * @return true on success, false if the input connection is no longer valid.
     */
    boolean deleteSurroundingText(int beforeLength, int afterLength);

    /**
     * A variant of {@link #deleteSurroundingText(int, int)}. Major differences are:
     *
     * <ul>
     *     <li>The lengths are supplied in code points, not in Java chars or in glyphs.</>
     *     <li>This method does nothing if there are one or more invalid surrogate pairs in the
     *     requested range.</li>
     * </ul>
     *
     * <p><strong>Editor authors:</strong> In addition to the requirement in
     * {@link #deleteSurroundingText(int, int)}, make sure to do nothing when one ore more invalid
     * surrogate pairs are found in the requested range.</p>
     *
     * @see #deleteSurroundingText(int, int)
     *
     * @param beforeLength The number of characters before the cursor to be deleted, in code points.
     *        If this is greater than the number of existing characters between the beginning of the
     *        text and the cursor, then this method does not fail but deletes all the characters in
     *        that range.
     * @param afterLength The number of characters after the cursor to be deleted, in code points.
     *        If this is greater than the number of existing characters between the cursor and
     *        the end of the text, then this method does not fail but deletes all the characters in
     *        that range.
     * @return true on success, false if the input connection is no longer valid.  Returns
     * {@code false} when the target application does not implement this method.
     */
    boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength);

    /**
     * Replace the currently composing text with the given text, and
     * set the new cursor position. Any composing text set previously
     * will be removed automatically.
     *
     * <p>If there is any composing span currently active, all
     * characters that it comprises are removed. The passed text is
     * added in its place, and a composing span is added to this
     * text. If there is no composing span active, the passed text is
     * added at the cursor position (removing selected characters
     * first if any), and a composing span is added on the new text.
     * Finally, the cursor is moved to the location specified by
     * <code>newCursorPosition</code>.</p>
     *
     * <p>This is usually called by IMEs to add or remove or change
     * characters in the composing span. Calling this method will
     * cause the editor to call
     * {@link android.inputmethodservice.InputMethodService#onUpdateSelection(int, int, int, int,
     * int, int)} on the current IME after the batch input is over.</p>
     *
     * <p><strong>Editor authors:</strong> please keep in mind the
     * text may be very similar or completely different than what was
     * in the composing span at call time, or there may not be a
     * composing span at all. Please note that although it's not
     * typical use, the string may be empty. Treat this normally,
     * replacing the currently composing text with an empty string.
     * Also, be careful with the cursor position. IMEs rely on this
     * working exactly as described above. Since this changes the
     * contents of the editor, you need to make the changes known to
     * the input method by calling
     * {@link InputMethodManager#updateSelection(View, int, int, int, int)},
     * but be careful to wait until the batch edit is over if one is
     * in progress. Note that this method can set the cursor position
     * on either edge of the composing text or entirely outside it,
     * but the IME may also go on to move the cursor position to
     * within the composing text in a subsequent call so you should
     * make no assumption at all: the composing text and the selection
     * are entirely independent.</p>
     *
     * @param text The composing text with styles if necessary. If no style
     *        object attached to the text, the default style for composing text
     *        is used. See {@link android.text.Spanned} for how to attach style
     *        object to the text. {@link android.text.SpannableString} and
     *        {@link android.text.SpannableStringBuilder} are two
     *        implementations of the interface {@link android.text.Spanned}.
     * @param newCursorPosition The new cursor position around the text. If
     *        > 0, this is relative to the end of the text - 1; if <= 0, this
     *        is relative to the start of the text. So a value of 1 will
     *        always advance you to the position after the full text being
     *        inserted. Note that this means you can't position the cursor
     *        within the text, because the editor can make modifications to
     *        the text you are providing so it is not possible to correctly
     *        specify locations there.
     * @return true on success, false if the input connection is no longer
     * valid.
     */
    boolean setComposingText(CharSequence text, int newCursorPosition);

    /**
     * Mark a certain region of text as composing text. If there was a
     * composing region, the characters are left as they were and the
     * composing span removed, as if {@link #finishComposingText()}
     * has been called. The default style for composing text is used.
     *
     * <p>The passed indices are clipped to the contents bounds. If
     * the resulting region is zero-sized, no region is marked and the
     * effect is the same as that of calling {@link #finishComposingText()}.
     * The order of start and end is not important. In effect, the
     * region from start to end and the region from end to start is
     * the same. Editor authors, be ready to accept a start that is
     * greater than end.</p>
     *
     * <p>Since this does not change the contents of the text, editors should not call
     * {@link InputMethodManager#updateSelection(View, int, int, int, int)} and
     * IMEs should not receive
     * {@link android.inputmethodservice.InputMethodService#onUpdateSelection(int, int, int, int,
     * int, int)}.</p>
     *
     * <p>This has no impact on the cursor/selection position. It may
     * result in the cursor being anywhere inside or outside the
     * composing region, including cases where the selection and the
     * composing region overlap partially or entirely.</p>
     *
     * @param start the position in the text at which the composing region begins
     * @param end the position in the text at which the composing region ends
     * @return true on success, false if the input connection is no longer
     * valid. In {@link android.os.Build.VERSION_CODES#N} and later, false is returned when the
     * target application does not implement this method.
     */
    boolean setComposingRegion(int start, int end);

    /**
     * Have the text editor finish whatever composing text is
     * currently active. This simply leaves the text as-is, removing
     * any special composing styling or other state that was around
     * it. The cursor position remains unchanged.
     *
     * <p><strong>IME authors:</strong> be aware that this call may be
     * expensive with some editors.</p>
     *
     * <p><strong>Editor authors:</strong> please note that the cursor
     * may be anywhere in the contents when this is called, including
     * in the middle of the composing span or in a completely
     * unrelated place. It must not move.</p>
     *
     * @return true on success, false if the input connection
     * is no longer valid.
     */
    boolean finishComposingText();

    /**
     * Commit text to the text box and set the new cursor position.
     *
     * <p>This method removes the contents of the currently composing
     * text and replaces it with the passed CharSequence, and then
     * moves the cursor according to {@code newCursorPosition}. If there
     * is no composing text when this method is called, the new text is
     * inserted at the cursor position, removing text inside the selection
     * if any. This behaves like calling
     * {@link #setComposingText(CharSequence, int) setComposingText(text, newCursorPosition)}
     * then {@link #finishComposingText()}.</p>
     *
     * <p>Calling this method will cause the editor to call
     * {@link android.inputmethodservice.InputMethodService#onUpdateSelection(int, int, int, int,
     * int, int)} on the current IME after the batch input is over.
     * <strong>Editor authors</strong>, for this to happen you need to
     * make the changes known to the input method by calling
     * {@link InputMethodManager#updateSelection(View, int, int, int, int)},
     * but be careful to wait until the batch edit is over if one is
     * in progress.</p>
     *
     * @param text The text to commit. This may include styles.
     * @param newCursorPosition The new cursor position around the text,
     *        in Java characters. If > 0, this is relative to the end
     *        of the text - 1; if <= 0, this is relative to the start
     *        of the text. So a value of 1 will always advance the cursor
     *        to the position after the full text being inserted. Note that
     *        this means you can't position the cursor within the text,
     *        because the editor can make modifications to the text
     *        you are providing so it is not possible to correctly specify
     *        locations there.
     * @return true on success, false if the input connection is no longer
     * valid.
     */
    boolean commitText(CharSequence text, int newCursorPosition);

    /**
     * Commit a completion the user has selected from the possible ones
     * previously reported to {@link InputMethodSession#displayCompletions
     * InputMethodSession#displayCompletions(CompletionInfo[])} or
     * {@link InputMethodManager#displayCompletions
     * InputMethodManager#displayCompletions(View, CompletionInfo[])}.
     * This will result in the same behavior as if the user had
     * selected the completion from the actual UI. In all other
     * respects, this behaves like {@link #commitText(CharSequence, int)}.
     *
     * <p><strong>IME authors:</strong> please take care to send the
     * same object that you received through
     * {@link android.inputmethodservice.InputMethodService#onDisplayCompletions(CompletionInfo[])}.
     * </p>
     *
     * <p><strong>Editor authors:</strong> if you never call
     * {@link InputMethodSession#displayCompletions(CompletionInfo[])} or
     * {@link InputMethodManager#displayCompletions(View, CompletionInfo[])} then
     * a well-behaved IME should never call this on your input
     * connection, but be ready to deal with misbehaving IMEs without
     * crashing.</p>
     *
     * <p>Calling this method (with a valid {@link CompletionInfo} object)
     * will cause the editor to call
     * {@link android.inputmethodservice.InputMethodService#onUpdateSelection(int, int, int, int,
     * int, int)} on the current IME after the batch input is over.
     * <strong>Editor authors</strong>, for this to happen you need to
     * make the changes known to the input method by calling
     * {@link InputMethodManager#updateSelection(View, int, int, int, int)},
     * but be careful to wait until the batch edit is over if one is
     * in progress.</p>
     *
     * @param text The committed completion.
     * @return true on success, false if the input connection is no longer
     * valid.
     */
    boolean commitCompletion(CompletionInfo text);

    /**
     * Commit a correction automatically performed on the raw user's input. A
     * typical example would be to correct typos using a dictionary.
     *
     * <p>Calling this method will cause the editor to call
     * {@link android.inputmethodservice.InputMethodService#onUpdateSelection(int, int, int, int,
     * int, int)} on the current IME after the batch input is over.
     * <strong>Editor authors</strong>, for this to happen you need to
     * make the changes known to the input method by calling
     * {@link InputMethodManager#updateSelection(View, int, int, int, int)},
     * but be careful to wait until the batch edit is over if one is
     * in progress.</p>
     *
     * @param correctionInfo Detailed information about the correction.
     * @return true on success, false if the input connection is no longer valid.
     * In {@link android.os.Build.VERSION_CODES#N} and later, returns false
     * when the target application does not implement this method.
     */
    boolean commitCorrection(CorrectionInfo correctionInfo);

    /**
     * Set the selection of the text editor. To set the cursor
     * position, start and end should have the same value.
     *
     * <p>Since this moves the cursor, calling this method will cause
     * the editor to call
     * {@link android.inputmethodservice.InputMethodService#onUpdateSelection(int, int, int, int,
     * int, int)} on the current IME after the batch input is over.
     * <strong>Editor authors</strong>, for this to happen you need to
     * make the changes known to the input method by calling
     * {@link InputMethodManager#updateSelection(View, int, int, int, int)},
     * but be careful to wait until the batch edit is over if one is
     * in progress.</p>
     *
     * <p>This has no effect on the composing region which must stay
     * unchanged. The order of start and end is not important. In
     * effect, the region from start to end and the region from end to
     * start is the same. Editor authors, be ready to accept a start
     * that is greater than end.</p>
     *
     * @param start the character index where the selection should start.
     * @param end the character index where the selection should end.
     * @return true on success, false if the input connection is no longer
     * valid.
     */
    boolean setSelection(int start, int end);

    /**
     * Have the editor perform an action it has said it can do.
     *
     * <p>This is typically used by IMEs when the user presses the key
     * associated with the action.</p>
     *
     * @param editorAction This must be one of the action constants for
     * {@link EditorInfo#imeOptions EditorInfo.editorType}, such as
     * {@link EditorInfo#IME_ACTION_GO EditorInfo.EDITOR_ACTION_GO}.
     * @return true on success, false if the input connection is no longer
     * valid.
     */
    boolean performEditorAction(int editorAction);

    /**
     * Perform a context menu action on the field. The given id may be one of:
     * {@link android.R.id#selectAll},
     * {@link android.R.id#startSelectingText}, {@link android.R.id#stopSelectingText},
     * {@link android.R.id#cut}, {@link android.R.id#copy},
     * {@link android.R.id#paste}, {@link android.R.id#copyUrl},
     * or {@link android.R.id#switchInputMethod}
     */
    boolean performContextMenuAction(int id);

    /**
     * Tell the editor that you are starting a batch of editor
     * operations. The editor will try to avoid sending you updates
     * about its state until {@link #endBatchEdit} is called. Batch
     * edits nest.
     *
     * <p><strong>IME authors:</strong> use this to avoid getting
     * calls to
     * {@link android.inputmethodservice.InputMethodService#onUpdateSelection(int, int, int, int,
     * int, int)} corresponding to intermediate state. Also, use this to avoid
     * flickers that may arise from displaying intermediate state. Be
     * sure to call {@link #endBatchEdit} for each call to this, or
     * you may block updates in the editor.</p>
     *
     * <p><strong>Editor authors:</strong> while a batch edit is in
     * progress, take care not to send updates to the input method and
     * not to update the display. IMEs use this intensively to this
     * effect. Also please note that batch edits need to nest
     * correctly.</p>
     *
     * @return true if a batch edit is now in progress, false otherwise. Since
     * this method starts a batch edit, that means it will always return true
     * unless the input connection is no longer valid.
     */
    boolean beginBatchEdit();

    /**
     * Tell the editor that you are done with a batch edit previously
     * initiated with {@link #beginBatchEdit}. This ends the latest
     * batch only.
     *
     * <p><strong>IME authors:</strong> make sure you call this
     * exactly once for each call to {@link #beginBatchEdit}.</p>
     *
     * <p><strong>Editor authors:</strong> please be careful about
     * batch edit nesting. Updates still to be held back until the end
     * of the last batch edit.</p>
     *
     * @return true if there is still a batch edit in progress after closing
     * the latest one (in other words, if the nesting count is > 0), false
     * otherwise or if the input connection is no longer valid.
     */
    boolean endBatchEdit();

    /**
     * Send a key event to the process that is currently attached
     * through this input connection. The event will be dispatched
     * like a normal key event, to the currently focused view; this
     * generally is the view that is providing this InputConnection,
     * but due to the asynchronous nature of this protocol that can
     * not be guaranteed and the focus may have changed by the time
     * the event is received.
     *
     * <p>This method can be used to send key events to the
     * application. For example, an on-screen keyboard may use this
     * method to simulate a hardware keyboard. There are three types
     * of standard keyboards, numeric (12-key), predictive (20-key)
     * and ALPHA (QWERTY). You can specify the keyboard type by
     * specify the device id of the key event.</p>
     *
     * <p>You will usually want to set the flag
     * {@link KeyEvent#FLAG_SOFT_KEYBOARD KeyEvent.FLAG_SOFT_KEYBOARD}
     * on all key event objects you give to this API; the flag will
     * not be set for you.</p>
     *
     * <p>Note that it's discouraged to send such key events in normal
     * operation; this is mainly for use with
     * {@link android.text.InputType#TYPE_NULL} type text fields. Use
     * the {@link #commitText} family of methods to send text to the
     * application instead.</p>
     *
     * @param event The key event.
     * @return true on success, false if the input connection is no longer
     * valid.
     *
     * @see KeyEvent
     * @see KeyCharacterMap#NUMERIC
     * @see KeyCharacterMap#PREDICTIVE
     * @see KeyCharacterMap#ALPHA
     */
    boolean sendKeyEvent(KeyEvent event);

    /**
     * Clear the given meta key pressed states in the given input
     * connection.
     *
     * <p>This can be used by the IME to clear the meta key states set
     * by a hardware keyboard with latched meta keys, if the editor
     * keeps track of these.</p>
     *
     * @param states The states to be cleared, may be one or more bits as
     * per {@link KeyEvent#getMetaState() KeyEvent.getMetaState()}.
     * @return true on success, false if the input connection is no longer
     * valid.
     */
    boolean clearMetaKeyStates(int states);

    /**
     * Called back when the connected IME switches between fullscreen and normal modes.
     *
     * <p>Note: On {@link android.os.Build.VERSION_CODES#O} and later devices, input methods are no
     * longer allowed to directly call this method at any time. To signal this event in the target
     * application, input methods should always call
     * {@link InputMethodService#updateFullscreenMode()} instead. This approach should work on API
     * {@link android.os.Build.VERSION_CODES#N_MR1} and prior devices.</p>
     *
     * @return For editor authors, the return value will always be ignored. For IME authors, this
     *         always returns {@code true} on {@link android.os.Build.VERSION_CODES#N_MR1} and prior
     *         devices and {@code false} on {@link android.os.Build.VERSION_CODES#O} and later
     *         devices.
     * @see InputMethodManager#isFullscreenMode()
     */
    boolean reportFullscreenMode(boolean enabled);

    /**
     * API to send private commands from an input method to its
     * connected editor. This can be used to provide domain-specific
     * features that are only known between certain input methods and
     * their clients. Note that because the InputConnection protocol
     * is asynchronous, you have no way to get a result back or know
     * if the client understood the command; you can use the
     * information in {@link EditorInfo} to determine if a client
     * supports a particular command.
     *
     * @param action Name of the command to be performed. This <em>must</em>
     * be a scoped name, i.e. prefixed with a package name you own, so that
     * different developers will not create conflicting commands.
     * @param data Any data to include with the command.
     * @return true if the command was sent (whether or not the
     * associated editor understood it), false if the input connection is no longer
     * valid.
     */
    boolean performPrivateCommand(String action, Bundle data);

    /**
     * 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 #CURSOR_UPDATE_MONITOR}.
     */
    int CURSOR_UPDATE_IMMEDIATE = 1 << 0;

    /**
     * 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#requestCursorUpdates(int)} again with this flag off.
     * <p>
     * This flag can be used together with {@link #CURSOR_UPDATE_IMMEDIATE}.
     * </p>
     */
    int CURSOR_UPDATE_MONITOR = 1 << 1;

    /**
     * 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 {@link #CURSOR_UPDATE_IMMEDIATE} and/or
     * {@link #CURSOR_UPDATE_MONITOR}. Pass {@code 0} to disable the effect of
     * {@link #CURSOR_UPDATE_MONITOR}.
     * @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)}.
     * In {@link android.os.Build.VERSION_CODES#N} and later, returns {@code false} also when the
     * target application does not implement this method.
     */
    boolean requestCursorUpdates(int cursorUpdateMode);

    /**
     * Called by the {@link InputMethodManager} to enable application developers to specify a
     * dedicated {@link Handler} on which incoming IPC method calls from input methods will be
     * dispatched.
     *
     * <p>Note: This does nothing when called from input methods.</p>
     *
     * @return {@code null} to use the default {@link Handler}.
     */
    Handler getHandler();

    /**
     * Called by the system up to only once to notify that the system is about to invalidate
     * connection between the input method and the application.
     *
     * <p><strong>Editor authors</strong>: You can clear all the nested batch edit right now and
     * you no longer need to handle subsequent callbacks on this connection, including
     * {@link #beginBatchEdit()}}.  Note that although the system tries to call this method whenever
     * possible, there may be a chance that this method is not called in some exceptional
     * situations.</p>
     *
     * <p>Note: This does nothing when called from input methods.</p>
     */
    void closeConnection();

    /**
     * When this flag is used, the editor will be able to request read access to the content URI
     * contained in the {@link InputContentInfo} object.
     *
     * <p>Make sure that the content provider owning the Uri sets the
     * {@link android.R.styleable#AndroidManifestProvider_grantUriPermissions
     * grantUriPermissions} attribute in its manifest or included the
     * {@link android.R.styleable#AndroidManifestGrantUriPermission
     * &lt;grant-uri-permissions&gt;} tag. Otherwise {@link InputContentInfo#requestPermission()}
     * can fail.</p>
     *
     * <p>Although calling this API is allowed only for the IME that is currently selected, the
     * client is able to request a temporary read-only access even after the current IME is switched
     * to any other IME as long as the client keeps {@link InputContentInfo} object.</p>
     **/
    int INPUT_CONTENT_GRANT_READ_URI_PERMISSION =
            android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;  // 0x00000001

    /**
     * Called by the input method to commit content such as a PNG image to the editor.
     *
     * <p>In order to avoid a variety of compatibility issues, this focuses on a simple use case,
     * where editors and IMEs are expected to work cooperatively as follows:</p>
     * <ul>
     *     <li>Editor must keep {@link EditorInfo#contentMimeTypes} equal to {@code null} if it does
     *     not support this method at all.</li>
     *     <li>Editor can ignore this request when the MIME type specified in
     *     {@code inputContentInfo} does not match any of {@link EditorInfo#contentMimeTypes}.
     *     </li>
     *     <li>Editor can ignore the cursor position when inserting the provided content.</li>
     *     <li>Editor can return {@code true} asynchronously, even before it starts loading the
     *     content.</li>
     *     <li>Editor should provide a way to delete the content inserted by this method or to
     *     revert the effect caused by this method.</li>
     *     <li>IME should not call this method when there is any composing text, in case calling
     *     this method causes a focus change.</li>
     *     <li>IME should grant a permission for the editor to read the content. See
     *     {@link EditorInfo#packageName} about how to obtain the package name of the editor.</li>
     * </ul>
     *
     * @param inputContentInfo Content to be inserted.
     * @param flags {@link #INPUT_CONTENT_GRANT_READ_URI_PERMISSION} if the content provider
     * allows {@link android.R.styleable#AndroidManifestProvider_grantUriPermissions
     * grantUriPermissions} or {@code 0} if the application does not need to call
     * {@link InputContentInfo#requestPermission()}.
     * @param opts optional bundle data. This can be {@code null}.
     * @return {@code true} if this request is accepted by the application, whether the request
     * is already handled or still being handled in background, {@code false} otherwise.
     */
    boolean commitContent(@NonNull InputContentInfo inputContentInfo, int flags,
            @Nullable Bundle opts);

    /**
     * Called by the input method to tell a hint about the locales of text to be committed.
     *
     * <p>This is just a hint for editor authors (and the system) to choose better options when
     * they have to disambiguate languages, like editor authors can do for input methods with
     * {@link EditorInfo#hintLocales}.</p>
     *
     * <p>The language hint provided by this callback should have higher priority than
     * {@link InputMethodSubtype#getLanguageTag()}, which cannot be updated dynamically.</p>
     *
     * <p>Note that in general it is discouraged for input method to specify
     * {@link android.text.style.LocaleSpan} when inputting text, mainly because of application
     * compatibility concerns.</p>
     * <ul>
     *     <li>When an existing text that already has {@link android.text.style.LocaleSpan} is being
     *     modified by both the input method and application, there is no reliable and easy way to
     *     keep track of who modified {@link android.text.style.LocaleSpan}. For instance, if the
     *     text was updated by JavaScript, it it highly likely that span information is completely
     *     removed, while some input method attempts to preserve spans if possible.</li>
     *     <li>There is no clear semantics regarding whether {@link android.text.style.LocaleSpan}
     *     means a weak (ignorable) hint or a strong hint. This becomes more problematic when
     *     multiple {@link android.text.style.LocaleSpan} instances are specified to the same
     *     text region, especially when those spans are conflicting.</li>
     * </ul>
     * @param languageHint list of languages sorted by the priority and/or probability
     */
    default void reportLanguageHint(@NonNull LocaleList languageHint) {
        // Intentionally empty.
        //
        // We need to have *some* default implementation for the source compatibility.
        // See Bug 72127682 for details.
    }
}
