Merge "InputMethodInfo attr to suppress spell checker." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
5ed3cb20b3
@@ -1394,6 +1394,7 @@ package android {
|
||||
field public static final int supportsRtl = 16843695; // 0x10103af
|
||||
field public static final int supportsSwitchingToNextInputMethod = 16843755; // 0x10103eb
|
||||
field public static final int supportsUploading = 16843419; // 0x101029b
|
||||
field public static final int suppressesSpellChecker = 16844354; // 0x1010642
|
||||
field public static final int switchMinWidth = 16843632; // 0x1010370
|
||||
field public static final int switchPadding = 16843633; // 0x1010371
|
||||
field public static final int switchPreferenceStyle = 16843629; // 0x101036d
|
||||
@@ -51470,6 +51471,7 @@ package android.view.inputmethod {
|
||||
method public int getSubtypeCount();
|
||||
method public android.graphics.drawable.Drawable loadIcon(android.content.pm.PackageManager);
|
||||
method public CharSequence loadLabel(android.content.pm.PackageManager);
|
||||
method public boolean suppressesSpellChecker();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.view.inputmethod.InputMethodInfo> CREATOR;
|
||||
}
|
||||
@@ -51491,6 +51493,7 @@ package android.view.inputmethod {
|
||||
method public boolean isActive(android.view.View);
|
||||
method public boolean isActive();
|
||||
method public boolean isFullscreenMode();
|
||||
method public boolean isInputMethodSuppressingSpellChecker();
|
||||
method @Deprecated public boolean isWatchingCursor(android.view.View);
|
||||
method public void restartInput(android.view.View);
|
||||
method public void sendAppPrivateCommand(android.view.View, String, android.os.Bundle);
|
||||
|
||||
@@ -60,6 +60,7 @@ import java.util.List;
|
||||
* @attr ref android.R.styleable#InputMethod_isDefault
|
||||
* @attr ref android.R.styleable#InputMethod_supportsSwitchingToNextInputMethod
|
||||
* @attr ref android.R.styleable#InputMethod_supportsInlineSuggestions
|
||||
* @attr ref android.R.styleable#InputMethod_suppressesSpellChecker
|
||||
*/
|
||||
public final class InputMethodInfo implements Parcelable {
|
||||
static final String TAG = "InputMethodInfo";
|
||||
@@ -117,6 +118,11 @@ public final class InputMethodInfo implements Parcelable {
|
||||
*/
|
||||
private final boolean mInlineSuggestionsEnabled;
|
||||
|
||||
/**
|
||||
* The flag whether this IME suppresses spell checker.
|
||||
*/
|
||||
private final boolean mSuppressesSpellChecker;
|
||||
|
||||
/**
|
||||
* @param service the {@link ResolveInfo} corresponds in which the IME is implemented.
|
||||
* @return a unique ID to be returned by {@link #getId()}. We have used
|
||||
@@ -160,6 +166,7 @@ public final class InputMethodInfo implements Parcelable {
|
||||
boolean isAuxIme = true;
|
||||
boolean supportsSwitchingToNextInputMethod = false; // false as default
|
||||
boolean inlineSuggestionsEnabled = false; // false as default
|
||||
boolean suppressesSpellChecker = false; // false as default
|
||||
mForceDefault = false;
|
||||
|
||||
PackageManager pm = context.getPackageManager();
|
||||
@@ -203,6 +210,8 @@ public final class InputMethodInfo implements Parcelable {
|
||||
false);
|
||||
inlineSuggestionsEnabled = sa.getBoolean(
|
||||
com.android.internal.R.styleable.InputMethod_supportsInlineSuggestions, false);
|
||||
suppressesSpellChecker = sa.getBoolean(
|
||||
com.android.internal.R.styleable.InputMethod_suppressesSpellChecker, false);
|
||||
sa.recycle();
|
||||
|
||||
final int depth = parser.getDepth();
|
||||
@@ -274,6 +283,7 @@ public final class InputMethodInfo implements Parcelable {
|
||||
mIsAuxIme = isAuxIme;
|
||||
mSupportsSwitchingToNextInputMethod = supportsSwitchingToNextInputMethod;
|
||||
mInlineSuggestionsEnabled = inlineSuggestionsEnabled;
|
||||
mSuppressesSpellChecker = suppressesSpellChecker;
|
||||
mIsVrOnly = isVrOnly;
|
||||
}
|
||||
|
||||
@@ -284,6 +294,7 @@ public final class InputMethodInfo implements Parcelable {
|
||||
mIsAuxIme = source.readInt() == 1;
|
||||
mSupportsSwitchingToNextInputMethod = source.readInt() == 1;
|
||||
mInlineSuggestionsEnabled = source.readInt() == 1;
|
||||
mSuppressesSpellChecker = source.readBoolean();
|
||||
mIsVrOnly = source.readBoolean();
|
||||
mService = ResolveInfo.CREATOR.createFromParcel(source);
|
||||
mSubtypes = new InputMethodSubtypeArray(source);
|
||||
@@ -342,6 +353,7 @@ public final class InputMethodInfo implements Parcelable {
|
||||
mForceDefault = forceDefault;
|
||||
mSupportsSwitchingToNextInputMethod = supportsSwitchingToNextInputMethod;
|
||||
mInlineSuggestionsEnabled = inlineSuggestionsEnabled;
|
||||
mSuppressesSpellChecker = false;
|
||||
mIsVrOnly = isVrOnly;
|
||||
}
|
||||
|
||||
@@ -494,7 +506,8 @@ public final class InputMethodInfo implements Parcelable {
|
||||
+ " mSettingsActivityName=" + mSettingsActivityName
|
||||
+ " mIsVrOnly=" + mIsVrOnly
|
||||
+ " mSupportsSwitchingToNextInputMethod=" + mSupportsSwitchingToNextInputMethod
|
||||
+ " mInlineSuggestionsEnabled=" + mInlineSuggestionsEnabled);
|
||||
+ " mInlineSuggestionsEnabled=" + mInlineSuggestionsEnabled
|
||||
+ " mSuppressesSpellChecker=" + mSuppressesSpellChecker);
|
||||
pw.println(prefix + "mIsDefaultResId=0x"
|
||||
+ Integer.toHexString(mIsDefaultResId));
|
||||
pw.println(prefix + "Service:");
|
||||
@@ -562,6 +575,13 @@ public final class InputMethodInfo implements Parcelable {
|
||||
return mInlineSuggestionsEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if this input method suppresses spell checker.
|
||||
*/
|
||||
public boolean suppressesSpellChecker() {
|
||||
return mSuppressesSpellChecker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to package this object into a {@link Parcel}.
|
||||
*
|
||||
@@ -576,6 +596,7 @@ public final class InputMethodInfo implements Parcelable {
|
||||
dest.writeInt(mIsAuxIme ? 1 : 0);
|
||||
dest.writeInt(mSupportsSwitchingToNextInputMethod ? 1 : 0);
|
||||
dest.writeInt(mInlineSuggestionsEnabled ? 1 : 0);
|
||||
dest.writeBoolean(mSuppressesSpellChecker);
|
||||
dest.writeBoolean(mIsVrOnly);
|
||||
mService.writeToParcel(dest, flags);
|
||||
mSubtypes.writeToParcel(dest);
|
||||
|
||||
@@ -444,6 +444,13 @@ public final class InputMethodManager {
|
||||
*/
|
||||
private Matrix mActivityViewToScreenMatrix = null;
|
||||
|
||||
/**
|
||||
* As reported by {@link InputBindResult}. This value is determined by
|
||||
* {@link com.android.internal.R.styleable#InputMethod_suppressesSpellChecking}.
|
||||
*/
|
||||
@GuardedBy("mH")
|
||||
private boolean mIsInputMethodSuppressingSpellChecker = false;
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -858,6 +865,8 @@ public final class InputMethodManager {
|
||||
mCurId = res.id;
|
||||
mBindSequence = res.sequence;
|
||||
mActivityViewToScreenMatrix = res.getActivityViewToScreenMatrix();
|
||||
mIsInputMethodSuppressingSpellChecker =
|
||||
res.isInputMethodSuppressingSpellChecker;
|
||||
}
|
||||
startInputInner(StartInputReason.BOUND_TO_IMMS, null, 0, 0, 0);
|
||||
return;
|
||||
@@ -1469,6 +1478,15 @@ public final class InputMethodManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the input method is suppressing system spell checker.
|
||||
*/
|
||||
public boolean isInputMethodSuppressingSpellChecker() {
|
||||
synchronized (mH) {
|
||||
return mIsInputMethodSuppressingSpellChecker;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all of the state associated with being bound to an input method.
|
||||
*/
|
||||
@@ -1513,6 +1531,7 @@ public final class InputMethodManager {
|
||||
@UnsupportedAppUsage
|
||||
void finishInputLocked() {
|
||||
mActivityViewToScreenMatrix = null;
|
||||
mIsInputMethodSuppressingSpellChecker = false;
|
||||
setNextServedViewLocked(null);
|
||||
if (getServedViewLocked() != null) {
|
||||
if (DEBUG) {
|
||||
@@ -2037,6 +2056,7 @@ public final class InputMethodManager {
|
||||
return false;
|
||||
}
|
||||
mActivityViewToScreenMatrix = res.getActivityViewToScreenMatrix();
|
||||
mIsInputMethodSuppressingSpellChecker = res.isInputMethodSuppressingSpellChecker;
|
||||
if (res.id != null) {
|
||||
setInputChannelLocked(res.channel);
|
||||
mBindSequence = res.sequence;
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.os.Message;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import com.android.internal.textservice.ISpellCheckerSession;
|
||||
import com.android.internal.textservice.ISpellCheckerSessionListener;
|
||||
@@ -176,6 +177,11 @@ public class SpellCheckerSession {
|
||||
* @param suggestionsLimit the maximum number of suggestions that will be returned
|
||||
*/
|
||||
public void getSentenceSuggestions(TextInfo[] textInfos, int suggestionsLimit) {
|
||||
final InputMethodManager imm = mTextServicesManager.getInputMethodManager();
|
||||
if (imm != null && imm.isInputMethodSuppressingSpellChecker()) {
|
||||
handleOnGetSentenceSuggestionsMultiple(new SentenceSuggestionsInfo[0]);
|
||||
return;
|
||||
}
|
||||
mSpellCheckerSessionListenerImpl.getSentenceSuggestionsMultiple(
|
||||
textInfos, suggestionsLimit);
|
||||
}
|
||||
@@ -204,6 +210,11 @@ public class SpellCheckerSession {
|
||||
if (DBG) {
|
||||
Log.w(TAG, "getSuggestions from " + mSpellCheckerInfo.getId());
|
||||
}
|
||||
final InputMethodManager imm = mTextServicesManager.getInputMethodManager();
|
||||
if (imm != null && imm.isInputMethodSuppressingSpellChecker()) {
|
||||
handleOnGetSuggestionsMultiple(new SuggestionsInfo[0]);
|
||||
return;
|
||||
}
|
||||
mSpellCheckerSessionListenerImpl.getSuggestionsMultiple(
|
||||
textInfos, suggestionsLimit, sequentialWords);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.os.ServiceManager;
|
||||
import android.os.ServiceManager.ServiceNotFoundException;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener;
|
||||
|
||||
import com.android.internal.textservice.ISpellCheckerSessionListener;
|
||||
@@ -88,10 +89,15 @@ public final class TextServicesManager {
|
||||
@UserIdInt
|
||||
private final int mUserId;
|
||||
|
||||
private TextServicesManager(@UserIdInt int userId) throws ServiceNotFoundException {
|
||||
@Nullable
|
||||
private final InputMethodManager mInputMethodManager;
|
||||
|
||||
private TextServicesManager(@UserIdInt int userId,
|
||||
@Nullable InputMethodManager inputMethodManager) throws ServiceNotFoundException {
|
||||
mService = ITextServicesManager.Stub.asInterface(
|
||||
ServiceManager.getServiceOrThrow(Context.TEXT_SERVICES_MANAGER_SERVICE));
|
||||
mUserId = userId;
|
||||
mInputMethodManager = inputMethodManager;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,7 +111,8 @@ public final class TextServicesManager {
|
||||
@NonNull
|
||||
public static TextServicesManager createInstance(@NonNull Context context)
|
||||
throws ServiceNotFoundException {
|
||||
return new TextServicesManager(context.getUserId());
|
||||
return new TextServicesManager(context.getUserId(), context.getSystemService(
|
||||
InputMethodManager.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,7 +125,7 @@ public final class TextServicesManager {
|
||||
synchronized (TextServicesManager.class) {
|
||||
if (sInstance == null) {
|
||||
try {
|
||||
sInstance = new TextServicesManager(UserHandle.myUserId());
|
||||
sInstance = new TextServicesManager(UserHandle.myUserId(), null);
|
||||
} catch (ServiceNotFoundException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
@@ -127,6 +134,12 @@ public final class TextServicesManager {
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Nullable
|
||||
public InputMethodManager getInputMethodManager() {
|
||||
return mInputMethodManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language component of a given locale string.
|
||||
*/
|
||||
|
||||
@@ -988,6 +988,12 @@ public class Editor {
|
||||
|
||||
if (mTextView.isTextEditable() && mTextView.isSuggestionsEnabled()
|
||||
&& !(mTextView.isInExtractedMode())) {
|
||||
final InputMethodManager imm = getInputMethodManager();
|
||||
if (imm != null && imm.isInputMethodSuppressingSpellChecker()) {
|
||||
// Do not close mSpellChecker here as it may be reused when the current IME has been
|
||||
// changed.
|
||||
return;
|
||||
}
|
||||
if (mSpellChecker == null && createSpellChecker) {
|
||||
mSpellChecker = new SpellChecker(mTextView);
|
||||
}
|
||||
|
||||
@@ -204,6 +204,8 @@ public final class InputBindResult implements Parcelable {
|
||||
@Nullable
|
||||
private final float[] mActivityViewToScreenMatrixValues;
|
||||
|
||||
public final boolean isInputMethodSuppressingSpellChecker;
|
||||
|
||||
/**
|
||||
* @return {@link Matrix} that corresponds to {@link #mActivityViewToScreenMatrixValues}.
|
||||
* {@code null} if {@link #mActivityViewToScreenMatrixValues} is {@code null}.
|
||||
@@ -220,7 +222,8 @@ public final class InputBindResult implements Parcelable {
|
||||
|
||||
public InputBindResult(@ResultCode int _result,
|
||||
IInputMethodSession _method, InputChannel _channel, String _id, int _sequence,
|
||||
@Nullable Matrix activityViewToScreenMatrix) {
|
||||
@Nullable Matrix activityViewToScreenMatrix,
|
||||
boolean isInputMethodSuppressingSpellChecker) {
|
||||
result = _result;
|
||||
method = _method;
|
||||
channel = _channel;
|
||||
@@ -232,6 +235,7 @@ public final class InputBindResult implements Parcelable {
|
||||
mActivityViewToScreenMatrixValues = new float[9];
|
||||
activityViewToScreenMatrix.getValues(mActivityViewToScreenMatrixValues);
|
||||
}
|
||||
this.isInputMethodSuppressingSpellChecker = isInputMethodSuppressingSpellChecker;
|
||||
}
|
||||
|
||||
InputBindResult(Parcel source) {
|
||||
@@ -245,6 +249,7 @@ public final class InputBindResult implements Parcelable {
|
||||
id = source.readString();
|
||||
sequence = source.readInt();
|
||||
mActivityViewToScreenMatrixValues = source.createFloatArray();
|
||||
isInputMethodSuppressingSpellChecker = source.readBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -252,6 +257,7 @@ public final class InputBindResult implements Parcelable {
|
||||
return "InputBindResult{result=" + getResultString() + " method="+ method + " id=" + id
|
||||
+ " sequence=" + sequence
|
||||
+ " activityViewToScreenMatrix=" + getActivityViewToScreenMatrix()
|
||||
+ " isInputMethodSuppressingSpellChecker=" + isInputMethodSuppressingSpellChecker
|
||||
+ "}";
|
||||
}
|
||||
|
||||
@@ -274,6 +280,7 @@ public final class InputBindResult implements Parcelable {
|
||||
dest.writeString(id);
|
||||
dest.writeInt(sequence);
|
||||
dest.writeFloatArray(mActivityViewToScreenMatrixValues);
|
||||
dest.writeBoolean(isInputMethodSuppressingSpellChecker);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -340,7 +347,7 @@ public final class InputBindResult implements Parcelable {
|
||||
}
|
||||
|
||||
private static InputBindResult error(@ResultCode int result) {
|
||||
return new InputBindResult(result, null, null, null, -1, null);
|
||||
return new InputBindResult(result, null, null, null, -1, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3564,6 +3564,7 @@
|
||||
<attr name="__removed2" format="boolean" />
|
||||
<!-- Specifies whether the IME supports showing inline suggestions. -->
|
||||
<attr name="supportsInlineSuggestions" format="boolean" />
|
||||
<attr name="suppressesSpellChecker" format="boolean" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- This is the subtype of InputMethod. Subtype can describe locales (for example, en_US and
|
||||
|
||||
@@ -3088,6 +3088,7 @@
|
||||
<public name="selectableAsDefault"/>
|
||||
<public name="isAccessibilityTool"/>
|
||||
<public name="attributionTags"/>
|
||||
<public name="suppressesSpellChecker" />
|
||||
</public-group>
|
||||
|
||||
<public-group type="drawable" first-id="0x010800b5">
|
||||
|
||||
@@ -2381,9 +2381,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
showCurrentInputLocked(mCurFocusedWindow, getAppShowFlags(), null,
|
||||
SoftInputShowHideReason.ATTACH_NEW_INPUT);
|
||||
}
|
||||
final InputMethodInfo curInputMethodInfo = mMethodMap.get(mCurId);
|
||||
final boolean suppressesSpellChecker =
|
||||
curInputMethodInfo != null && curInputMethodInfo.suppressesSpellChecker();
|
||||
return new InputBindResult(InputBindResult.ResultCode.SUCCESS_WITH_IME_SESSION,
|
||||
session.session, (session.channel != null ? session.channel.dup() : null),
|
||||
mCurId, mCurSeq, mCurActivityViewToScreenMatrix);
|
||||
mCurId, mCurSeq, mCurActivityViewToScreenMatrix, suppressesSpellChecker);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -2425,7 +2428,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
// party code.
|
||||
return new InputBindResult(
|
||||
InputBindResult.ResultCode.ERROR_SYSTEM_NOT_READY,
|
||||
null, null, mCurMethodId, mCurSeq, null);
|
||||
null, null, mCurMethodId, mCurSeq, null, false);
|
||||
}
|
||||
|
||||
if (!InputMethodUtils.checkIfPackageBelongsToUid(mAppOpsManager, cs.uid,
|
||||
@@ -2501,7 +2504,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
requestClientSessionLocked(cs);
|
||||
return new InputBindResult(
|
||||
InputBindResult.ResultCode.SUCCESS_WAITING_IME_SESSION,
|
||||
null, null, mCurId, mCurSeq, null);
|
||||
null, null, mCurId, mCurSeq, null, false);
|
||||
} else if (SystemClock.uptimeMillis()
|
||||
< (mLastBindTime+TIME_TO_RECONNECT)) {
|
||||
// In this case we have connected to the service, but
|
||||
@@ -2513,7 +2516,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
// to see if we can get back in touch with the service.
|
||||
return new InputBindResult(
|
||||
InputBindResult.ResultCode.SUCCESS_WAITING_IME_BINDING,
|
||||
null, null, mCurId, mCurSeq, null);
|
||||
null, null, mCurId, mCurSeq, null, false);
|
||||
} else {
|
||||
EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME,
|
||||
mCurMethodId, SystemClock.uptimeMillis()-mLastBindTime, 0);
|
||||
@@ -2553,7 +2556,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
}
|
||||
return new InputBindResult(
|
||||
InputBindResult.ResultCode.SUCCESS_WAITING_IME_BINDING,
|
||||
null, null, mCurId, mCurSeq, null);
|
||||
null, null, mCurId, mCurSeq, null, false);
|
||||
}
|
||||
mCurIntent = null;
|
||||
Slog.w(TAG, "Failure connecting to input method service: " + mCurIntent);
|
||||
@@ -3509,7 +3512,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
}
|
||||
return new InputBindResult(
|
||||
InputBindResult.ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY,
|
||||
null, null, null, -1, null);
|
||||
null, null, null, -1, null, false);
|
||||
}
|
||||
|
||||
mCurFocusedWindow = windowToken;
|
||||
|
||||
@@ -1748,7 +1748,7 @@ public final class MultiClientInputMethodManagerService {
|
||||
return new InputBindResult(
|
||||
InputBindResult.ResultCode.SUCCESS_WAITING_IME_SESSION,
|
||||
null, null, data.mCurrentInputMethodInfo.getId(),
|
||||
clientInfo.mBindingSequence, null);
|
||||
clientInfo.mBindingSequence, null, false);
|
||||
case InputMethodClientState.READY_TO_SEND_FIRST_BIND_RESULT:
|
||||
case InputMethodClientState.ALREADY_SENT_BIND_RESULT:
|
||||
clientInfo.mBindingSequence++;
|
||||
@@ -1770,7 +1770,7 @@ public final class MultiClientInputMethodManagerService {
|
||||
clientInfo.mInputMethodSession,
|
||||
clientInfo.mWriteChannel.dup(),
|
||||
data.mCurrentInputMethodInfo.getId(),
|
||||
clientInfo.mBindingSequence, null);
|
||||
clientInfo.mBindingSequence, null, false);
|
||||
case InputMethodClientState.UNREGISTERED:
|
||||
Slog.e(TAG, "The client is already unregistered.");
|
||||
return InputBindResult.INVALID_CLIENT;
|
||||
|
||||
Reference in New Issue
Block a user