Refactor sentence level spell checking APIs
Support sentence level spell checking APIs: Step 1 Change-Id: I31c0b88e7885f33a0694ab60b8f2dbceeffe42f1
This commit is contained in:
@@ -27,6 +27,7 @@ import android.os.IBinder;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.textservice.SentenceSuggestionsInfo;
|
||||
import android.view.textservice.SuggestionsInfo;
|
||||
import android.view.textservice.TextInfo;
|
||||
|
||||
@@ -140,19 +141,21 @@ public abstract class SpellCheckerService extends Service {
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* The default implementation returns an array of SuggestionsInfo by simply calling
|
||||
* The default implementation returns an array of SentenceSuggestionsInfo by simply calling
|
||||
* onGetSuggestions().
|
||||
* When you override this method, make sure that suggestionsLimit is applied to suggestions
|
||||
* that share the same start position and length.
|
||||
*/
|
||||
public SuggestionsInfo[] onGetSuggestionsMultipleForSentence(TextInfo[] textInfos,
|
||||
public SentenceSuggestionsInfo[] onGetSentenceSuggestionsMultiple(TextInfo[] textInfos,
|
||||
int suggestionsLimit) {
|
||||
final int length = textInfos.length;
|
||||
final SuggestionsInfo[] retval = new SuggestionsInfo[length];
|
||||
final SentenceSuggestionsInfo[] retval = new SentenceSuggestionsInfo[length];
|
||||
for (int i = 0; i < length; ++i) {
|
||||
retval[i] = onGetSuggestions(textInfos[i], suggestionsLimit);
|
||||
retval[i].setCookieAndSequence(
|
||||
textInfos[i].getCookie(), textInfos[i].getSequence());
|
||||
final SuggestionsInfo si = onGetSuggestions(textInfos[i], suggestionsLimit);
|
||||
si.setCookieAndSequence(textInfos[i].getCookie(), textInfos[i].getSequence());
|
||||
final int N = textInfos[i].getText().length();
|
||||
retval[i] = new SentenceSuggestionsInfo(
|
||||
new SuggestionsInfo[] {si}, new int[]{0}, new int[]{N});
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
@@ -220,11 +223,10 @@ public abstract class SpellCheckerService extends Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetSuggestionsMultipleForSentence(
|
||||
TextInfo[] textInfos, int suggestionsLimit) {
|
||||
public void onGetSentenceSuggestionsMultiple(TextInfo[] textInfos, int suggestionsLimit) {
|
||||
try {
|
||||
mListener.onGetSuggestionsForSentence(
|
||||
mSession.onGetSuggestionsMultipleForSentence(textInfos, suggestionsLimit));
|
||||
mListener.onGetSentenceSuggestions(
|
||||
mSession.onGetSentenceSuggestionsMultiple(textInfos, suggestionsLimit));
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.view.textservice;
|
||||
|
||||
parcelable SentenceSuggestionsInfo;
|
||||
129
core/java/android/view/textservice/SentenceSuggestionsInfo.java
Normal file
129
core/java/android/view/textservice/SentenceSuggestionsInfo.java
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package android.view.textservice;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* This class contains a metadata of sentence level suggestions from the text service
|
||||
*/
|
||||
public final class SentenceSuggestionsInfo implements Parcelable {
|
||||
|
||||
private final SuggestionsInfo[] mSuggestionsInfos;
|
||||
private final int[] mOffsets;
|
||||
private final int[] mLengths;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param suggestionsInfos from the text service
|
||||
* @param offsets the array of offsets of suggestions
|
||||
* @param lengths the array of lengths of suggestions
|
||||
*/
|
||||
public SentenceSuggestionsInfo(
|
||||
SuggestionsInfo[] suggestionsInfos, int[] offsets, int[] lengths) {
|
||||
if (suggestionsInfos == null || offsets == null || lengths == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (suggestionsInfos.length != offsets.length || offsets.length != lengths.length) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
final int infoSize = suggestionsInfos.length;
|
||||
mSuggestionsInfos = Arrays.copyOf(suggestionsInfos, infoSize);
|
||||
mOffsets = Arrays.copyOf(offsets, infoSize);
|
||||
mLengths = Arrays.copyOf(lengths, infoSize);
|
||||
}
|
||||
|
||||
public SentenceSuggestionsInfo(Parcel source) {
|
||||
final int infoSize = source.readInt();
|
||||
mSuggestionsInfos = new SuggestionsInfo[infoSize];
|
||||
source.readTypedArray(mSuggestionsInfos, SuggestionsInfo.CREATOR);
|
||||
mOffsets = new int[mSuggestionsInfos.length];
|
||||
source.readIntArray(mOffsets);
|
||||
mLengths = new int[mSuggestionsInfos.length];
|
||||
source.readIntArray(mLengths);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to package this object into a {@link Parcel}.
|
||||
*
|
||||
* @param dest The {@link Parcel} to be written.
|
||||
* @param flags The flags used for parceling.
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
final int infoSize = mSuggestionsInfos.length;
|
||||
dest.writeInt(infoSize);
|
||||
dest.writeTypedArray(mSuggestionsInfos, 0);
|
||||
dest.writeIntArray(mOffsets);
|
||||
dest.writeIntArray(mLengths);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public SuggestionsInfo getSuggestionsInfoAt(int i) {
|
||||
if (i >= 0 && i < mSuggestionsInfos.length) {
|
||||
return mSuggestionsInfos[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public int getOffsetAt(int i) {
|
||||
if (i >= 0 && i < mOffsets.length) {
|
||||
return mOffsets[i];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public int getLengthAt(int i) {
|
||||
if (i >= 0 && i < mLengths.length) {
|
||||
return mLengths[i];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to make this class parcelable.
|
||||
*/
|
||||
public static final Parcelable.Creator<SentenceSuggestionsInfo> CREATOR
|
||||
= new Parcelable.Creator<SentenceSuggestionsInfo>() {
|
||||
@Override
|
||||
public SentenceSuggestionsInfo createFromParcel(Parcel source) {
|
||||
return new SentenceSuggestionsInfo(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SentenceSuggestionsInfo[] newArray(int size) {
|
||||
return new SentenceSuggestionsInfo[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -115,7 +115,7 @@ public class SpellCheckerSession {
|
||||
handleOnGetSuggestionsMultiple((SuggestionsInfo[]) msg.obj);
|
||||
break;
|
||||
case MSG_ON_GET_SUGGESTION_MULTIPLE_FOR_SENTENCE:
|
||||
handleOnGetSuggestionsMultipleForSentence((SuggestionsInfo[]) msg.obj);
|
||||
handleOnGetSentenceSuggestionsMultiple((SentenceSuggestionsInfo[]) msg.obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -180,8 +180,8 @@ public class SpellCheckerSession {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void getSuggestionsForSentence(TextInfo textInfo, int suggestionsLimit) {
|
||||
mSpellCheckerSessionListenerImpl.getSuggestionsMultipleForSentence(
|
||||
public void getSentenceSuggestions(TextInfo textInfo, int suggestionsLimit) {
|
||||
mSpellCheckerSessionListenerImpl.getSentenceSuggestionsMultiple(
|
||||
new TextInfo[] {textInfo}, suggestionsLimit);
|
||||
}
|
||||
|
||||
@@ -214,8 +214,8 @@ public class SpellCheckerSession {
|
||||
mSpellCheckerSessionListener.onGetSuggestions(suggestionInfos);
|
||||
}
|
||||
|
||||
private void handleOnGetSuggestionsMultipleForSentence(SuggestionsInfo[] suggestionInfos) {
|
||||
mSpellCheckerSessionListener.onGetSuggestionsForSentence(suggestionInfos);
|
||||
private void handleOnGetSentenceSuggestionsMultiple(SentenceSuggestionsInfo[] suggestionInfos) {
|
||||
mSpellCheckerSessionListener.onGetSentenceSuggestions(suggestionInfos);
|
||||
}
|
||||
|
||||
private static class SpellCheckerSessionListenerImpl extends ISpellCheckerSessionListener.Stub {
|
||||
@@ -285,7 +285,7 @@ public class SpellCheckerSession {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
try {
|
||||
session.onGetSuggestionsMultipleForSentence(
|
||||
session.onGetSentenceSuggestionsMultiple(
|
||||
scp.mTextInfos, scp.mSuggestionsLimit);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to get suggestions " + e);
|
||||
@@ -366,9 +366,9 @@ public class SpellCheckerSession {
|
||||
suggestionsLimit, sequentialWords));
|
||||
}
|
||||
|
||||
public void getSuggestionsMultipleForSentence(TextInfo[] textInfos, int suggestionsLimit) {
|
||||
public void getSentenceSuggestionsMultiple(TextInfo[] textInfos, int suggestionsLimit) {
|
||||
if (DBG) {
|
||||
Log.w(TAG, "getSuggestionsMultipleForSentence");
|
||||
Log.w(TAG, "getSentenceSuggestionsMultiple");
|
||||
}
|
||||
processOrEnqueueTask(
|
||||
new SpellCheckerParams(TASK_GET_SUGGESTIONS_MULTIPLE_FOR_SENTENCE,
|
||||
@@ -399,8 +399,8 @@ public class SpellCheckerSession {
|
||||
while (!mPendingTasks.isEmpty()) {
|
||||
final SpellCheckerParams tmp = mPendingTasks.poll();
|
||||
if (tmp.mWhat == TASK_CLOSE) {
|
||||
// Only one close task should be processed, while we need to remove all
|
||||
// close tasks from the queue
|
||||
// Only one close task should be processed, while we need to remove
|
||||
// all close tasks from the queue
|
||||
closeTask = tmp;
|
||||
}
|
||||
}
|
||||
@@ -426,7 +426,7 @@ public class SpellCheckerSession {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetSuggestionsForSentence(SuggestionsInfo[] results) {
|
||||
public void onGetSentenceSuggestions(SentenceSuggestionsInfo[] results) {
|
||||
mHandler.sendMessage(
|
||||
Message.obtain(mHandler, MSG_ON_GET_SUGGESTION_MULTIPLE_FOR_SENTENCE, results));
|
||||
}
|
||||
@@ -444,7 +444,7 @@ public class SpellCheckerSession {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void onGetSuggestionsForSentence(SuggestionsInfo[] results);
|
||||
public void onGetSentenceSuggestions(SentenceSuggestionsInfo[] results);
|
||||
}
|
||||
|
||||
private static class InternalListener extends ITextServicesSessionListener.Stub {
|
||||
|
||||
@@ -21,14 +21,11 @@ import com.android.internal.util.ArrayUtils;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
private static final int NOT_A_LENGTH = -1;
|
||||
|
||||
/**
|
||||
* Flag of the attributes of the suggestions that can be obtained by
|
||||
@@ -50,8 +47,6 @@ public final class SuggestionsInfo implements Parcelable {
|
||||
public static final int RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS = 0x0004;
|
||||
private final int mSuggestionsAttributes;
|
||||
private final String[] mSuggestions;
|
||||
private final int[] mStartPosArray;
|
||||
private final int[] mLengthArray;
|
||||
private final boolean mSuggestionsAvailable;
|
||||
private int mCookie;
|
||||
private int mSequence;
|
||||
@@ -74,46 +69,12 @@ public final class SuggestionsInfo implements Parcelable {
|
||||
*/
|
||||
public SuggestionsInfo(
|
||||
int suggestionsAttributes, String[] suggestions, int cookie, int sequence) {
|
||||
this(suggestionsAttributes, suggestions, cookie, sequence, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Constructor.
|
||||
* @param suggestionsAttributes from the text service
|
||||
* @param suggestions from the text service
|
||||
* @param cookie the cookie of the input TextInfo
|
||||
* @param sequence the cookie of the input TextInfo
|
||||
* @param startPosArray the array of start positions of suggestions
|
||||
* @param lengthArray the array of length of suggestions
|
||||
*/
|
||||
public SuggestionsInfo(
|
||||
int suggestionsAttributes, String[] suggestions, int cookie, int sequence,
|
||||
int[] startPosArray, int[] lengthArray) {
|
||||
final int suggestsLen;
|
||||
if (suggestions == null) {
|
||||
mSuggestions = EMPTY;
|
||||
mSuggestionsAvailable = false;
|
||||
suggestsLen = 0;
|
||||
mStartPosArray = new int[0];
|
||||
mLengthArray = new int[0];
|
||||
} else {
|
||||
mSuggestions = suggestions;
|
||||
mSuggestionsAvailable = true;
|
||||
suggestsLen = suggestions.length;
|
||||
if (startPosArray == null || lengthArray == null) {
|
||||
mStartPosArray = new int[suggestsLen];
|
||||
mLengthArray = new int[suggestsLen];
|
||||
for (int i = 0; i < suggestsLen; ++i) {
|
||||
mStartPosArray[i] = 0;
|
||||
mLengthArray[i] = NOT_A_LENGTH;
|
||||
}
|
||||
} else if (suggestsLen != startPosArray.length || suggestsLen != lengthArray.length) {
|
||||
throw new IllegalArgumentException();
|
||||
} else {
|
||||
mStartPosArray = Arrays.copyOf(startPosArray, suggestsLen);
|
||||
mLengthArray = Arrays.copyOf(lengthArray, suggestsLen);
|
||||
}
|
||||
}
|
||||
mSuggestionsAttributes = suggestionsAttributes;
|
||||
mCookie = cookie;
|
||||
@@ -126,10 +87,6 @@ public final class SuggestionsInfo implements Parcelable {
|
||||
mCookie = source.readInt();
|
||||
mSequence = source.readInt();
|
||||
mSuggestionsAvailable = source.readInt() == 1;
|
||||
mStartPosArray = new int[mSuggestions.length];
|
||||
mLengthArray = new int[mSuggestions.length];
|
||||
source.readIntArray(mStartPosArray);
|
||||
source.readIntArray(mLengthArray);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,8 +102,6 @@ public final class SuggestionsInfo implements Parcelable {
|
||||
dest.writeInt(mCookie);
|
||||
dest.writeInt(mSequence);
|
||||
dest.writeInt(mSuggestionsAvailable ? 1 : 0);
|
||||
dest.writeIntArray(mStartPosArray);
|
||||
dest.writeIntArray(mLengthArray);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,24 +182,4 @@ public final class SuggestionsInfo implements Parcelable {
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public int getSuggestionStartPosAt(int i) {
|
||||
if (i >= 0 && i < mStartPosArray.length) {
|
||||
return mStartPosArray[i];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public int getSuggestionLengthAt(int i) {
|
||||
if (i >= 0 && i < mLengthArray.length) {
|
||||
return mLengthArray[i];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.text.Spanned;
|
||||
import android.text.method.WordIterator;
|
||||
import android.text.style.SpellCheckSpan;
|
||||
import android.text.style.SuggestionSpan;
|
||||
import android.view.textservice.SentenceSuggestionsInfo;
|
||||
import android.view.textservice.SpellCheckerSession;
|
||||
import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener;
|
||||
import android.view.textservice.SuggestionsInfo;
|
||||
@@ -277,9 +278,9 @@ public class SpellChecker implements SpellCheckerSessionListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetSuggestionsForSentence(SuggestionsInfo[] results) {
|
||||
public void onGetSentenceSuggestions(SentenceSuggestionsInfo[] results) {
|
||||
// TODO: Handle the position and length for each suggestion
|
||||
onGetSuggestions(results);
|
||||
// do nothing for now
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,7 +24,7 @@ import android.view.textservice.TextInfo;
|
||||
oneway interface ISpellCheckerSession {
|
||||
void onGetSuggestionsMultiple(
|
||||
in TextInfo[] textInfos, int suggestionsLimit, boolean multipleWords);
|
||||
void onGetSuggestionsMultipleForSentence(in TextInfo[] textInfos, int suggestionsLimit);
|
||||
void onGetSentenceSuggestionsMultiple(in TextInfo[] textInfos, int suggestionsLimit);
|
||||
void onCancel();
|
||||
void onClose();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.internal.textservice;
|
||||
|
||||
import android.view.textservice.SentenceSuggestionsInfo;
|
||||
import android.view.textservice.SuggestionsInfo;
|
||||
|
||||
/**
|
||||
@@ -23,5 +24,5 @@ import android.view.textservice.SuggestionsInfo;
|
||||
*/
|
||||
oneway interface ISpellCheckerSessionListener {
|
||||
void onGetSuggestions(in SuggestionsInfo[] results);
|
||||
void onGetSuggestionsForSentence(in SuggestionsInfo[] results);
|
||||
void onGetSentenceSuggestions(in SentenceSuggestionsInfo[] result);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user