diff options
author | Jean Chalard <jchalard@google.com> | 2013-05-30 19:47:41 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2013-05-30 19:47:41 -0700 |
commit | 44baed2dc31d29c48f5d49577c109ca3903ad915 (patch) | |
tree | 148693d4adcdbea016efb37877cd3d17aa16e36d /core | |
parent | 6474d8407cb1551608fc403861e11cf514f8558e (diff) | |
parent | af9e5e5f618448f77f74bb36e0adbe88cb2ae156 (diff) | |
download | frameworks_base-44baed2dc31d29c48f5d49577c109ca3903ad915.zip frameworks_base-44baed2dc31d29c48f5d49577c109ca3903ad915.tar.gz frameworks_base-44baed2dc31d29c48f5d49577c109ca3903ad915.tar.bz2 |
am af9e5e5f: Merge "Improve the documentation for InputConnection." into jb-mr2-dev
* commit 'af9e5e5f618448f77f74bb36e0adbe88cb2ae156':
Improve the documentation for InputConnection.
Diffstat (limited to 'core')
4 files changed, 600 insertions, 202 deletions
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java index 7ec5398..d6b973e 100644 --- a/core/java/android/view/inputmethod/BaseInputConnection.java +++ b/core/java/android/view/inputmethod/BaseInputConnection.java @@ -42,7 +42,8 @@ class ComposingText implements NoCopySpan { * Base class for implementors of the InputConnection interface, taking care * of most of the common behavior for providing a connection to an Editable. * Implementors of this class will want to be sure to implement - * {@link #getEditable} to provide access to their own editable object. + * {@link #getEditable} to provide access to their own editable object, and + * to refer to the documentation in {@link InputConnection}. */ public class BaseInputConnection implements InputConnection { private static final boolean DEBUG = false; diff --git a/core/java/android/view/inputmethod/CompletionInfo.java b/core/java/android/view/inputmethod/CompletionInfo.java index 3591cb1..70b8059 100644 --- a/core/java/android/view/inputmethod/CompletionInfo.java +++ b/core/java/android/view/inputmethod/CompletionInfo.java @@ -1,12 +1,12 @@ /* * 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 @@ -23,6 +23,30 @@ import android.text.TextUtils; /** * Information about a single text completion that an editor has reported to * an input method. + * + * <p>This class encapsulates a completion offered by an application + * that wants it to be presented to the user by the IME. Usually, apps + * present their completions directly in a scrolling list for example + * (UI developers will usually use or extend + * {@see android.widget.AutoCompleteTextView} to implement this). + * However, in some cases, the editor may not be visible, as in the + * case in extract mode where the IME has taken over the full + * screen. In this case, the editor can choose to send their + * completions to the IME for display. + * + * <p>Most applications who want to send completions to an IME should use + * {@link android.widget.AutoCompleteTextView} as this class makes this + * process easy. In this case, the application would not have to deal directly + * with this class. + * + * <p>An application who implements its own editor and wants direct control + * over this would create an array of CompletionInfo objects, and send it to the IME using + * {@link InputMethodManager#displayCompletions(View, CompletionInfo[])}. + * The IME would present the completions however they see fit, and + * call back to the editor through + * {@link InputConnection#commitCompletion(CompletionInfo)}. + * The application can then pick up the commit event by overriding + * {@link android.widget.TextView#onCommitCompletion(CompletionInfo)}. */ public final class CompletionInfo implements Parcelable { private final long mId; @@ -32,6 +56,12 @@ public final class CompletionInfo implements Parcelable { /** * Create a simple completion with just text, no label. + * + * @param id An id that get passed as is (to the editor's discretion) + * @param index An index that get passed as is. Typically this is the + * index in the list of completions inside the editor. + * @param text The text that should be inserted into the editor when + * this completion is chosen. */ public CompletionInfo(long id, int index, CharSequence text) { mId = id; @@ -41,7 +71,18 @@ public final class CompletionInfo implements Parcelable { } /** - * Create a full completion with both text and label. + * Create a full completion with both text and label. The text is + * what will get inserted into the editor, while the label is what + * the IME should display. If they are the same, use the version + * of the constructor without a `label' argument. + * + * @param id An id that get passed as is (to the editor's discretion) + * @param index An index that get passed as is. Typically this is the + * index in the list of completions inside the editor. + * @param text The text that should be inserted into the editor when + * this completion is chosen. + * @param label The text that the IME should be showing among the + * completions list. */ public CompletionInfo(long id, int index, CharSequence text, CharSequence label) { mId = id; @@ -56,7 +97,7 @@ public final class CompletionInfo implements Parcelable { mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); } - + /** * Return the abstract identifier for this completion, typically * corresponding to the id associated with it in the original adapter. @@ -64,7 +105,7 @@ public final class CompletionInfo implements Parcelable { public long getId() { return mId; } - + /** * Return the original position of this completion, typically * corresponding to its position in the original adapter. @@ -72,7 +113,7 @@ public final class CompletionInfo implements Parcelable { public int getPosition() { return mPosition; } - + /** * Return the actual text associated with this completion. This is the * real text that will be inserted into the editor if the user selects it. @@ -80,7 +121,7 @@ public final class CompletionInfo implements Parcelable { public CharSequence getText() { return mText; } - + /** * Return the user-visible label for the completion, or null if the plain * text should be shown. If non-null, this will be what the user sees as @@ -89,7 +130,7 @@ public final class CompletionInfo implements Parcelable { public CharSequence getLabel() { return mLabel; } - + @Override public String toString() { return "CompletionInfo{#" + mPosition + " \"" + mText diff --git a/core/java/android/view/inputmethod/ExtractedText.java b/core/java/android/view/inputmethod/ExtractedText.java index 3b2508c..0c5d9e9 100644 --- a/core/java/android/view/inputmethod/ExtractedText.java +++ b/core/java/android/view/inputmethod/ExtractedText.java @@ -22,6 +22,9 @@ import android.text.TextUtils; /** * Information about text that has been extracted for use by an input method. + * + * This contains information about a portion of the currently edited text, + * that the IME should display into its own interface while in extracted mode. */ public class ExtractedText implements Parcelable { /** @@ -33,7 +36,7 @@ public class ExtractedText implements Parcelable { * The offset in the overall text at which the extracted text starts. */ public int startOffset; - + /** * If the content is a report of a partial text change, this is the * offset where the change starts and it runs until @@ -41,7 +44,7 @@ public class ExtractedText implements Parcelable { * field is -1. */ public int partialStartOffset; - + /** * If the content is a report of a partial text change, this is the offset * where the change ends. Note that the actual text may be larger or @@ -49,40 +52,43 @@ public class ExtractedText implements Parcelable { * meaning a reduction or increase, respectively, in the total text. */ public int partialEndOffset; - + /** * The offset where the selection currently starts within the extracted * text. The real selection start position is at * <var>startOffset</var>+<var>selectionStart</var>. */ public int selectionStart; - + /** * The offset where the selection currently ends within the extracted * text. The real selection end position is at * <var>startOffset</var>+<var>selectionEnd</var>. */ public int selectionEnd; - + /** * Bit for {@link #flags}: set if the text being edited can only be on * a single line. */ public static final int FLAG_SINGLE_LINE = 0x0001; - + /** * Bit for {@link #flags}: set if the editor is currently in selection mode. + * + * This happens when a hardware keyboard with latched keys is attached and + * the shift key is currently latched. */ public static final int FLAG_SELECTING = 0x0002; - + /** * Additional bit flags of information about the edited text. */ public int flags; - + /** * Used to package this object into a {@link Parcel}. - * + * * @param dest The {@link Parcel} to be written. * @param flags The flags used for parceling. */ @@ -99,7 +105,8 @@ public class ExtractedText implements Parcelable { /** * Used to make this class parcelable. */ - public static final Parcelable.Creator<ExtractedText> CREATOR = new Parcelable.Creator<ExtractedText>() { + public static final Parcelable.Creator<ExtractedText> CREATOR + = new Parcelable.Creator<ExtractedText>() { public ExtractedText createFromParcel(Parcel source) { ExtractedText res = new ExtractedText(); res.text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java index 76c6d19..e7d84c2 100644 --- a/core/java/android/view/inputmethod/InputConnection.java +++ b/core/java/android/view/inputmethod/InputConnection.java @@ -1,12 +1,12 @@ /* * 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 @@ -22,60 +22,167 @@ 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>Applications should never directly implement this interface, but instead - * subclass from {@link BaseInputConnection}. This will ensure that the - * application does not break when new methods are added to the interface. + * {@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>Applications should never directly implement this interface, but + * instead subclass from {@link BaseInputConnection}. This will ensure + * that the application does not break when new methods are added to + * the interface.</p> + * + * <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 edition 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, you will receive only the raw text. If - * set, you may receive a complex CharSequence of both text and style - * spans. + * {@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. + * 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 client is taking too long to - * respond with the text (it is given a couple seconds to return). - * In either case, a null is returned. - * + * 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. + * * @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 Returns the text before the cursor position; the length of the + * 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, a null is returned. - * + * 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.</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 Returns the text after the cursor position; the length of the + * 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); @@ -83,139 +190,287 @@ public interface InputConnection { /** * 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, a null is returned. + * <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 Returns the text that is currently selected, if any, or null if + * 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. */ 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, a 0 is returned. - * + * 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 + * {@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 Returns the caps mode flags that are in effect. + * @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, a null is returned. - * + * 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 Returns an ExtractedText object describing the state of the - * text view and containing the extracted text itself. + + * @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 composing text. Before and after refer - * to the order of the characters in the string, not to their visual representation. - * + * 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 to be deleted before the * current cursor position. * @param afterLength The number of characters to be deleted after the * current cursor position. - * - * @return Returns true on success, false if the input connection is no longer + * @return true on success, false if the input connection is no longer * valid. */ public boolean deleteSurroundingText(int beforeLength, int afterLength); /** - * Set composing text around the current cursor position with the given text, - * and set the new cursor position. Any composing text set previously will - * be removed automatically. - * + * Set composing text around the current cursor position 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. 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 + * 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 + * 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 + * 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 Returns true on success, false if the input connection is no longer + * @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. Any composing text set - * previously will be removed automatically. The default style for composing - * text is used. + * 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 Returns true on success, false if the input connection is no longer + * @return true on success, false if the input connection is no longer * valid. */ 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. + * 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. - * Any composing text set previously will be removed - * automatically. - * - * @param text The committed text. - * @param newCursorPosition The new cursor position around the text. If + * + * <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}. + * 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 committed text. This may include styles. + * @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 + * 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 + * 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 Returns true on success, false if the input connection is no longer + * @return true on success, false if the input connection is no longer * valid. */ public boolean commitText(CharSequence text, int newCursorPosition); @@ -223,49 +478,102 @@ public interface InputConnection { /** * Commit a completion the user has selected from the possible ones * previously reported to {@link InputMethodSession#displayCompletions - * InputMethodSession.displayCompletions()}. This will result in the - * same behavior as if the user had selected the completion from the - * actual UI. - * + * 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 Returns true on success, false if the input connection is no longer + * @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. + * Commit a correction automatically performed on the raw user's input. A + * typical example would be to correct typos using a dictionary. * - * @param correctionInfo Detailed information about the correction. + * <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> * - * @return True on success, false if the input connection is no longer valid. + * @param correctionInfo Detailed information about the correction. + * @return true on success, false if the input connection is no longer valid. */ 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. - * @return Returns true on success, false if the input connection is no longer + * 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 Returns true on success, false if the input connection is no longer + * @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: + * 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}, @@ -273,50 +581,82 @@ public interface InputConnection { * 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. + * 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}. + * 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; 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> - * 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>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. + * 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 Returns true on success, false if the input connection is no longer + * @return true on success, false if the input connection is no longer * valid. - * + * * @see KeyEvent * @see KeyCharacterMap#NUMERIC * @see KeyCharacterMap#PREDICTIVE @@ -325,37 +665,46 @@ public interface InputConnection { public boolean sendKeyEvent(KeyEvent event); /** - * Clear the given meta key pressed states in the given input connection. - * + * 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 Returns true on success, false if the input connection is no longer + * @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}. + * 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> + * 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 Returns true if the command was sent (whether or not the + * @return true if the command was sent (whether or not the * associated editor understood it), false if the input connection is no longer * valid. */ |