Introduce SpellCheckerSessionParams.

SpellCheckerSessionParams encapsulates parameters for
TextServicesManager#newSpellCheckerSession().

Bug: 179804789
Test: atest CtsInputMethodTestCases:SpellCheckerTest
Change-Id: I724aaad15b0a4bd38f6a24585c4c45cfeee5b499
This commit is contained in:
Kohsuke Yatoh
2021-04-14 16:26:33 -07:00
parent 14d6cdca25
commit 94635fcb89
4 changed files with 212 additions and 42 deletions

View File

@@ -52715,6 +52715,22 @@ package android.view.textservice {
method public void onGetSuggestions(android.view.textservice.SuggestionsInfo[]);
}
public static class SpellCheckerSession.SpellCheckerSessionParams {
method @NonNull public android.os.Bundle getExtras();
method @Nullable public java.util.Locale getLocale();
method public int getSupportedAttributes();
method public boolean shouldReferToSpellCheckerLanguageSettings();
}
public static final class SpellCheckerSession.SpellCheckerSessionParams.Builder {
ctor public SpellCheckerSession.SpellCheckerSessionParams.Builder();
method @NonNull public android.view.textservice.SpellCheckerSession.SpellCheckerSessionParams build();
method @NonNull public android.view.textservice.SpellCheckerSession.SpellCheckerSessionParams.Builder setExtras(@NonNull android.os.Bundle);
method @NonNull public android.view.textservice.SpellCheckerSession.SpellCheckerSessionParams.Builder setLocale(@Nullable java.util.Locale);
method @NonNull public android.view.textservice.SpellCheckerSession.SpellCheckerSessionParams.Builder setShouldReferToSpellCheckerLanguageSettings(boolean);
method @NonNull public android.view.textservice.SpellCheckerSession.SpellCheckerSessionParams.Builder setSupportedAttributes(int);
}
public final class SpellCheckerSubtype implements android.os.Parcelable {
ctor @Deprecated public SpellCheckerSubtype(int, String, String);
method public boolean containsExtraValueKey(String);
@@ -52768,7 +52784,7 @@ package android.view.textservice {
method @NonNull public java.util.List<android.view.textservice.SpellCheckerInfo> getEnabledSpellCheckerInfos();
method public boolean isSpellCheckerEnabled();
method @Nullable public android.view.textservice.SpellCheckerSession newSpellCheckerSession(@Nullable android.os.Bundle, @Nullable java.util.Locale, @NonNull android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener, boolean);
method @Nullable public android.view.textservice.SpellCheckerSession newSpellCheckerSession(@Nullable java.util.Locale, boolean, int, @Nullable android.os.Bundle, @NonNull java.util.concurrent.Executor, @NonNull android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener);
method @Nullable public android.view.textservice.SpellCheckerSession newSpellCheckerSession(@NonNull android.view.textservice.SpellCheckerSession.SpellCheckerSessionParams, @NonNull java.util.concurrent.Executor, @NonNull android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener);
}
}

View File

@@ -17,10 +17,13 @@
package android.view.textservice;
import android.annotation.BinderThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
@@ -37,6 +40,7 @@ import com.android.internal.textservice.ITextServicesSessionListener;
import dalvik.system.CloseGuard;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Queue;
import java.util.concurrent.Executor;
@@ -525,6 +529,161 @@ public class SpellCheckerSession {
}
}
/** Parameters used to create a {@link SpellCheckerSession}. */
public static class SpellCheckerSessionParams {
@Nullable
private final Locale mLocale;
private final boolean mShouldReferToSpellCheckerLanguageSettings;
private final @SuggestionsInfo.ResultAttrs int mSupportedAttributes;
private final Bundle mExtras;
private SpellCheckerSessionParams(Locale locale,
boolean referToSpellCheckerLanguageSettings, int supportedAttributes,
Bundle extras) {
mLocale = locale;
mShouldReferToSpellCheckerLanguageSettings = referToSpellCheckerLanguageSettings;
mSupportedAttributes = supportedAttributes;
mExtras = extras;
}
/**
* Returns the locale in which the spell checker should operate.
*
* @see android.service.textservice.SpellCheckerService.Session#getLocale()
*/
@SuppressLint("UseIcu")
@Nullable
public Locale getLocale() {
return mLocale;
}
/**
* Returns true if the user's spell checker language settings should be used to determine
* the spell checker locale.
*/
public boolean shouldReferToSpellCheckerLanguageSettings() {
return mShouldReferToSpellCheckerLanguageSettings;
}
/**
* Returns a bitmask of {@link SuggestionsInfo} attributes that the spell checker can set
* in {@link SuggestionsInfo} it returns.
*
* @see android.service.textservice.SpellCheckerService.Session#getSupportedAttributes()
*/
public @SuggestionsInfo.ResultAttrs int getSupportedAttributes() {
return mSupportedAttributes;
}
/**
* Returns a bundle containing extra parameters for the spell checker.
*
* <p>This bundle can be used to pass implementation-specific parameters to the
* {@link android.service.textservice.SpellCheckerService} implementation.
*
* @see android.service.textservice.SpellCheckerService.Session#getBundle()
*/
@NonNull
public Bundle getExtras() {
return mExtras;
}
/** Builder of {@link SpellCheckerSessionParams}. */
public static final class Builder {
@Nullable
private Locale mLocale;
private boolean mShouldReferToSpellCheckerLanguageSettings = false;
private @SuggestionsInfo.ResultAttrs int mSupportedAttributes = 0;
private Bundle mExtras = Bundle.EMPTY;
/** Constructs a {@code Builder}. */
public Builder() {
}
/**
* Returns constructed {@link SpellCheckerSession} instance.
*
* <p>Before calling this method, either {@link #setLocale(Locale)} should be called
* with a non-null locale or
* {@link #setShouldReferToSpellCheckerLanguageSettings(boolean)} should be called with
* {@code true}.
*/
@NonNull
public SpellCheckerSessionParams build() {
if (mLocale == null && !mShouldReferToSpellCheckerLanguageSettings) {
throw new IllegalArgumentException("mLocale should not be null if "
+ " mShouldReferToSpellCheckerLanguageSettings is false.");
}
return new SpellCheckerSessionParams(mLocale,
mShouldReferToSpellCheckerLanguageSettings, mSupportedAttributes, mExtras);
}
/**
* Sets the locale in which the spell checker should operate.
*
* @see android.service.textservice.SpellCheckerService.Session#getLocale()
*/
@NonNull
public Builder setLocale(@SuppressLint("UseIcu") @Nullable Locale locale) {
mLocale = locale;
return this;
}
/**
* Sets whether or not the user's spell checker language settings should be used to
* determine spell checker locale.
*
* <p>If {@code shouldReferToSpellCheckerLanguageSettings} is true, the exact way of
* determining spell checker locale differs based on {@code locale} specified in
* {@link #setLocale(Locale)}.
* If {@code shouldReferToSpellCheckerLanguageSettings} is true and {@code locale} is
* null, the locale specified in Settings will be used. If
* {@code shouldReferToSpellCheckerLanguageSettings} is true and {@code locale} is not
* null, {@link SpellCheckerSession} can be created only when the locale specified in
* Settings is the same as {@code locale}. Exceptionally, if
* {@code shouldReferToSpellCheckerLanguageSettings} is true and {@code locale} is
* language only (e.g. "en"), the specified locale in Settings (e.g. "en_US") will be
* used.
*
* @see #setLocale(Locale)
*/
@NonNull
public Builder setShouldReferToSpellCheckerLanguageSettings(
boolean shouldReferToSpellCheckerLanguageSettings) {
mShouldReferToSpellCheckerLanguageSettings =
shouldReferToSpellCheckerLanguageSettings;
return this;
}
/**
* Sets a bitmask of {@link SuggestionsInfo} attributes that the spell checker can set
* in {@link SuggestionsInfo} it returns.
*
* @see android.service.textservice.SpellCheckerService.Session#getSupportedAttributes()
*/
@NonNull
public Builder setSupportedAttributes(
@SuggestionsInfo.ResultAttrs int supportedAttributes) {
mSupportedAttributes = supportedAttributes;
return this;
}
/**
* Sets a bundle containing extra parameters for the spell checker.
*
* <p>This bundle can be used to pass implementation-specific parameters to the
* {@link android.service.textservice.SpellCheckerService} implementation.
*
* @see android.service.textservice.SpellCheckerService.Session#getBundle()
*/
@NonNull
public Builder setExtras(@NonNull Bundle extras) {
mExtras = extras;
return this;
}
}
}
/**
* Callback for getting results from text services
*/

View File

@@ -19,7 +19,6 @@ package android.view.textservice;
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.SystemService;
import android.annotation.UserIdInt;
import android.compat.annotation.UnsupportedAppUsage;
@@ -35,6 +34,7 @@ import android.os.UserHandle;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;
import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener;
import android.view.textservice.SpellCheckerSession.SpellCheckerSessionParams;
import com.android.internal.textservice.ISpellCheckerSessionListener;
import com.android.internal.textservice.ITextServicesManager;
@@ -166,15 +166,17 @@ public final class TextServicesManager {
* {@link SuggestionsInfo#RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS} will be passed to the spell
* checker as supported attributes.
*
* @see #newSpellCheckerSession(Locale, boolean, int, Bundle, Executor,
* SpellCheckerSessionListener)
* @param bundle A bundle to pass to the spell checker.
* @param locale The locale for the spell checker.
* @param listener A spell checker session lister for getting results from the spell checker.
* The listener will be called on the calling thread.
* @param referToSpellCheckerLanguageSettings If true, the session for one of enabled
* languages in settings will be used.
* @return A spell checker session from the spell checker.
* @param locale the locale for the spell checker. If {@code locale} is null and
* referToSpellCheckerLanguageSettings is true, the locale specified in Settings will be
* returned. If {@code locale} is not null and referToSpellCheckerLanguageSettings is true,
* the locale specified in Settings will be returned only when it is same as {@code locale}.
* Exceptionally, when referToSpellCheckerLanguageSettings is true and {@code locale} is
* only language (e.g. "en"), the specified locale in Settings (e.g. "en_US") will be
* selected.
* @param listener a spell checker session lister for getting results from the spell checker.
* @param referToSpellCheckerLanguageSettings if true, the session for one of enabled
* languages in settings will be returned.
* @return a spell checker session of the spell checker
*/
@Nullable
public SpellCheckerSession newSpellCheckerSession(@Nullable Bundle bundle,
@@ -186,51 +188,40 @@ public final class TextServicesManager {
int supportedAttributes = SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY
| SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO
| SuggestionsInfo.RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS;
SpellCheckerSessionParams.Builder paramsBuilder = new SpellCheckerSessionParams.Builder()
.setLocale(locale)
.setShouldReferToSpellCheckerLanguageSettings(referToSpellCheckerLanguageSettings)
.setSupportedAttributes(supportedAttributes);
if (bundle != null) {
paramsBuilder.setExtras(bundle);
}
// Using the implicit looper to preserve the old behavior.
Executor executor = new HandlerExecutor(new Handler());
return newSpellCheckerSession(locale, referToSpellCheckerLanguageSettings,
supportedAttributes, bundle, executor, listener);
return newSpellCheckerSession(paramsBuilder.build(), executor, listener);
}
/**
* Get a spell checker session from the spell checker.
*
* <p>If {@code locale} is null and {@code referToSpellCheckerLanguageSettings} is true, the
* locale specified in Settings will be used. If {@code locale} is not null and
* {@code referToSpellCheckerLanguageSettings} is true, the locale specified in Settings will be
* returned only when it is same as {@code locale}.
* Exceptionally, when {@code referToSpellCheckerLanguageSettings} is true and {@code locale} is
* language only (e.g. "en"), the specified locale in Settings (e.g. "en_US") will be
* selected.
*
* @param locale The locale for the spell checker.
* @param referToSpellCheckerLanguageSettings If true, the session for one of enabled
* languages in settings will be used.
* @param supportedAttributes A union of {@link SuggestionsInfo} attributes that the spell
* checker can set in the spell checking results.
* @param bundle A bundle for passing implementation-specific extra parameters for the spell
* checker. You can check the current spell checker package by
* {@link #getCurrentSpellCheckerInfo()}.
* @param executor An executor to call the listener on.
* @param listener A spell checker session lister for getting results from a spell checker.
* @param params The parameters passed to the spell checker.
* @param executor The executor on which {@code listener} will be called back.
* @param listener a spell checker session lister for getting results from the spell checker.
* @return The spell checker session of the spell checker.
*/
@Nullable
public SpellCheckerSession newSpellCheckerSession(
@SuppressLint("UseIcu") @Nullable Locale locale,
boolean referToSpellCheckerLanguageSettings,
@SuggestionsInfo.ResultAttrs int supportedAttributes,
@Nullable Bundle bundle,
@NonNull SpellCheckerSessionParams params,
@NonNull @CallbackExecutor Executor executor,
@NonNull SpellCheckerSessionListener listener) {
Objects.requireNonNull(executor);
Objects.requireNonNull(listener);
if (!referToSpellCheckerLanguageSettings && locale == null) {
Locale locale = params.getLocale();
if (!params.shouldReferToSpellCheckerLanguageSettings() && locale == null) {
throw new IllegalArgumentException("Locale should not be null if you don't refer"
+ " settings.");
}
if (referToSpellCheckerLanguageSettings && !isSpellCheckerEnabled()) {
if (params.shouldReferToSpellCheckerLanguageSettings() && !isSpellCheckerEnabled()) {
return null;
}
@@ -244,7 +235,7 @@ public final class TextServicesManager {
return null;
}
SpellCheckerSubtype subtypeInUse = null;
if (referToSpellCheckerLanguageSettings) {
if (params.shouldReferToSpellCheckerLanguageSettings()) {
subtypeInUse = getCurrentSpellCheckerSubtype(true);
if (subtypeInUse == null) {
return null;
@@ -278,7 +269,8 @@ public final class TextServicesManager {
try {
mService.getSpellCheckerService(mUserId, sci.getId(), subtypeInUse.getLocale(),
session.getTextServicesSessionListener(),
session.getSpellCheckerSessionListener(), bundle, supportedAttributes);
session.getSpellCheckerSessionListener(),
params.getExtras(), params.getSupportedAttributes());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

View File

@@ -28,6 +28,7 @@ import android.util.Range;
import android.view.textservice.SentenceSuggestionsInfo;
import android.view.textservice.SpellCheckerSession;
import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener;
import android.view.textservice.SpellCheckerSession.SpellCheckerSessionParams;
import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo;
import android.view.textservice.TextServicesManager;
@@ -124,10 +125,12 @@ public class SpellChecker implements SpellCheckerSessionListener {
| SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO
| SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_GRAMMAR_ERROR
| SuggestionsInfo.RESULT_ATTR_DONT_SHOW_UI_FOR_SUGGESTIONS;
SpellCheckerSessionParams params = new SpellCheckerSessionParams.Builder()
.setLocale(mCurrentLocale)
.setSupportedAttributes(supportedAttributes)
.build();
mSpellCheckerSession = mTextServicesManager.newSpellCheckerSession(
mCurrentLocale, false, supportedAttributes,
null /* Bundle not currently used by the textServicesManager */,
mTextView.getContext().getMainExecutor(), this);
params, mTextView.getContext().getMainExecutor(), this);
}
// Restore SpellCheckSpans in pool