aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java
diff options
context:
space:
mode:
authorAmin Bandali <bandali@kelar.org>2024-12-16 21:45:41 -0500
committerAmin Bandali <bandali@kelar.org>2025-01-11 14:17:35 -0500
commite9a0e66716dab4dd3184d009d8920de1961efdfa (patch)
tree02dcc096643d74645bf28459c2834c3d4a2ad7f2 /java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java
parentfb3b9360d70596d7e921de8bf7d3ca99564a077e (diff)
downloadlatinime-e9a0e66716dab4dd3184d009d8920de1961efdfa.tar.gz
latinime-e9a0e66716dab4dd3184d009d8920de1961efdfa.tar.xz
latinime-e9a0e66716dab4dd3184d009d8920de1961efdfa.zip
Rename to Kelar Keyboard (org.kelar.inputmethod.latin)
Diffstat (limited to 'java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java')
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java225
1 files changed, 0 insertions, 225 deletions
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java
deleted file mode 100644
index c7622e7a1..000000000
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * 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 com.android.inputmethod.latin.spellcheck;
-
-import android.annotation.TargetApi;
-import android.content.res.Resources;
-import android.os.Binder;
-import android.os.Build;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.textservice.SentenceSuggestionsInfo;
-import android.view.textservice.SuggestionsInfo;
-import android.view.textservice.TextInfo;
-
-import com.android.inputmethod.compat.TextInfoCompatUtils;
-import com.android.inputmethod.latin.NgramContext;
-import com.android.inputmethod.latin.utils.SpannableStringUtils;
-
-import java.util.ArrayList;
-import java.util.Locale;
-
-public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheckerSession {
- private static final String TAG = AndroidSpellCheckerSession.class.getSimpleName();
- private static final boolean DBG = false;
- private final Resources mResources;
- private SentenceLevelAdapter mSentenceLevelAdapter;
-
- public AndroidSpellCheckerSession(AndroidSpellCheckerService service) {
- super(service);
- mResources = service.getResources();
- }
-
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
- private SentenceSuggestionsInfo fixWronglyInvalidatedWordWithSingleQuote(TextInfo ti,
- SentenceSuggestionsInfo ssi) {
- final CharSequence typedText = TextInfoCompatUtils.getCharSequenceOrString(ti);
- if (!typedText.toString().contains(AndroidSpellCheckerService.SINGLE_QUOTE)) {
- return null;
- }
- final int N = ssi.getSuggestionsCount();
- final ArrayList<Integer> additionalOffsets = new ArrayList<>();
- final ArrayList<Integer> additionalLengths = new ArrayList<>();
- final ArrayList<SuggestionsInfo> additionalSuggestionsInfos = new ArrayList<>();
- CharSequence currentWord = null;
- for (int i = 0; i < N; ++i) {
- final SuggestionsInfo si = ssi.getSuggestionsInfoAt(i);
- final int flags = si.getSuggestionsAttributes();
- if ((flags & SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY) == 0) {
- continue;
- }
- final int offset = ssi.getOffsetAt(i);
- final int length = ssi.getLengthAt(i);
- final CharSequence subText = typedText.subSequence(offset, offset + length);
- final NgramContext ngramContext =
- new NgramContext(new NgramContext.WordInfo(currentWord));
- currentWord = subText;
- if (!subText.toString().contains(AndroidSpellCheckerService.SINGLE_QUOTE)) {
- continue;
- }
- // Split preserving spans.
- final CharSequence[] splitTexts = SpannableStringUtils.split(subText,
- AndroidSpellCheckerService.SINGLE_QUOTE,
- true /* preserveTrailingEmptySegments */);
- if (splitTexts == null || splitTexts.length <= 1) {
- continue;
- }
- final int splitNum = splitTexts.length;
- for (int j = 0; j < splitNum; ++j) {
- final CharSequence splitText = splitTexts[j];
- if (TextUtils.isEmpty(splitText)) {
- continue;
- }
- if (mSuggestionsCache.getSuggestionsFromCache(splitText.toString()) == null) {
- continue;
- }
- final int newLength = splitText.length();
- // Neither RESULT_ATTR_IN_THE_DICTIONARY nor RESULT_ATTR_LOOKS_LIKE_TYPO
- final int newFlags = 0;
- final SuggestionsInfo newSi = new SuggestionsInfo(newFlags, EMPTY_STRING_ARRAY);
- newSi.setCookieAndSequence(si.getCookie(), si.getSequence());
- if (DBG) {
- Log.d(TAG, "Override and remove old span over: " + splitText + ", "
- + offset + "," + newLength);
- }
- additionalOffsets.add(offset);
- additionalLengths.add(newLength);
- additionalSuggestionsInfos.add(newSi);
- }
- }
- final int additionalSize = additionalOffsets.size();
- if (additionalSize <= 0) {
- return null;
- }
- final int suggestionsSize = N + additionalSize;
- final int[] newOffsets = new int[suggestionsSize];
- final int[] newLengths = new int[suggestionsSize];
- final SuggestionsInfo[] newSuggestionsInfos = new SuggestionsInfo[suggestionsSize];
- int i;
- for (i = 0; i < N; ++i) {
- newOffsets[i] = ssi.getOffsetAt(i);
- newLengths[i] = ssi.getLengthAt(i);
- newSuggestionsInfos[i] = ssi.getSuggestionsInfoAt(i);
- }
- for (; i < suggestionsSize; ++i) {
- newOffsets[i] = additionalOffsets.get(i - N);
- newLengths[i] = additionalLengths.get(i - N);
- newSuggestionsInfos[i] = additionalSuggestionsInfos.get(i - N);
- }
- return new SentenceSuggestionsInfo(newSuggestionsInfos, newOffsets, newLengths);
- }
-
- @Override
- public SentenceSuggestionsInfo[] onGetSentenceSuggestionsMultiple(TextInfo[] textInfos,
- int suggestionsLimit) {
- final SentenceSuggestionsInfo[] retval = splitAndSuggest(textInfos, suggestionsLimit);
- if (retval == null || retval.length != textInfos.length) {
- return retval;
- }
- for (int i = 0; i < retval.length; ++i) {
- final SentenceSuggestionsInfo tempSsi =
- fixWronglyInvalidatedWordWithSingleQuote(textInfos[i], retval[i]);
- if (tempSsi != null) {
- retval[i] = tempSsi;
- }
- }
- return retval;
- }
-
- /**
- * Get sentence suggestions for specified texts in an array of TextInfo. This is taken from
- * SpellCheckerService#onGetSentenceSuggestionsMultiple that we can't use because it's
- * using private variables.
- * The default implementation splits the input text to words and returns
- * {@link SentenceSuggestionsInfo} which contains suggestions for each word.
- * This function will run on the incoming IPC thread.
- * So, this is not called on the main thread,
- * but will be called in series on another thread.
- * @param textInfos an array of the text metadata
- * @param suggestionsLimit the maximum number of suggestions to be returned
- * @return an array of {@link SentenceSuggestionsInfo} returned by
- * {@link android.service.textservice.SpellCheckerService.Session#onGetSuggestions(TextInfo, int)}
- */
- private SentenceSuggestionsInfo[] splitAndSuggest(TextInfo[] textInfos, int suggestionsLimit) {
- if (textInfos == null || textInfos.length == 0) {
- return SentenceLevelAdapter.getEmptySentenceSuggestionsInfo();
- }
- SentenceLevelAdapter sentenceLevelAdapter;
- synchronized(this) {
- sentenceLevelAdapter = mSentenceLevelAdapter;
- if (sentenceLevelAdapter == null) {
- final String localeStr = getLocale();
- if (!TextUtils.isEmpty(localeStr)) {
- sentenceLevelAdapter = new SentenceLevelAdapter(mResources,
- new Locale(localeStr));
- mSentenceLevelAdapter = sentenceLevelAdapter;
- }
- }
- }
- if (sentenceLevelAdapter == null) {
- return SentenceLevelAdapter.getEmptySentenceSuggestionsInfo();
- }
- final int infosSize = textInfos.length;
- final SentenceSuggestionsInfo[] retval = new SentenceSuggestionsInfo[infosSize];
- for (int i = 0; i < infosSize; ++i) {
- final SentenceLevelAdapter.SentenceTextInfoParams textInfoParams =
- sentenceLevelAdapter.getSplitWords(textInfos[i]);
- final ArrayList<SentenceLevelAdapter.SentenceWordItem> mItems =
- textInfoParams.mItems;
- final int itemsSize = mItems.size();
- final TextInfo[] splitTextInfos = new TextInfo[itemsSize];
- for (int j = 0; j < itemsSize; ++j) {
- splitTextInfos[j] = mItems.get(j).mTextInfo;
- }
- retval[i] = SentenceLevelAdapter.reconstructSuggestions(
- textInfoParams, onGetSuggestionsMultiple(
- splitTextInfos, suggestionsLimit, true));
- }
- return retval;
- }
-
- @Override
- public SuggestionsInfo[] onGetSuggestionsMultiple(TextInfo[] textInfos,
- int suggestionsLimit, boolean sequentialWords) {
- long ident = Binder.clearCallingIdentity();
- try {
- final int length = textInfos.length;
- final SuggestionsInfo[] retval = new SuggestionsInfo[length];
- for (int i = 0; i < length; ++i) {
- final CharSequence prevWord;
- if (sequentialWords && i > 0) {
- final TextInfo prevTextInfo = textInfos[i - 1];
- final CharSequence prevWordCandidate =
- TextInfoCompatUtils.getCharSequenceOrString(prevTextInfo);
- // Note that an empty string would be used to indicate the initial word
- // in the future.
- prevWord = TextUtils.isEmpty(prevWordCandidate) ? null : prevWordCandidate;
- } else {
- prevWord = null;
- }
- final NgramContext ngramContext =
- new NgramContext(new NgramContext.WordInfo(prevWord));
- final TextInfo textInfo = textInfos[i];
- retval[i] = onGetSuggestionsInternal(textInfo, ngramContext, suggestionsLimit);
- retval[i].setCookieAndSequence(textInfo.getCookie(), textInfo.getSequence());
- }
- return retval;
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-}