Merge "Add Executor param to TSM#newSpellCheckerSession()." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
c95396e1c8
@@ -52315,7 +52315,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 android.os.Bundle, @Nullable java.util.Locale, @NonNull android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener, boolean, int);
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.view.textservice;
|
||||
|
||||
import android.annotation.BinderThread;
|
||||
import android.annotation.Nullable;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
@@ -27,6 +29,7 @@ import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.textservice.ISpellCheckerSession;
|
||||
import com.android.internal.textservice.ISpellCheckerSessionListener;
|
||||
import com.android.internal.textservice.ITextServicesSessionListener;
|
||||
@@ -35,6 +38,7 @@ import dalvik.system.CloseGuard;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* The SpellCheckerSession interface provides the per client functionality of SpellCheckerService.
|
||||
@@ -102,38 +106,26 @@ public class SpellCheckerSession {
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||||
private final SpellCheckerSessionListener mSpellCheckerSessionListener;
|
||||
private final SpellCheckerSessionListenerImpl mSpellCheckerSessionListenerImpl;
|
||||
private final Executor mExecutor;
|
||||
|
||||
private final CloseGuard mGuard = CloseGuard.get();
|
||||
|
||||
/** Handler that will execute the main tasks */
|
||||
private final Handler mHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MSG_ON_GET_SUGGESTION_MULTIPLE:
|
||||
handleOnGetSuggestionsMultiple((SuggestionsInfo[]) msg.obj);
|
||||
break;
|
||||
case MSG_ON_GET_SUGGESTION_MULTIPLE_FOR_SENTENCE:
|
||||
handleOnGetSentenceSuggestionsMultiple((SentenceSuggestionsInfo[]) msg.obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @hide
|
||||
*/
|
||||
public SpellCheckerSession(
|
||||
SpellCheckerInfo info, TextServicesManager tsm, SpellCheckerSessionListener listener) {
|
||||
SpellCheckerInfo info, TextServicesManager tsm, SpellCheckerSessionListener listener,
|
||||
Executor executor) {
|
||||
if (info == null || listener == null || tsm == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
mSpellCheckerInfo = info;
|
||||
mSpellCheckerSessionListenerImpl = new SpellCheckerSessionListenerImpl(mHandler);
|
||||
mSpellCheckerSessionListenerImpl = new SpellCheckerSessionListenerImpl(this);
|
||||
mInternalListener = new InternalListener(mSpellCheckerSessionListenerImpl);
|
||||
mTextServicesManager = tsm;
|
||||
mSpellCheckerSessionListener = listener;
|
||||
mExecutor = executor;
|
||||
|
||||
mGuard.open("finishSession");
|
||||
}
|
||||
@@ -219,12 +211,13 @@ public class SpellCheckerSession {
|
||||
textInfos, suggestionsLimit, sequentialWords);
|
||||
}
|
||||
|
||||
private void handleOnGetSuggestionsMultiple(SuggestionsInfo[] suggestionInfos) {
|
||||
mSpellCheckerSessionListener.onGetSuggestions(suggestionInfos);
|
||||
void handleOnGetSuggestionsMultiple(SuggestionsInfo[] suggestionsInfos) {
|
||||
mExecutor.execute(() -> mSpellCheckerSessionListener.onGetSuggestions(suggestionsInfos));
|
||||
}
|
||||
|
||||
private void handleOnGetSentenceSuggestionsMultiple(SentenceSuggestionsInfo[] suggestionInfos) {
|
||||
mSpellCheckerSessionListener.onGetSentenceSuggestions(suggestionInfos);
|
||||
void handleOnGetSentenceSuggestionsMultiple(SentenceSuggestionsInfo[] suggestionsInfos) {
|
||||
mExecutor.execute(() ->
|
||||
mSpellCheckerSessionListener.onGetSentenceSuggestions(suggestionsInfos));
|
||||
}
|
||||
|
||||
private static final class SpellCheckerSessionListenerImpl
|
||||
@@ -249,7 +242,8 @@ public class SpellCheckerSession {
|
||||
}
|
||||
|
||||
private final Queue<SpellCheckerParams> mPendingTasks = new LinkedList<>();
|
||||
private Handler mHandler;
|
||||
@GuardedBy("SpellCheckerSessionListenerImpl.this")
|
||||
private SpellCheckerSession mSpellCheckerSession;
|
||||
|
||||
private static final int STATE_WAIT_CONNECTION = 0;
|
||||
private static final int STATE_CONNECTED = 1;
|
||||
@@ -270,8 +264,8 @@ public class SpellCheckerSession {
|
||||
private HandlerThread mThread;
|
||||
private Handler mAsyncHandler;
|
||||
|
||||
public SpellCheckerSessionListenerImpl(Handler handler) {
|
||||
mHandler = handler;
|
||||
SpellCheckerSessionListenerImpl(SpellCheckerSession spellCheckerSession) {
|
||||
mSpellCheckerSession = spellCheckerSession;
|
||||
}
|
||||
|
||||
private static class SpellCheckerParams {
|
||||
@@ -349,6 +343,7 @@ public class SpellCheckerSession {
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("SpellCheckerSessionListenerImpl.this")
|
||||
private void processCloseLocked() {
|
||||
if (DBG) Log.d(TAG, "entering processCloseLocked:"
|
||||
+ " session" + (mISpellCheckerSession != null ? ".hashCode()=#"
|
||||
@@ -358,7 +353,7 @@ public class SpellCheckerSession {
|
||||
if (mThread != null) {
|
||||
mThread.quit();
|
||||
}
|
||||
mHandler = null;
|
||||
mSpellCheckerSession = null;
|
||||
mPendingTasks.clear();
|
||||
mThread = null;
|
||||
mAsyncHandler = null;
|
||||
@@ -502,23 +497,30 @@ public class SpellCheckerSession {
|
||||
processTask(session, scp, false);
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
@Override
|
||||
public void onGetSuggestions(SuggestionsInfo[] results) {
|
||||
synchronized (this) {
|
||||
if (mHandler != null) {
|
||||
mHandler.sendMessage(Message.obtain(mHandler,
|
||||
MSG_ON_GET_SUGGESTION_MULTIPLE, results));
|
||||
}
|
||||
SpellCheckerSession session = getSpellCheckerSession();
|
||||
if (session != null) {
|
||||
// Lock should not be held when calling callback, in order to avoid deadlock.
|
||||
session.handleOnGetSuggestionsMultiple(results);
|
||||
}
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
@Override
|
||||
public void onGetSentenceSuggestions(SentenceSuggestionsInfo[] results) {
|
||||
synchronized (this) {
|
||||
if (mHandler != null) {
|
||||
mHandler.sendMessage(Message.obtain(mHandler,
|
||||
MSG_ON_GET_SUGGESTION_MULTIPLE_FOR_SENTENCE, results));
|
||||
}
|
||||
SpellCheckerSession session = getSpellCheckerSession();
|
||||
if (session != null) {
|
||||
// Lock should not be held when calling callback, in order to avoid deadlock.
|
||||
session.handleOnGetSentenceSuggestionsMultiple(results);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private SpellCheckerSession getSpellCheckerSession() {
|
||||
synchronized (SpellCheckerSessionListenerImpl.this) {
|
||||
return mSpellCheckerSession;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.view.textservice;
|
||||
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SuppressLint;
|
||||
@@ -25,6 +26,8 @@ import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerExecutor;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.ServiceManager.ServiceNotFoundException;
|
||||
@@ -40,6 +43,8 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* System API to the overall text services, which arbitrates interaction between applications
|
||||
@@ -161,10 +166,12 @@ public final class TextServicesManager {
|
||||
* {@link SuggestionsInfo#RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS} will be passed to the spell
|
||||
* checker as supported attributes.
|
||||
*
|
||||
* @see #newSpellCheckerSession(Bundle, Locale, SpellCheckerSessionListener, boolean, int)
|
||||
* @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.
|
||||
@@ -174,10 +181,15 @@ public final class TextServicesManager {
|
||||
@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);
|
||||
// Attributes existed before {@link #newSpellCheckerSession(Locale, boolean, int, Bundle,
|
||||
// Executor, SpellCheckerSessionListener)} was introduced.
|
||||
int supportedAttributes = SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY
|
||||
| SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO
|
||||
| SuggestionsInfo.RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS;
|
||||
// Using the implicit looper to preserve the old behavior.
|
||||
Executor executor = new HandlerExecutor(new Handler());
|
||||
return newSpellCheckerSession(locale, referToSpellCheckerLanguageSettings,
|
||||
supportedAttributes, bundle, executor, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,25 +203,28 @@ public final class TextServicesManager {
|
||||
* 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.
|
||||
* @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.
|
||||
* @return The spell checker session of the spell checker.
|
||||
*/
|
||||
@Nullable
|
||||
public SpellCheckerSession newSpellCheckerSession(
|
||||
@SuppressLint("NullableCollection") @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();
|
||||
}
|
||||
boolean referToSpellCheckerLanguageSettings,
|
||||
@SuggestionsInfo.ResultAttrs int supportedAttributes,
|
||||
@Nullable Bundle bundle,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull SpellCheckerSessionListener listener) {
|
||||
Objects.requireNonNull(executor);
|
||||
Objects.requireNonNull(listener);
|
||||
if (!referToSpellCheckerLanguageSettings && locale == null) {
|
||||
throw new IllegalArgumentException("Locale should not be null if you don't refer"
|
||||
+ " settings.");
|
||||
@@ -259,7 +274,7 @@ public final class TextServicesManager {
|
||||
if (subtypeInUse == null) {
|
||||
return null;
|
||||
}
|
||||
final SpellCheckerSession session = new SpellCheckerSession(sci, this, listener);
|
||||
final SpellCheckerSession session = new SpellCheckerSession(sci, this, listener, executor);
|
||||
try {
|
||||
mService.getSpellCheckerService(mUserId, sci.getId(), subtypeInUse.getLocale(),
|
||||
session.getTextServicesSessionListener(),
|
||||
|
||||
@@ -126,14 +126,14 @@ public class SpellChecker implements SpellCheckerSessionListener {
|
||||
|| mTextServicesManager.getCurrentSpellCheckerSubtype(true) == null) {
|
||||
mSpellCheckerSession = null;
|
||||
} else {
|
||||
int supportedAttributes = 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;
|
||||
mSpellCheckerSession = mTextServicesManager.newSpellCheckerSession(
|
||||
mCurrentLocale, false, supportedAttributes,
|
||||
null /* Bundle not currently used by the textServicesManager */,
|
||||
mCurrentLocale, this,
|
||||
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);
|
||||
mTextView.getContext().getMainExecutor(), this);
|
||||
}
|
||||
|
||||
// Restore SpellCheckSpans in pool
|
||||
|
||||
Reference in New Issue
Block a user