diff options
7 files changed, 80 insertions, 0 deletions
diff --git a/api/current.txt b/api/current.txt index 8d26717af988..c335d419f760 100644 --- a/api/current.txt +++ b/api/current.txt @@ -49191,6 +49191,7 @@ package android.view.inputmethod { method public abstract boolean performEditorAction(int); method public abstract boolean performPrivateCommand(java.lang.String, android.os.Bundle); method public abstract boolean reportFullscreenMode(boolean); + method public default void reportLanguageHint(android.os.LocaleList); method public abstract boolean requestCursorUpdates(int); method public abstract boolean sendKeyEvent(android.view.KeyEvent); method public abstract boolean setComposingRegion(int, int); diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java index e5545405728d..eba91763acf1 100644 --- a/core/java/android/view/inputmethod/InputConnection.java +++ b/core/java/android/view/inputmethod/InputConnection.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.inputmethodservice.InputMethodService; import android.os.Bundle; import android.os.Handler; +import android.os.LocaleList; import android.view.KeyCharacterMap; import android.view.KeyEvent; @@ -898,4 +899,37 @@ public interface InputConnection { */ boolean commitContent(@NonNull InputContentInfo inputContentInfo, int flags, @Nullable Bundle opts); + + /** + * Called by the input method to tell a hint about the locales of text to be committed. + * + * <p>This is just a hint for editor authors (and the system) to choose better options when + * they have to disambiguate languages, like editor authors can do for input methods with + * {@link EditorInfo#hintLocales}.</p> + * + * <p>The language hint provided by this callback should have higher priority than + * {@link InputMethodSubtype#getLanguageTag()}, which cannot be updated dynamically.</p> + * + * <p>Note that in general it is discouraged for input method to specify + * {@link android.text.style.LocaleSpan} when inputting text, mainly because of application + * compatibility concerns.</p> + * <ul> + * <li>When an existing text that already has {@link android.text.style.LocaleSpan} is being + * modified by both the input method and application, there is no reliable and easy way to + * keep track of who modified {@link android.text.style.LocaleSpan}. For instance, if the + * text was updated by JavaScript, it it highly likely that span information is completely + * removed, while some input method attempts to preserve spans if possible.</li> + * <li>There is no clear semantics regarding whether {@link android.text.style.LocaleSpan} + * means a weak (ignorable) hint or a strong hint. This becomes more problematic when + * multiple {@link android.text.style.LocaleSpan} instances are specified to the same + * text region, especially when those spans are conflicting.</li> + * </ul> + * @param languageHint list of languages sorted by the priority and/or probability + */ + default void reportLanguageHint(@NonNull LocaleList languageHint) { + // Intentionally empty. + // + // We need to have *some* default implementation for the source compatibility. + // See Bug 72127682 for details. + } } diff --git a/core/java/android/view/inputmethod/InputConnectionWrapper.java b/core/java/android/view/inputmethod/InputConnectionWrapper.java index f671e22b4922..cbe6856bba41 100644 --- a/core/java/android/view/inputmethod/InputConnectionWrapper.java +++ b/core/java/android/view/inputmethod/InputConnectionWrapper.java @@ -16,8 +16,10 @@ package android.view.inputmethod; +import android.annotation.NonNull; import android.os.Bundle; import android.os.Handler; +import android.os.LocaleList; import android.view.KeyEvent; /** @@ -303,4 +305,13 @@ public class InputConnectionWrapper implements InputConnection { public boolean commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts) { return mTarget.commitContent(inputContentInfo, flags, opts); } + + /** + * {@inheritDoc} + * @throws NullPointerException if the target is {@code null}. + */ + @Override + public void reportLanguageHint(@NonNull LocaleList languageHint) { + mTarget.reportLanguageHint(languageHint); + } } diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 6bee58f96f8a..7e52e8fac4fe 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -30,6 +30,7 @@ import android.graphics.drawable.TransitionDrawable; import android.os.Bundle; import android.os.Debug; import android.os.Handler; +import android.os.LocaleList; import android.os.Parcel; import android.os.Parcelable; import android.os.StrictMode; @@ -6026,6 +6027,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te public boolean commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts) { return getTarget().commitContent(inputContentInfo, flags, opts); } + + @Override + public void reportLanguageHint(@NonNull LocaleList languageHint) { + getTarget().reportLanguageHint(languageHint); + } } /** diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java index 28291aefd036..e08caa8e199d 100644 --- a/core/java/com/android/internal/view/IInputConnectionWrapper.java +++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java @@ -23,6 +23,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Bundle; import android.os.Handler; +import android.os.LocaleList; import android.os.Looper; import android.os.Message; import android.os.RemoteException; @@ -64,6 +65,7 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub { private static final int DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO = 140; private static final int DO_CLOSE_CONNECTION = 150; private static final int DO_COMMIT_CONTENT = 160; + private static final int DO_REPORT_LANGUAGE_HINT = 170; @GuardedBy("mLock") @Nullable @@ -217,6 +219,10 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub { callback)); } + public void reportLanguageHint(@NonNull LocaleList languageHint) { + dispatchMessage(obtainMessageO(DO_REPORT_LANGUAGE_HINT, languageHint)); + } + void dispatchMessage(Message msg) { // If we are calling this from the main thread, then we can call // right through. Otherwise, we need to send the message to the @@ -577,6 +583,16 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub { } return; } + case DO_REPORT_LANGUAGE_HINT: { + final LocaleList languageHint = (LocaleList) msg.obj; + final InputConnection ic = getInputConnection(); + if (ic == null || !isActive()) { + Log.w(TAG, "reportLanguageHint on inactive InputConnection"); + return; + } + ic.reportLanguageHint(languageHint); + return; + } } Log.w(TAG, "Unhandled message code: " + msg.what); } diff --git a/core/java/com/android/internal/view/IInputContext.aidl b/core/java/com/android/internal/view/IInputContext.aidl index c22799179b72..e69a87ffc1dd 100644 --- a/core/java/com/android/internal/view/IInputContext.aidl +++ b/core/java/com/android/internal/view/IInputContext.aidl @@ -17,6 +17,7 @@ package com.android.internal.view; import android.os.Bundle; +import android.os.LocaleList; import android.view.KeyEvent; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.CorrectionInfo; @@ -78,4 +79,6 @@ import com.android.internal.view.IInputContextCallback; void commitContent(in InputContentInfo inputContentInfo, int flags, in Bundle opts, int sec, IInputContextCallback callback); + + void reportLanguageHint(in LocaleList languageHint); } diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java index 5b65bbe1e90e..34be598dd615 100644 --- a/core/java/com/android/internal/view/InputConnectionWrapper.java +++ b/core/java/com/android/internal/view/InputConnectionWrapper.java @@ -22,6 +22,7 @@ import android.annotation.NonNull; import android.inputmethodservice.AbstractInputMethodService; import android.os.Bundle; import android.os.Handler; +import android.os.LocaleList; import android.os.RemoteException; import android.os.SystemClock; import android.util.Log; @@ -620,6 +621,14 @@ public class InputConnectionWrapper implements InputConnection { } @AnyThread + public void reportLanguageHint(@NonNull LocaleList languageHint) { + try { + mIInputContext.reportLanguageHint(languageHint); + } catch (RemoteException e) { + } + } + + @AnyThread private boolean isMethodMissing(@MissingMethodFlags final int methodFlag) { return (mMissingMethods & methodFlag) == methodFlag; } |