Skip to content
This repository has been archived by the owner on Nov 8, 2023. It is now read-only.

Commit

Permalink
Clarify the purpose of EditorInfo#hintLocales.
Browse files Browse the repository at this point in the history
During the initial attempt to support automatic language switching in
LatinIME, it turns out that the current EditorInfo#locales is difficult
to use and even confusing in some situations.  Based on that
experience, this CL changes as follows:

* Rename EditorInfo#locales to EditorInfo#hintLocales:
  This is mainly to avoid possible confusion when to set this.  We want
  to make it clear that having non-empty LocaleList there is a clear
  signal that the user would switch to certain languages regardless of
  the currently selected input method subtype.

* Make EditorInfo#hintLocales nullable:
  Previously marshaling EditorInfor causes NPE when
  EditorInfo#hintLocales is null.  This CL relaxes such a restriction.

* Introduce TextView#{set, get}ImeHintLocales():
  In the previous implementation [1], we just copied
  TextView#getTextLocales() into EditorInfo.  This is, however, does not
  work well because it is no more or less than the default value.  If
  LatinIME supports automatic language switching, having the default
  value in EditorInfo actually means that whenever you focus in a new
  text field, the keyboard language is reset to the default locale.
  In order to make this "hint" useful for IME developers, this "hint"
  should be specified only when the application developers are confident
  to do so.

  [1]: I738ffaaf07091d8b980f8bfc6e16227fcb85a96a
       0445fdf

Bug: 22859862
Change-Id: I0a730011874ea8d01e50624ed3f1ecd197d05f94
  • Loading branch information
yukawa committed Jan 21, 2016
1 parent 88f0430 commit d469f21
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 20 deletions.
4 changes: 3 additions & 1 deletion api/current.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43584,14 +43584,14 @@ package android.view.inputmethod {
field public android.os.Bundle extras;
field public int fieldId;
field public java.lang.String fieldName;
field public android.util.LocaleList hintLocales;
field public java.lang.CharSequence hintText;
field public int imeOptions;
field public int initialCapsMode;
field public int initialSelEnd;
field public int initialSelStart;
field public int inputType;
field public java.lang.CharSequence label;
field public android.util.LocaleList locales;
field public java.lang.String packageName;
field public java.lang.String privateImeOptions;
}
Expand Down Expand Up @@ -46838,6 +46838,7 @@ package android.widget {
method public int getHyphenationFrequency();
method public int getImeActionId();
method public java.lang.CharSequence getImeActionLabel();
method public android.util.LocaleList getImeHintLocales();
method public int getImeOptions();
method public boolean getIncludeFontPadding();
method public android.os.Bundle getInputExtras(boolean);
Expand Down Expand Up @@ -46944,6 +46945,7 @@ package android.widget {
method public void setHorizontallyScrolling(boolean);
method public void setHyphenationFrequency(int);
method public void setImeActionLabel(java.lang.CharSequence, int);
method public void setImeHintLocales(android.util.LocaleList);
method public void setImeOptions(int);
method public void setIncludeFontPadding(boolean);
method public void setInputExtras(int) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
Expand Down
4 changes: 3 additions & 1 deletion api/system-current.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45985,14 +45985,14 @@ package android.view.inputmethod {
field public android.os.Bundle extras;
field public int fieldId;
field public java.lang.String fieldName;
field public android.util.LocaleList hintLocales;
field public java.lang.CharSequence hintText;
field public int imeOptions;
field public int initialCapsMode;
field public int initialSelEnd;
field public int initialSelStart;
field public int inputType;
field public java.lang.CharSequence label;
field public android.util.LocaleList locales;
field public java.lang.String packageName;
field public java.lang.String privateImeOptions;
}
Expand Down Expand Up @@ -49565,6 +49565,7 @@ package android.widget {
method public int getHyphenationFrequency();
method public int getImeActionId();
method public java.lang.CharSequence getImeActionLabel();
method public android.util.LocaleList getImeHintLocales();
method public int getImeOptions();
method public boolean getIncludeFontPadding();
method public android.os.Bundle getInputExtras(boolean);
Expand Down Expand Up @@ -49671,6 +49672,7 @@ package android.widget {
method public void setHorizontallyScrolling(boolean);
method public void setHyphenationFrequency(int);
method public void setImeActionLabel(java.lang.CharSequence, int);
method public void setImeHintLocales(android.util.LocaleList);
method public void setImeOptions(int);
method public void setIncludeFontPadding(boolean);
method public void setInputExtras(int) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
Expand Down
4 changes: 3 additions & 1 deletion api/test-current.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43600,14 +43600,14 @@ package android.view.inputmethod {
field public android.os.Bundle extras;
field public int fieldId;
field public java.lang.String fieldName;
field public android.util.LocaleList hintLocales;
field public java.lang.CharSequence hintText;
field public int imeOptions;
field public int initialCapsMode;
field public int initialSelEnd;
field public int initialSelStart;
field public int inputType;
field public java.lang.CharSequence label;
field public android.util.LocaleList locales;
field public java.lang.String packageName;
field public java.lang.String privateImeOptions;
}
Expand Down Expand Up @@ -46854,6 +46854,7 @@ package android.widget {
method public int getHyphenationFrequency();
method public int getImeActionId();
method public java.lang.CharSequence getImeActionLabel();
method public android.util.LocaleList getImeHintLocales();
method public int getImeOptions();
method public boolean getIncludeFontPadding();
method public android.os.Bundle getInputExtras(boolean);
Expand Down Expand Up @@ -46960,6 +46961,7 @@ package android.widget {
method public void setHorizontallyScrolling(boolean);
method public void setHyphenationFrequency(int);
method public void setImeActionLabel(java.lang.CharSequence, int);
method public void setImeHintLocales(android.util.LocaleList);
method public void setImeOptions(int);
method public void setIncludeFontPadding(boolean);
method public void setInputExtras(int) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
Expand Down
40 changes: 26 additions & 14 deletions core/java/android/view/inputmethod/EditorInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package android.view.inputmethod;

import android.annotation.Nullable;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
Expand Down Expand Up @@ -341,20 +342,26 @@ public class EditorInfo implements InputType, Parcelable {
public Bundle extras;

/**
* Additional context information that tells what languages are expected by the user.
* List of the languages that the user is supposed to switch to no matter what input method
* subtype is currently used. This special "hint" can be used mainly for, but not limited to,
* multilingual users who want IMEs to switch language context automatically.
*
* <p><strong>IME authors:</strong> Possible use cases for IME developers would be:</p>
* <ul>
* <li>Automatically switching keyboard layout.</li>
* <li>Changing language model for better typing experience.</li>
* </ul>
* <p>{@code null} means that no special language "hint" is needed.</p>
*
* <p><strong>Editor authors:</strong> Providing this context information can help IMEs to
* improve text input experience. For example, chat applications can remember what language is
* used in the last conversation for each chat session, and put the last used language at the
* top of {@link #locales}.</p>
* <p><strong>Editor authors:</strong> Specify this only when you are confident that the user
* will switch to certain languages in this context no matter what input method subtype is
* currently selected. Otherwise, keep this {@code null}. Explicit user actions and/or
* preferences would be good signals to specify this special "hint", For example, a chat
* application may be able to put the last used language at the top of {@link #hintLocales}
* based on whom the user is going to talk, by remembering what language is used in the last
* conversation. Do not specify {@link android.widget.TextView#getTextLocales()} only because
* it is used for text rendering.</p>
*
* @see android.widget.TextView#setImeHintLocales(LocaleList)
* @see android.widget.TextView#getImeHintLocales()
*/
public LocaleList locales = LocaleList.getEmptyLocaleList();
@Nullable
public LocaleList hintLocales = null;

/**
* Ensure that the data in this EditorInfo is compatible with an application
Expand Down Expand Up @@ -410,7 +417,7 @@ public void dump(Printer pw, String prefix) {
+ " fieldId=" + fieldId
+ " fieldName=" + fieldName);
pw.println(prefix + "extras=" + extras);
pw.println(prefix + "locales=" + locales);
pw.println(prefix + "hintLocales=" + hintLocales);
}

/**
Expand All @@ -434,7 +441,11 @@ public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(fieldId);
dest.writeString(fieldName);
dest.writeBundle(extras);
locales.writeToParcel(dest, flags);
if (hintLocales != null) {
hintLocales.writeToParcel(dest, flags);
} else {
LocaleList.getEmptyLocaleList().writeToParcel(dest, flags);
}
}

/**
Expand All @@ -458,7 +469,8 @@ public EditorInfo createFromParcel(Parcel source) {
res.fieldId = source.readInt();
res.fieldName = source.readString();
res.extras = source.readBundle();
res.locales = LocaleList.CREATOR.createFromParcel(source);
LocaleList hintLocales = LocaleList.CREATOR.createFromParcel(source);
res.hintLocales = hintLocales.isEmpty() ? null : hintLocales;
return res;
}

Expand Down
2 changes: 2 additions & 0 deletions core/java/android/widget/Editor.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
import android.text.style.TextAppearanceSpan;
import android.text.style.URLSpan;
import android.util.DisplayMetrics;
import android.util.LocaleList;
import android.util.Log;
import android.util.SparseArray;
import android.view.ActionMode;
Expand Down Expand Up @@ -5299,6 +5300,7 @@ static class InputContentType {
Bundle extras;
OnEditorActionListener onEditorActionListener;
boolean enterDown;
LocaleList imeHintLocales;
}

static class InputMethodState {
Expand Down
34 changes: 31 additions & 3 deletions core/java/android/widget/TextView.java
Original file line number Diff line number Diff line change
Expand Up @@ -4991,6 +4991,35 @@ public Bundle getInputExtras(boolean create) {
return mEditor.mInputContentType.extras;
}

/**
* Change "hint" locales associated with the text view, which will be reported to an IME with
* {@link EditorInfo#hintLocales} when it has focus.
*
* <p><strong>Note:</strong> If you want new "hint" to take effect immediately you need to
* call {@link InputMethodManager#restartInput(View)}.</p>
* @param hintLocales List of the languages that the user is supposed to switch to no matter
* what input method subtype is currently used. Set {@code null} to clear the current "hint".
* @see #getImeHIntLocales()
* @see android.view.inputmethod.EditorInfo#hintLocales
*/
public void setImeHintLocales(@Nullable LocaleList hintLocales) {
createEditorIfNeeded();
mEditor.createInputContentTypeIfNeeded();
mEditor.mInputContentType.imeHintLocales = hintLocales;
}

/**
* @return The current languages list "hint". {@code null} when no "hint" is available.
* @see #setImeHintLocales(LocaleList)
* @see android.view.inputmethod.EditorInfo#hintLocales
*/
@Nullable
public LocaleList getImeHintLocales() {
if (mEditor == null) { return null; }
if (mEditor.mInputContentType == null) { return null; }
return mEditor.mInputContentType.imeHintLocales;
}

/**
* Returns the error message that was set to be displayed with
* {@link #setError}, or <code>null</code> if no error was set
Expand Down Expand Up @@ -6411,8 +6440,10 @@ public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
outAttrs.actionLabel = mEditor.mInputContentType.imeActionLabel;
outAttrs.actionId = mEditor.mInputContentType.imeActionId;
outAttrs.extras = mEditor.mInputContentType.extras;
outAttrs.hintLocales = mEditor.mInputContentType.imeHintLocales;
} else {
outAttrs.imeOptions = EditorInfo.IME_NULL;
outAttrs.hintLocales = null;
}
if (focusSearch(FOCUS_DOWN) != null) {
outAttrs.imeOptions |= EditorInfo.IME_FLAG_NAVIGATE_NEXT;
Expand Down Expand Up @@ -6440,9 +6471,6 @@ public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_ENTER_ACTION;
}
outAttrs.hintText = mHint;
// LocaleList is designed to be immutable. This is theoretically equivalent to copy
// the snapshot of the current text locales.
outAttrs.locales = getTextLocales();
if (mText instanceof Editable) {
InputConnection ic = new EditableInputConnection(this);
outAttrs.initialSelStart = getSelectionStart();
Expand Down

0 comments on commit d469f21

Please sign in to comment.