Merge "Add supportedAttributes param for spell checker."

This commit is contained in:
TreeHugger Robot
2021-01-21 19:45:17 +00:00
committed by Android (Google) Code Review
8 changed files with 128 additions and 34 deletions

View File

@@ -38202,6 +38202,7 @@ package android.service.textservice {
ctor public SpellCheckerService.Session();
method public android.os.Bundle getBundle();
method public String getLocale();
method public int getSupportedAttributes();
method public void onCancel();
method public void onClose();
method public abstract void onCreate();
@@ -51796,7 +51797,8 @@ package android.view.textservice {
method @Nullable public android.view.textservice.SpellCheckerSubtype getCurrentSpellCheckerSubtype(boolean);
method @Nullable public java.util.List<android.view.textservice.SpellCheckerInfo> getEnabledSpellCheckersList();
method public boolean isSpellCheckerEnabled();
method public android.view.textservice.SpellCheckerSession newSpellCheckerSession(android.os.Bundle, java.util.Locale, android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener, boolean);
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 android.os.Bundle, @Nullable java.util.Locale, @NonNull android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener, boolean, int);
}
}

View File

@@ -16,11 +16,6 @@
package android.service.textservice;
import com.android.internal.textservice.ISpellCheckerService;
import com.android.internal.textservice.ISpellCheckerServiceCallback;
import com.android.internal.textservice.ISpellCheckerSession;
import com.android.internal.textservice.ISpellCheckerSessionListener;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
@@ -34,6 +29,11 @@ import android.view.textservice.SentenceSuggestionsInfo;
import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo;
import com.android.internal.textservice.ISpellCheckerService;
import com.android.internal.textservice.ISpellCheckerServiceCallback;
import com.android.internal.textservice.ISpellCheckerSession;
import com.android.internal.textservice.ISpellCheckerSessionListener;
import java.lang.ref.WeakReference;
import java.text.BreakIterator;
import java.util.ArrayList;
@@ -231,6 +231,18 @@ public abstract class SpellCheckerService extends Service {
public Bundle getBundle() {
return mInternalSession.getBundle();
}
/**
* Returns result attributes supported for this session.
*
* <p>The session implementation should not set attributes that are not included in the
* return value of {@code getSupportedAttributes()} when creating {@link SuggestionsInfo}.
*
* @return The supported result attributes for this session
*/
public @SuggestionsInfo.ResultAttrs int getSupportedAttributes() {
return mInternalSession.getSupportedAttributes();
}
}
// Preventing from exposing ISpellCheckerSession.aidl, create an internal class.
@@ -239,13 +251,16 @@ public abstract class SpellCheckerService extends Service {
private final Session mSession;
private final String mLocale;
private final Bundle mBundle;
private final @SuggestionsInfo.ResultAttrs int mSupportedAttributes;
public InternalISpellCheckerSession(String locale, ISpellCheckerSessionListener listener,
Bundle bundle, Session session) {
Bundle bundle, Session session,
@SuggestionsInfo.ResultAttrs int supportedAttributes) {
mListener = listener;
mSession = session;
mLocale = locale;
mBundle = bundle;
mSupportedAttributes = supportedAttributes;
session.setInternalISpellCheckerSession(this);
}
@@ -303,6 +318,10 @@ public abstract class SpellCheckerService extends Service {
public Bundle getBundle() {
return mBundle;
}
public @SuggestionsInfo.ResultAttrs int getSupportedAttributes() {
return mSupportedAttributes;
}
}
private static class SpellCheckerServiceBinder extends ISpellCheckerService.Stub {
@@ -323,11 +342,14 @@ public abstract class SpellCheckerService extends Service {
* {@link Session#onGetSuggestionsMultiple(TextInfo[], int, boolean)} and
* {@link Session#onGetSuggestions(TextInfo, int)}
* @param bundle bundle to be returned from {@link Session#getBundle()}
* @param supportedAttributes A union of {@link SuggestionsInfo} attributes that the spell
* checker can set in the spell checking results.
* @param callback IPC channel to return the result to the caller in an asynchronous manner
*/
@Override
public void getISpellCheckerSession(
String locale, ISpellCheckerSessionListener listener, Bundle bundle,
@SuggestionsInfo.ResultAttrs int supportedAttributes,
ISpellCheckerServiceCallback callback) {
final SpellCheckerService service = mInternalServiceRef.get();
final InternalISpellCheckerSession internalSession;
@@ -337,8 +359,8 @@ public abstract class SpellCheckerService extends Service {
internalSession = null;
} else {
final Session session = service.createSession();
internalSession =
new InternalISpellCheckerSession(locale, listener, bundle, session);
internalSession = new InternalISpellCheckerSession(
locale, listener, bundle, session, supportedAttributes);
session.onCreate();
}
try {

View File

@@ -16,17 +16,37 @@
package android.view.textservice;
import android.annotation.IntDef;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.ArrayUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* This class contains a metadata of suggestions from the text service
*/
public final class SuggestionsInfo implements Parcelable {
private static final String[] EMPTY = ArrayUtils.emptyArray(String.class);
/**
* An internal annotation to indicate that one ore more combinations of
* <code>RESULT_ATTR_</code> flags are expected.
*
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, prefix = { "RESULT_ATTR_" }, value = {
RESULT_ATTR_IN_THE_DICTIONARY,
RESULT_ATTR_LOOKS_LIKE_TYPO,
RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS,
RESULT_ATTR_LOOKS_LIKE_GRAMMAR_ERROR,
RESULT_ATTR_DONT_SHOW_UI_FOR_SUGGESTIONS,
})
public @interface ResultAttrs {}
/**
* Flag of the attributes of the suggestions that can be obtained by
* {@link #getSuggestionsAttributes}: this tells that the requested word was found
@@ -63,7 +83,7 @@ public final class SuggestionsInfo implements Parcelable {
*/
public static final int RESULT_ATTR_DONT_SHOW_UI_FOR_SUGGESTIONS = 0x0010;
private final int mSuggestionsAttributes;
private final @ResultAttrs int mSuggestionsAttributes;
private final String[] mSuggestions;
private final boolean mSuggestionsAvailable;
private int mCookie;
@@ -85,8 +105,8 @@ public final class SuggestionsInfo implements Parcelable {
* @param cookie the cookie of the input TextInfo
* @param sequence the cookie of the input TextInfo
*/
public SuggestionsInfo(
int suggestionsAttributes, String[] suggestions, int cookie, int sequence) {
public SuggestionsInfo(@ResultAttrs int suggestionsAttributes, String[] suggestions, int cookie,
int sequence) {
if (suggestions == null) {
mSuggestions = EMPTY;
mSuggestionsAvailable = false;
@@ -152,7 +172,7 @@ public final class SuggestionsInfo implements Parcelable {
* in its dictionary or not and whether the spell checker has confident suggestions for the
* word or not.
*/
public int getSuggestionsAttributes() {
public @ResultAttrs int getSuggestionsAttributes() {
return mSuggestionsAttributes;
}

View File

@@ -18,6 +18,7 @@ package android.view.textservice;
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;
@@ -139,21 +140,58 @@ public final class TextServicesManager {
}
/**
* Get a spell checker session for the specified 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 a spell checker.
* @param referToSpellCheckerLanguageSettings if true, the session for one of enabled
* languages in settings will be returned.
* @return the spell checker session of the spell checker
* Get a spell checker session from the spell checker.
*
* <p>{@link SuggestionsInfo#RESULT_ATTR_IN_THE_DICTIONARY},
* {@link SuggestionsInfo#RESULT_ATTR_LOOKS_LIKE_TYPO}, and
* {@link SuggestionsInfo#RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS} will be passed to the spell
* checker as supported attributes.
*
* @see #newSpellCheckerSession(Bundle, Locale, SpellCheckerSessionListener, boolean, int)
* @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.
* @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.
*/
public SpellCheckerSession newSpellCheckerSession(Bundle bundle, Locale locale,
SpellCheckerSessionListener listener, boolean referToSpellCheckerLanguageSettings) {
@Nullable
public SpellCheckerSession newSpellCheckerSession(@Nullable Bundle bundle,
@Nullable Locale locale,
@NonNull SpellCheckerSessionListener listener,
boolean referToSpellCheckerLanguageSettings) {
return newSpellCheckerSession(bundle, locale, listener, referToSpellCheckerLanguageSettings,
SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY
| SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO
| SuggestionsInfo.RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS);
}
/**
* 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 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 a 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.
* @return The spell checker session of the spell checker.
*/
@Nullable
public SpellCheckerSession newSpellCheckerSession(@Nullable Bundle bundle,
@SuppressLint("UseIcu") @Nullable Locale locale,
@NonNull SpellCheckerSessionListener listener,
@SuppressLint("ListenerLast") boolean referToSpellCheckerLanguageSettings,
@SuppressLint("ListenerLast") @SuggestionsInfo.ResultAttrs int supportedAttributes) {
if (listener == null) {
throw new NullPointerException();
}
@@ -210,7 +248,7 @@ public final class TextServicesManager {
try {
mService.getSpellCheckerService(mUserId, sci.getId(), subtypeInUse.getLocale(),
session.getTextServicesSessionListener(),
session.getSpellCheckerSessionListener(), bundle);
session.getSpellCheckerSessionListener(), bundle, supportedAttributes);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

View File

@@ -129,7 +129,11 @@ public class SpellChecker implements SpellCheckerSessionListener {
mSpellCheckerSession = mTextServicesManager.newSpellCheckerSession(
null /* Bundle not currently used by the textServicesManager */,
mCurrentLocale, this,
false /* means any available languages from current spell checker */);
false /* means any available languages from current spell checker */,
SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY
| SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO
| SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_GRAMMAR_ERROR
| SuggestionsInfo.RESULT_ATTR_DONT_SHOW_UI_FOR_SUGGESTIONS);
mIsSentenceSpellCheckSupported = true;
}

View File

@@ -39,9 +39,11 @@ oneway interface ISpellCheckerService {
* {@link android.service.textservice.SpellCheckerService.Session#onGetSuggestionsMultiple(TextInfo[], int, boolean)} and
* {@link android.service.textservice.SpellCheckerService.Session#onGetSuggestions(TextInfo, int)}
* @param bundle bundle to be returned from {@link android.service.textservice.SpellCheckerService.Session#getBundle()}
* @param supportedAttributes supported attributes to be returned from {@link android.service.textservice.SpellCheckerService.Session#getSupportedAttributes()}
* @param callback IPC channel to return the result to the caller in an asynchronous manner
*/
void getISpellCheckerSession(
String locale, ISpellCheckerSessionListener listener, in Bundle bundle,
int supportedAttributes,
ISpellCheckerServiceCallback callback);
}

View File

@@ -34,7 +34,7 @@ interface ITextServicesManager {
boolean allowImplicitlySelectedSubtype);
oneway void getSpellCheckerService(int userId, String sciId, in String locale,
in ITextServicesSessionListener tsListener,
in ISpellCheckerSessionListener scListener, in Bundle bundle);
in ISpellCheckerSessionListener scListener, in Bundle bundle, int supportedAttributes);
oneway void finishSpellCheckerService(int userId, in ISpellCheckerSessionListener listener);
boolean isSpellCheckerEnabled(int userId);
SpellCheckerInfo[] getEnabledSpellCheckers(int userId);

View File

@@ -45,6 +45,7 @@ import android.util.Slog;
import android.util.SparseArray;
import android.view.textservice.SpellCheckerInfo;
import android.view.textservice.SpellCheckerSubtype;
import android.view.textservice.SuggestionsInfo;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
@@ -58,7 +59,6 @@ import com.android.internal.textservice.ITextServicesSessionListener;
import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemService.TargetUser;
import org.xmlpull.v1.XmlPullParserException;
@@ -567,7 +567,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
@Override
public void getSpellCheckerService(@UserIdInt int userId, String sciId, String locale,
ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener,
Bundle bundle) {
Bundle bundle, @SuggestionsInfo.ResultAttrs int supportedAttributes) {
verifyUser(userId);
if (TextUtils.isEmpty(sciId) || tsListener == null || scListener == null) {
Slog.e(TAG, "getSpellCheckerService: Invalid input.");
@@ -603,7 +603,8 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
// Start getISpellCheckerSession async IPC, or just queue the request until the spell
// checker service is bound.
bindGroup.getISpellCheckerSessionOrQueueLocked(
new SessionRequest(uid, locale, tsListener, scListener, bundle));
new SessionRequest(uid, locale, tsListener, scListener, bundle,
supportedAttributes));
}
}
@@ -774,15 +775,18 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
public final ISpellCheckerSessionListener mScListener;
@Nullable
public final Bundle mBundle;
public final int mSupportedAttributes;
SessionRequest(int uid, @Nullable String locale,
@NonNull ITextServicesSessionListener tsListener,
@NonNull ISpellCheckerSessionListener scListener, @Nullable Bundle bundle) {
@NonNull ISpellCheckerSessionListener scListener, @Nullable Bundle bundle,
@SuggestionsInfo.ResultAttrs int supportedAttributes) {
mUid = uid;
mLocale = locale;
mTsListener = tsListener;
mScListener = scListener;
mBundle = bundle;
mSupportedAttributes = supportedAttributes;
}
}
@@ -825,6 +829,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
final SessionRequest request = mPendingSessionRequests.get(i);
mSpellChecker.getISpellCheckerSession(
request.mLocale, request.mScListener, request.mBundle,
request.mSupportedAttributes,
new ISpellCheckerServiceCallbackBinder(this, request));
mOnGoingSessionRequests.add(request);
}
@@ -913,6 +918,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
try {
mSpellChecker.getISpellCheckerSession(
request.mLocale, request.mScListener, request.mBundle,
request.mSupportedAttributes,
new ISpellCheckerServiceCallbackBinder(this, request));
mOnGoingSessionRequests.add(request);
} catch(RemoteException e) {