Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d404fe11 authored by satok's avatar satok
Browse files

Refactor sentence level spell checking APIs

Support sentence level spell checking APIs: Step 1

Change-Id: I31c0b88e7885f33a0694ab60b8f2dbceeffe42f1
parent 30c46ad5
Loading
Loading
Loading
Loading
+12 −10
Original line number Diff line number Diff line
@@ -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) {
            }
        }
+19 −0
Original line number Diff line number Diff line
/*
 * 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 −0
Original line number Diff line number Diff line
/*
 * 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];
        }
    };
}
+12 −12
Original line number Diff line number Diff line
@@ -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 {
+0 −65
Original line number Diff line number Diff line
@@ -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;
    }
}
Loading