/*
 * Copyright (C) 2007-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;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Bundle;
import android.os.Handler;
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.
     */
    static final 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.
     */
    public static final 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>.
     */
    public 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>.
     */
    public 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.
     */
    public 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}.
     */
    public 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.
     */
    public 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.
     */
    public 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.
     */
    public 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.
     */
    public 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.
     */
    public 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.
     */
    public 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.
     */
    public 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.
     */
    public 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.
     */
    public 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.
     */
    public 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.
     */
    public 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}
     */
    public 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.
     */
    public 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.
     */
    public 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
     */
    public 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.
     */
    public boolean clearMetaKeyStates(int states);

    /**
     * Called by the IME to tell the client when it switches between
     * fullscreen and normal modes. This will normally be called for
     * you by the standard implementation of
     * {@link android.inputmethodservice.InputMethodService}.
     *
     * @return true on success, false if the input connection is no longer
     * valid.
     */
    public 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.
     */
    public 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}.
     */
    public static final 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>
     */
    public static final 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.
     */
    public 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}.
     */
    public 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>
     */
    public 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>
     **/
    public static int INPUT_CONTENT_GRANT_READ_URI_PERMISSION =
            android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;  // 0x00000001

    /**
     * Called by the input method to commit a content such as PNG image to the editor.
     *
     * <p>In order to avoid variety of compatibility issues, this focuses on a simple use case,
     * where we expect editors and IMEs work cooperatively as follows:</p>
     * <ul>
     *     <li>Editor must keep {@link EditorInfo#contentMimeTypes} to be {@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 to any of {@link EditorInfo#contentMimeTypes}.
     *     </li>
     *     <li>Editor can ignore the cursor position when inserting the provided context.</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 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 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 {@code 0} or {@link #INPUT_CONTENT_GRANT_READ_URI_PERMISSION}.
     * @param opts optional bundle data. This can be {@code null}.
     * @return {@code true} if this request is accepted by the application, no matter if the request
     * is already handled or still being handled in background.
     */
    public boolean commitContent(@NonNull InputContentInfo inputContentInfo, int flags,
            @Nullable Bundle opts);
}
