diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin')
-rw-r--r-- | java/src/com/android/inputmethod/latin/BinaryDictionary.java | 13 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/DictionaryFactory.java | 8 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java | 2 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/LatinIME.java | 20 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/RichInputConnection.java | 15 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/Settings.java | 4 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/SubtypeLocale.java | 4 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java | 58 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/utils/DebugLogUtils.java (renamed from java/src/com/android/inputmethod/latin/utils/LogUtils.java) | 4 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java | 134 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/utils/Utils.java | 136 |
11 files changed, 211 insertions, 187 deletions
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 05b1a2ee1..f36c9e878 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -78,20 +78,23 @@ public final class BinaryDictionary extends Dictionary { * @param length the length of the binary data. * @param useFullEditDistance whether to use the full edit distance in suggestions * @param dictType the dictionary type, as a human-readable string + * @param isUpdatable whether to open the dictionary file in writable mode. */ public BinaryDictionary(final String filename, final long offset, final long length, - final boolean useFullEditDistance, final Locale locale, final String dictType) { + final boolean useFullEditDistance, final Locale locale, final String dictType, + final boolean isUpdatable) { super(dictType); mLocale = locale; mNativeSuggestOptions.setUseFullEditDistance(useFullEditDistance); - loadDictionary(filename, offset, length); + loadDictionary(filename, offset, length, isUpdatable); } static { JniUtils.loadNativeLibrary(); } - private static native long openNative(String sourceDir, long dictOffset, long dictSize); + private static native long openNative(String sourceDir, long dictOffset, long dictSize, + boolean isUpdatable); private static native void closeNative(long dict); private static native int getProbabilityNative(long dict, int[] word); private static native boolean isValidBigramNative(long dict, int[] word1, int[] word2); @@ -105,8 +108,8 @@ public final class BinaryDictionary extends Dictionary { // TODO: Move native dict into session private final void loadDictionary(final String path, final long startOffset, - final long length) { - mNativeDict = openNative(path, startOffset, length); + final long length, final boolean isUpdatable) { + mNativeDict = openNative(path, startOffset, length, isUpdatable); } @Override diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java index 5b98613a4..3721132c5 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java @@ -60,7 +60,8 @@ public final class DictionaryFactory { if (null != assetFileList) { for (final AssetFileAddress f : assetFileList) { final BinaryDictionary binaryDictionary = new BinaryDictionary(f.mFilename, - f.mOffset, f.mLength, useFullEditDistance, locale, Dictionary.TYPE_MAIN); + f.mOffset, f.mLength, useFullEditDistance, locale, Dictionary.TYPE_MAIN, + false /* isUpdatable */); if (binaryDictionary.isValidDictionary()) { dictList.add(binaryDictionary); } @@ -113,7 +114,8 @@ public final class DictionaryFactory { return null; } return new BinaryDictionary(sourceDir, afd.getStartOffset(), afd.getLength(), - false /* useFullEditDistance */, locale, Dictionary.TYPE_MAIN); + false /* useFullEditDistance */, locale, Dictionary.TYPE_MAIN, + false /* isUpdatable */); } catch (android.content.res.Resources.NotFoundException e) { Log.e(TAG, "Could not find the resource"); return null; @@ -142,7 +144,7 @@ public final class DictionaryFactory { for (final AssetFileAddress address : dictionaryList) { final BinaryDictionary binaryDictionary = new BinaryDictionary(address.mFilename, address.mOffset, address.mLength, useFullEditDistance, locale, - Dictionary.TYPE_MAIN); + Dictionary.TYPE_MAIN, false /* isUpdatable */); dictionaryCollection.addDictionary(binaryDictionary); } return dictionaryCollection; diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index f357e2a1e..9cdb86c2d 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -286,7 +286,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { // Build the new binary dictionary final BinaryDictionary newBinaryDictionary = new BinaryDictionary(filename, 0, length, - true /* useFullEditDistance */, null, mDictType); + true /* useFullEditDistance */, null, mDictType, false /* isUpdatable */); if (mBinaryDictionary != null) { // Ensure all threads accessing the current dictionary have finished before swapping in diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 0efe0eba7..6fcac9a65 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -926,19 +926,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } - // TODO: refactor the following code to be less contrived. - // "newSelStart != composingSpanEnd" || "newSelEnd != composingSpanEnd" means - // that the cursor is not at the end of the composing span, or there is a selection. - // "mLastSelectionStart != newSelStart" means that the cursor is not in the same place - // as last time we were called (if there is a selection, it means the start hasn't - // changed, so it's the end that did). - final boolean selectionChanged = (newSelStart != composingSpanEnd - || newSelEnd != composingSpanEnd) && mLastSelectionStart != newSelStart; + final boolean selectionChanged = mLastSelectionStart != newSelStart + || mLastSelectionEnd != newSelEnd; // if composingSpanStart and composingSpanEnd are -1, it means there is no composing // span in the view - we can use that to narrow down whether the cursor was moved // by us or not. If we are composing a word but there is no composing span, then // we know for sure the cursor moved while we were composing and we should reset - // the state. + // the state. TODO: rescind this policy: the framework never removes the composing + // span on its own accord while editing. This test is useless. + final boolean noComposingSpan = composingSpanStart == -1 && composingSpanEnd == -1; // If the keyboard is not visible, we don't need to do all the housekeeping work, as it // will be reset when the keyboard shows up anyway. @@ -979,6 +975,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (isSuggestionsStripVisible()) { mHandler.postResumeSuggestions(); } + mConnection.userMovedCursor(newSelEnd); // Reset the last recapitalization. mRecapitalizeStatus.deactivate(); mKeyboardSwitcher.updateShiftState(); @@ -2655,11 +2652,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } - // Used by the RingCharBuffer - public boolean isWordSeparator(final int code) { - return mSettings.getCurrent().isWordSeparator(code); - } - // TODO: Make this private // Outside LatinIME, only used by the {@link InputTestsBase} test suite. @UsedForTesting diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index d431ad60b..6e3e7b218 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -28,7 +28,7 @@ import android.view.inputmethod.InputConnection; import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.utils.CapsModeUtils; -import com.android.inputmethod.latin.utils.LogUtils; +import com.android.inputmethod.latin.utils.DebugLogUtils; import com.android.inputmethod.latin.utils.StringUtils; import com.android.inputmethod.research.ResearchLogger; @@ -107,7 +107,7 @@ public final class RichInputConnection { + "\nActual text = " + reference.length() + " " + reference; ((LatinIME)mParent).debugDumpStateAndCrashWithException(context); } else { - Log.e(TAG, LogUtils.getStackTrace(2)); + Log.e(TAG, DebugLogUtils.getStackTrace(2)); Log.e(TAG, "Exp <> Actual : " + mCurrentCursorPosition + " <> " + et.selectionStart); } } @@ -156,7 +156,7 @@ public final class RichInputConnection { if (mNestLevel != 1) { // TODO: exception instead Log.e(TAG, "Batch edit level incorrect : " + mNestLevel); - Log.e(TAG, LogUtils.getStackTrace(4)); + Log.e(TAG, DebugLogUtils.getStackTrace(4)); } } @@ -340,7 +340,6 @@ public final class RichInputConnection { public void setComposingRegion(final int start, final int end) { if (DEBUG_BATCH_NESTING) checkBatchEdit(); if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug(); - mCurrentCursorPosition = end; final CharSequence textBeforeCursor = getTextBeforeCursor(DEFAULT_TEXT_CACHE_SIZE + (end - start), 0); mCommittedTextBeforeComposingText.setLength(0); @@ -731,6 +730,14 @@ public final class RichInputConnection { } /** + * The user moved the cursor by hand. Take a note of it. + * @param newCursorPosition The new cursor position. + */ + public void userMovedCursor(final int newCursorPosition) { + mCurrentCursorPosition = newCursorPosition; + } + + /** * Looks at the text just before the cursor to find out if it looks like a URL. * * The weakest point here is, if we don't have enough text bufferized, we may fail to realize diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java index 084d3308c..adc92d021 100644 --- a/java/src/com/android/inputmethod/latin/Settings.java +++ b/java/src/com/android/inputmethod/latin/Settings.java @@ -152,6 +152,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang return mSettingsValues.mWordSeparators; } + public boolean isWordSeparator(final int code) { + return mSettingsValues.isWordSeparator(code); + } + public Locale getCurrentLocale() { return mCurrentLocale; } diff --git a/java/src/com/android/inputmethod/latin/SubtypeLocale.java b/java/src/com/android/inputmethod/latin/SubtypeLocale.java index 3f94aca3a..30df2eb4e 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeLocale.java +++ b/java/src/com/android/inputmethod/latin/SubtypeLocale.java @@ -26,9 +26,9 @@ import android.util.Log; import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.latin.utils.CollectionUtils; +import com.android.inputmethod.latin.utils.DebugLogUtils; import com.android.inputmethod.latin.utils.LocaleUtils; import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale; -import com.android.inputmethod.latin.utils.LogUtils; import com.android.inputmethod.latin.utils.StringUtils; import java.util.HashMap; @@ -242,7 +242,7 @@ public final class SubtypeLocale { + " nameResId=" + subtype.getNameResId() + " locale=" + subtype.getLocale() + " extra=" + subtype.getExtraValue() - + "\n" + LogUtils.getStackTrace()); + + "\n" + DebugLogUtils.getStackTrace()); return ""; } } diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java index b6caf9b7b..9565f63f7 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java @@ -86,6 +86,7 @@ final class SuggestionStripLayoutHelper { private final float mAlphaObsoleted; private final float mCenterSuggestionWeight; private final int mCenterPositionInStrip; + private final int mTypedWordPositionWhenAutocorrect; private final Drawable mMoreSuggestionsHint; private static final String MORE_SUGGESTIONS_HINT = "\u2026"; private static final String LEFTWARDS_ARROW = "\u2190"; @@ -159,6 +160,10 @@ final class SuggestionStripLayoutHelper { mMoreSuggestionsHint = getMoreSuggestionsHint(res, res.getDimension(R.dimen.more_suggestions_hint_text_size), mColorAutoCorrect); mCenterPositionInStrip = mSuggestionsCountInStrip / 2; + // Assuming there are at least three suggestions. Also, note that the suggestions are + // laid out according to script direction, so this is left of the center for LTR scripts + // and right of the center for RTL scripts. + mTypedWordPositionWhenAutocorrect = mCenterPositionInStrip - 1; mMoreSuggestionsBottomGap = res.getDimensionPixelOffset( R.dimen.more_suggestions_bottom_gap); mMoreSuggestionsRowHeight = res.getDimensionPixelSize(R.dimen.more_suggestions_row_height); @@ -233,24 +238,31 @@ final class SuggestionStripLayoutHelper { return spannedWord; } - private int getIndexInSuggestedWords(final int positionInStrip, + private int getPositionInSuggestionStrip(final int indexInSuggestedWords, final SuggestedWords suggestedWords) { - // TODO: This works for 3 suggestions. Revisit this algorithm when there are 5 or more - // suggestions. - final int mostImportantIndexInSuggestedWords = suggestedWords.willAutoCorrect() - ? SuggestedWords.INDEX_OF_AUTO_CORRECTION : SuggestedWords.INDEX_OF_TYPED_WORD; - if (positionInStrip == mCenterPositionInStrip) { - return mostImportantIndexInSuggestedWords; + final int indexToDisplayMostImportantSuggestion; + final int indexToDisplaySecondMostImportantSuggestion; + if (suggestedWords.willAutoCorrect()) { + indexToDisplayMostImportantSuggestion = SuggestedWords.INDEX_OF_AUTO_CORRECTION; + indexToDisplaySecondMostImportantSuggestion = SuggestedWords.INDEX_OF_TYPED_WORD; + } else { + indexToDisplayMostImportantSuggestion = SuggestedWords.INDEX_OF_TYPED_WORD; + indexToDisplaySecondMostImportantSuggestion = SuggestedWords.INDEX_OF_AUTO_CORRECTION; } - if (positionInStrip == mostImportantIndexInSuggestedWords) { + if (indexInSuggestedWords == indexToDisplayMostImportantSuggestion) { return mCenterPositionInStrip; } - return positionInStrip; + if (indexInSuggestedWords == indexToDisplaySecondMostImportantSuggestion) { + return mTypedWordPositionWhenAutocorrect; + } + // If neither of those, the order in the suggestion strip is the same as in SuggestedWords. + return indexInSuggestedWords; } - private int getSuggestionTextColor(final int positionInStrip, + private int getSuggestionTextColor(final int indexInSuggestedWords, final SuggestedWords suggestedWords) { - final int indexInSuggestedWords = getIndexInSuggestedWords(positionInStrip, suggestedWords); + final int positionInStrip = + getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords); // TODO: Need to revisit this logic with bigram suggestions final boolean isSuggested = (indexInSuggestedWords != SuggestedWords.INDEX_OF_TYPED_WORD); @@ -352,7 +364,7 @@ final class SuggestionStripLayoutHelper { * increase towards the right for LTR scripts and the left for RTL scripts, starting with 0. * The position of the most important suggestion is in {@link #mCenterPositionInStrip}. This * usually doesn't match the index in <code>suggedtedWords</code> -- see - * {@link #getIndexInSuggestedWords(int,SuggestedWords)}. + * {@link #getPositionInSuggestionStrip(int,SuggestedWords)}. * * @param positionInStrip the position in the suggestion strip. * @param width the maximum width for layout in pixels. @@ -413,10 +425,19 @@ final class SuggestionStripLayoutHelper { private void setupWordViewsTextAndColor(final SuggestedWords suggestedWords, final int countInStrip) { + // Clear all suggestions first + for (int positionInStrip = 0; positionInStrip < countInStrip; ++positionInStrip) { + mWordViews.get(positionInStrip).setText(null); + // Make this inactive for touches in {@link #layoutWord(int,int)}. + if (SuggestionStripView.DBG) { + mDebugInfoViews.get(positionInStrip).setText(null); + } + } final int count = Math.min(suggestedWords.size(), countInStrip); - for (int positionInStrip = 0; positionInStrip < count; positionInStrip++) { - final int indexInSuggestedWords = - getIndexInSuggestedWords(positionInStrip, suggestedWords); + for (int indexInSuggestedWords = 0; indexInSuggestedWords < count; + indexInSuggestedWords++) { + final int positionInStrip = + getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords); final TextView wordView = mWordViews.get(positionInStrip); // {@link TextView#getTag()} is used to get the index in suggestedWords at // {@link SuggestionStripView#onClick(View)}. @@ -428,13 +449,6 @@ final class SuggestionStripLayoutHelper { Utils.getDebugInfo(suggestedWords, indexInSuggestedWords)); } } - for (int positionInStrip = count; positionInStrip < countInStrip; positionInStrip++) { - mWordViews.get(positionInStrip).setText(null); - // Make this inactive for touches in {@link #layoutWord(int,int)}. - if (SuggestionStripView.DBG) { - mDebugInfoViews.get(positionInStrip).setText(null); - } - } } private void layoutPunctuationSuggestions(final SuggestedWords suggestedWords, diff --git a/java/src/com/android/inputmethod/latin/utils/LogUtils.java b/java/src/com/android/inputmethod/latin/utils/DebugLogUtils.java index a0d2e0495..c4ead0ad1 100644 --- a/java/src/com/android/inputmethod/latin/utils/LogUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/DebugLogUtils.java @@ -23,8 +23,8 @@ import com.android.inputmethod.latin.LatinImeLogger; /** * A class for logging and debugging utility methods. */ -public final class LogUtils { - private final static String TAG = LogUtils.class.getSimpleName(); +public final class DebugLogUtils { + private final static String TAG = DebugLogUtils.class.getSimpleName(); private final static boolean sDBG = LatinImeLogger.sDBG; /** diff --git a/java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java b/java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java new file mode 100644 index 000000000..3e67e8216 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2013 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.utils; + +import android.inputmethodservice.InputMethodService; + +import com.android.inputmethod.annotations.UsedForTesting; +import com.android.inputmethod.latin.Settings; +import com.android.inputmethod.latin.utils.Utils.UsabilityStudyLogUtils; + +public final class UserLogRingCharBuffer { + public /* for test */ static final int BUFSIZE = 20; + public /* for test */ int mLength = 0; + + private static UserLogRingCharBuffer sUserLogRingCharBuffer = new UserLogRingCharBuffer(); + private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC'; + private static final int INVALID_COORDINATE = -2; + private boolean mEnabled = false; + private int mEnd = 0; + private char[] mCharBuf = new char[BUFSIZE]; + private int[] mXBuf = new int[BUFSIZE]; + private int[] mYBuf = new int[BUFSIZE]; + + private UserLogRingCharBuffer() { + // Intentional empty constructor for singleton. + } + + @UsedForTesting + public static UserLogRingCharBuffer getInstance() { + return sUserLogRingCharBuffer; + } + + public static UserLogRingCharBuffer init(final InputMethodService context, + final boolean enabled, final boolean usabilityStudy) { + if (!(enabled || usabilityStudy)) { + return null; + } + sUserLogRingCharBuffer.mEnabled = true; + UsabilityStudyLogUtils.getInstance().init(context); + return sUserLogRingCharBuffer; + } + + private static int normalize(final int in) { + int ret = in % BUFSIZE; + return ret < 0 ? ret + BUFSIZE : ret; + } + + // TODO: accept code points + @UsedForTesting + public void push(final char c, final int x, final int y) { + if (!mEnabled) { + return; + } + mCharBuf[mEnd] = c; + mXBuf[mEnd] = x; + mYBuf[mEnd] = y; + mEnd = normalize(mEnd + 1); + if (mLength < BUFSIZE) { + ++mLength; + } + } + + public char pop() { + if (mLength < 1) { + return PLACEHOLDER_DELIMITER_CHAR; + } + mEnd = normalize(mEnd - 1); + --mLength; + return mCharBuf[mEnd]; + } + + public char getBackwardNthChar(final int n) { + if (mLength <= n || n < 0) { + return PLACEHOLDER_DELIMITER_CHAR; + } + return mCharBuf[normalize(mEnd - n - 1)]; + } + + public int getPreviousX(final char c, final int back) { + final int index = normalize(mEnd - 2 - back); + if (mLength <= back + || Character.toLowerCase(c) != Character.toLowerCase(mCharBuf[index])) { + return INVALID_COORDINATE; + } + return mXBuf[index]; + } + + public int getPreviousY(final char c, final int back) { + int index = normalize(mEnd - 2 - back); + if (mLength <= back + || Character.toLowerCase(c) != Character.toLowerCase(mCharBuf[index])) { + return INVALID_COORDINATE; + } + return mYBuf[index]; + } + + public String getLastWord(final int ignoreCharCount) { + final StringBuilder sb = new StringBuilder(); + int i = ignoreCharCount; + for (; i < mLength; ++i) { + final char c = mCharBuf[normalize(mEnd - 1 - i)]; + if (!Settings.getInstance().isWordSeparator(c)) { + break; + } + } + for (; i < mLength; ++i) { + char c = mCharBuf[normalize(mEnd - 1 - i)]; + if (!Settings.getInstance().isWordSeparator(c)) { + sb.append(c); + } else { + break; + } + } + return sb.reverse().toString(); + } + + public void reset() { + mLength = 0; + } +} diff --git a/java/src/com/android/inputmethod/latin/utils/Utils.java b/java/src/com/android/inputmethod/latin/utils/Utils.java index 390d306c8..c4e18ed7e 100644 --- a/java/src/com/android/inputmethod/latin/utils/Utils.java +++ b/java/src/com/android/inputmethod/latin/utils/Utils.java @@ -26,7 +26,6 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.inputmethodservice.InputMethodService; import android.net.Uri; -import android.os.AsyncTask; import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; @@ -34,9 +33,7 @@ import android.os.Process; import android.text.TextUtils; import android.util.Log; -import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; @@ -63,135 +60,6 @@ public final class Utils { // This utility class is not publicly instantiable. } - /** - * Cancel an {@link AsyncTask}. - * - * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this - * task should be interrupted; otherwise, in-progress tasks are allowed - * to complete. - */ - public static void cancelTask(final AsyncTask<?, ?, ?> task, - final boolean mayInterruptIfRunning) { - if (task != null && task.getStatus() != AsyncTask.Status.FINISHED) { - task.cancel(mayInterruptIfRunning); - } - } - - // TODO: Make this an external class - public /* for test */ static final class RingCharBuffer { - public /* for test */ static final int BUFSIZE = 20; - public /* for test */ int mLength = 0; - - private static RingCharBuffer sRingCharBuffer = new RingCharBuffer(); - private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC'; - private static final int INVALID_COORDINATE = -2; - private InputMethodService mContext; - private boolean mEnabled = false; - private int mEnd = 0; - private char[] mCharBuf = new char[BUFSIZE]; - private int[] mXBuf = new int[BUFSIZE]; - private int[] mYBuf = new int[BUFSIZE]; - - private RingCharBuffer() { - // Intentional empty constructor for singleton. - } - - @UsedForTesting - public static RingCharBuffer getInstance() { - return sRingCharBuffer; - } - - public static RingCharBuffer init(final InputMethodService context, final boolean enabled, - final boolean usabilityStudy) { - if (!(enabled || usabilityStudy)) { - return null; - } - sRingCharBuffer.mContext = context; - sRingCharBuffer.mEnabled = true; - UsabilityStudyLogUtils.getInstance().init(context); - return sRingCharBuffer; - } - - private static int normalize(final int in) { - int ret = in % BUFSIZE; - return ret < 0 ? ret + BUFSIZE : ret; - } - - // TODO: accept code points - @UsedForTesting - public void push(final char c, final int x, final int y) { - if (!mEnabled) { - return; - } - mCharBuf[mEnd] = c; - mXBuf[mEnd] = x; - mYBuf[mEnd] = y; - mEnd = normalize(mEnd + 1); - if (mLength < BUFSIZE) { - ++mLength; - } - } - - public char pop() { - if (mLength < 1) { - return PLACEHOLDER_DELIMITER_CHAR; - } - mEnd = normalize(mEnd - 1); - --mLength; - return mCharBuf[mEnd]; - } - - public char getBackwardNthChar(final int n) { - if (mLength <= n || n < 0) { - return PLACEHOLDER_DELIMITER_CHAR; - } - return mCharBuf[normalize(mEnd - n - 1)]; - } - - public int getPreviousX(final char c, final int back) { - final int index = normalize(mEnd - 2 - back); - if (mLength <= back - || Character.toLowerCase(c) != Character.toLowerCase(mCharBuf[index])) { - return INVALID_COORDINATE; - } - return mXBuf[index]; - } - - public int getPreviousY(final char c, final int back) { - int index = normalize(mEnd - 2 - back); - if (mLength <= back - || Character.toLowerCase(c) != Character.toLowerCase(mCharBuf[index])) { - return INVALID_COORDINATE; - } - return mYBuf[index]; - } - - public String getLastWord(final int ignoreCharCount) { - final StringBuilder sb = new StringBuilder(); - final LatinIME latinIme = (LatinIME)mContext; - int i = ignoreCharCount; - for (; i < mLength; ++i) { - final char c = mCharBuf[normalize(mEnd - 1 - i)]; - if (!latinIme.isWordSeparator(c)) { - break; - } - } - for (; i < mLength; ++i) { - char c = mCharBuf[normalize(mEnd - 1 - i)]; - if (!latinIme.isWordSeparator(c)) { - sb.append(c); - } else { - break; - } - } - return sb.reverse().toString(); - } - - public void reset() { - mLength = 0; - } - } - // TODO: Make this an external class public static final class UsabilityStudyLogUtils { // TODO: remove code duplication with ResearchLog class @@ -409,7 +277,7 @@ public final class Utils { // TODO: Make this an external class public static final class Stats { public static void onNonSeparator(final char code, final int x, final int y) { - RingCharBuffer.getInstance().push(code, x, y); + UserLogRingCharBuffer.getInstance().push(code, x, y); LatinImeLogger.logOnInputChar(); } @@ -424,7 +292,7 @@ public final class Utils { for (int i = 0; i < length; i = Character.offsetByCodePoints(separator, i, 1)) { int codePoint = Character.codePointAt(separator, i); // TODO: accept code points - RingCharBuffer.getInstance().push((char)codePoint, x, y); + UserLogRingCharBuffer.getInstance().push((char)codePoint, x, y); } LatinImeLogger.logOnInputSeparator(); } |