aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android')
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java1
-rw-r--r--java/src/com/android/inputmethod/keyboard/TextDecorator.java372
-rw-r--r--java/src/com/android/inputmethod/keyboard/TextDecoratorUi.java262
-rw-r--r--java/src/com/android/inputmethod/keyboard/TextDecoratorUiOperator.java51
-rw-r--r--java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java133
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java9
-rw-r--r--java/src/com/android/inputmethod/latin/DicTraverseSession.java11
-rw-r--r--java/src/com/android/inputmethod/latin/Dictionary.java11
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitator.java87
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java187
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java20
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java5
-rw-r--r--java/src/com/android/inputmethod/latin/LastComposedWord.java4
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java142
-rw-r--r--java/src/com/android/inputmethod/latin/NgramContext.java36
-rw-r--r--java/src/com/android/inputmethod/latin/PersonalizationHelperForDictionaryFacilitator.java185
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputConnection.java126
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java24
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java16
-rw-r--r--java/src/com/android/inputmethod/latin/UserBinaryDictionary.java51
-rw-r--r--java/src/com/android/inputmethod/latin/WordComposer.java14
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java174
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FormatSpec.java4
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/ContextualDictionary.java58
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java1
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationDataChunk.java39
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java46
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java36
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java7
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsValues.java7
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java13
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java6
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java53
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java53
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java3
-rw-r--r--java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java178
-rw-r--r--java/src/com/android/inputmethod/latin/userdictionary/UserDictionarySettings.java2
-rw-r--r--java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java4
-rw-r--r--java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java29
-rw-r--r--java/src/com/android/inputmethod/latin/utils/FragmentUtils.java2
-rw-r--r--java/src/com/android/inputmethod/latin/utils/NgramContextUtils.java5
-rw-r--r--java/src/com/android/inputmethod/latin/utils/SuggestionResults.java14
-rw-r--r--java/src/com/android/inputmethod/latin/utils/WordInputEventForPersonalization.java7
43 files changed, 334 insertions, 2154 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 9dc57e308..46476e29e 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -127,7 +127,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions,
mKeyboardTextsSet.setLocale(mRichImm.getCurrentSubtypeLocales()[0], mThemeContext);
} catch (KeyboardLayoutSetException e) {
Log.w(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause());
- return;
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/TextDecorator.java b/java/src/com/android/inputmethod/keyboard/TextDecorator.java
deleted file mode 100644
index 892d36752..000000000
--- a/java/src/com/android/inputmethod/keyboard/TextDecorator.java
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (C) 2014 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.keyboard;
-
-import android.graphics.Matrix;
-import android.graphics.RectF;
-import android.inputmethodservice.InputMethodService;
-import android.os.Message;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.View;
-import android.view.inputmethod.CursorAnchorInfo;
-
-import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.compat.CursorAnchorInfoCompatWrapper;
-import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-/**
- * A controller class of the add-to-dictionary indicator (a.k.a. TextDecorator). This class
- * is designed to be independent of UI subsystems such as {@link View}. All the UI related
- * operations are delegated to {@link TextDecoratorUi} via {@link TextDecoratorUiOperator}.
- */
-public class TextDecorator {
- private static final String TAG = TextDecorator.class.getSimpleName();
- private static final boolean DEBUG = false;
-
- private static final int INVALID_CURSOR_INDEX = -1;
-
- private static final int MODE_MONITOR = 0;
- private static final int MODE_WAITING_CURSOR_INDEX = 1;
- private static final int MODE_SHOWING_INDICATOR = 2;
-
- private int mMode = MODE_MONITOR;
-
- private String mLastComposingText = null;
- private boolean mHasRtlCharsInLastComposingText = false;
- private RectF mComposingTextBoundsForLastComposingText = new RectF();
-
- private boolean mIsFullScreenMode = false;
- private String mWaitingWord = null;
- private int mWaitingCursorStart = INVALID_CURSOR_INDEX;
- private int mWaitingCursorEnd = INVALID_CURSOR_INDEX;
- @Nullable
- private CursorAnchorInfoCompatWrapper mCursorAnchorInfoWrapper = null;
-
- @Nonnull
- private final Listener mListener;
-
- @Nonnull
- private TextDecoratorUiOperator mUiOperator = EMPTY_UI_OPERATOR;
-
- public interface Listener {
- /**
- * Called when the user clicks the indicator to add the word into the dictionary.
- * @param word the word which the user clicked on.
- */
- void onClickComposingTextToAddToDictionary(final String word);
- }
-
- public TextDecorator(@Nullable final Listener listener) {
- mListener = (listener != null) ? listener : EMPTY_LISTENER;
- }
-
- /**
- * Sets the UI operator for {@link TextDecorator}. Any user visible operations will be
- * delegated to the associated UI operator.
- * @param uiOperator the UI operator to be associated.
- */
- public void setUiOperator(@Nonnull final TextDecoratorUiOperator uiOperator) {
- mUiOperator.disposeUi();
- mUiOperator = uiOperator;
- mUiOperator.setOnClickListener(getOnClickHandler());
- }
-
- private final Runnable mDefaultOnClickHandler = new Runnable() {
- @Override
- public void run() {
- onClickIndicator();
- }
- };
-
- @UsedForTesting
- final Runnable getOnClickHandler() {
- return mDefaultOnClickHandler;
- }
-
- /**
- * Shows the "Add to dictionary" indicator and associates it with associating the given word.
- *
- * @param word the word which should be associated with the indicator. This object will be
- * passed back in {@link Listener#onClickComposingTextToAddToDictionary(String)}.
- * @param selectionStart the cursor index (inclusive) when the indicator should be displayed.
- * @param selectionEnd the cursor index (exclusive) when the indicator should be displayed.
- */
- public void showAddToDictionaryIndicator(final String word, final int selectionStart,
- final int selectionEnd) {
- mWaitingWord = word;
- mWaitingCursorStart = selectionStart;
- mWaitingCursorEnd = selectionEnd;
- mMode = MODE_WAITING_CURSOR_INDEX;
- layoutLater();
- return;
- }
-
- /**
- * Must be called when the input method is about changing to for from the full screen mode.
- * @param fullScreenMode {@code true} if the input method is entering the full screen mode.
- * {@code false} is the input method is finishing the full screen mode.
- */
- public void notifyFullScreenMode(final boolean fullScreenMode) {
- final boolean fullScreenModeChanged = (mIsFullScreenMode != fullScreenMode);
- mIsFullScreenMode = fullScreenMode;
- if (fullScreenModeChanged) {
- layoutLater();
- }
- }
-
- /**
- * Resets previous requests and makes indicator invisible.
- */
- public void reset() {
- mWaitingWord = null;
- mMode = MODE_MONITOR;
- mWaitingCursorStart = INVALID_CURSOR_INDEX;
- mWaitingCursorEnd = INVALID_CURSOR_INDEX;
- cancelLayoutInternalExpectedly("Resetting internal state.");
- }
-
- /**
- * Must be called when the {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)}
- * is called.
- *
- * <p>CAVEAT: Currently the input method author is responsible for ignoring
- * {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)} called in full screen
- * mode.</p>
- * @param info the compatibility wrapper object for the received {@link CursorAnchorInfo}.
- */
- public void onUpdateCursorAnchorInfo(@Nullable final CursorAnchorInfoCompatWrapper info) {
- mCursorAnchorInfoWrapper = info;
- // Do not use layoutLater() to minimize the latency.
- layoutImmediately();
- }
-
- private void cancelLayoutInternalUnexpectedly(final String message) {
- mUiOperator.hideUi();
- Log.d(TAG, message);
- }
-
- private void cancelLayoutInternalExpectedly(final String message) {
- mUiOperator.hideUi();
- if (DEBUG) {
- Log.d(TAG, message);
- }
- }
-
- private void layoutLater() {
- mLayoutInvalidator.invalidateLayout();
- }
-
-
- private void layoutImmediately() {
- // Clear pending layout requests.
- mLayoutInvalidator.cancelInvalidateLayout();
- layoutMain();
- }
-
- void layoutMain() {
- final CursorAnchorInfoCompatWrapper info = mCursorAnchorInfoWrapper;
-
- if (info == null) {
- cancelLayoutInternalExpectedly("CursorAnchorInfo isn't available.");
- return;
- }
-
- final Matrix matrix = info.getMatrix();
- if (matrix == null) {
- cancelLayoutInternalUnexpectedly("Matrix is null");
- }
-
- final CharSequence composingText = info.getComposingText();
- if (!TextUtils.isEmpty(composingText)) {
- final int composingTextStart = info.getComposingTextStart();
- final int lastCharRectIndex = composingTextStart + composingText.length() - 1;
- final RectF lastCharRect = info.getCharacterBounds(lastCharRectIndex);
- final int lastCharRectFlags = info.getCharacterBoundsFlags(lastCharRectIndex);
- final boolean hasInvisibleRegionInLastCharRect =
- (lastCharRectFlags & CursorAnchorInfoCompatWrapper.FLAG_HAS_INVISIBLE_REGION)
- != 0;
- if (lastCharRect == null || matrix == null || hasInvisibleRegionInLastCharRect) {
- mUiOperator.hideUi();
- return;
- }
-
- // Note that the following layout information is fragile, and must be invalidated
- // even when surrounding text next to the composing text is changed because it can
- // affect how the composing text is rendered.
- // TODO: Investigate if we can change the input logic to make the target text
- // composing state so that we can retrieve the character bounds reliably.
- final String composingTextString = composingText.toString();
- final float top = lastCharRect.top;
- final float bottom = lastCharRect.bottom;
- float left = lastCharRect.left;
- float right = lastCharRect.right;
- boolean useRtlLayout = false;
- for (int i = composingText.length() - 1; i >= 0; --i) {
- final int characterIndex = composingTextStart + i;
- final RectF characterBounds = info.getCharacterBounds(characterIndex);
- final int characterBoundsFlags = info.getCharacterBoundsFlags(characterIndex);
- if (characterBounds == null) {
- break;
- }
- if (characterBounds.top != top) {
- break;
- }
- if (characterBounds.bottom != bottom) {
- break;
- }
- if ((characterBoundsFlags & CursorAnchorInfoCompatWrapper.FLAG_IS_RTL) != 0) {
- // This is for both RTL text and bi-directional text. RTL languages usually mix
- // RTL characters with LTR characters and in this case we should display the
- // indicator on the left, while in LTR languages that normally never happens.
- // TODO: Try to come up with a better algorithm.
- useRtlLayout = true;
- }
- left = Math.min(characterBounds.left, left);
- right = Math.max(characterBounds.right, right);
- }
- mLastComposingText = composingTextString;
- mHasRtlCharsInLastComposingText = useRtlLayout;
- mComposingTextBoundsForLastComposingText.set(left, top, right, bottom);
- }
-
- final int selectionStart = info.getSelectionStart();
- final int selectionEnd = info.getSelectionEnd();
- switch (mMode) {
- case MODE_MONITOR:
- mUiOperator.hideUi();
- return;
- case MODE_WAITING_CURSOR_INDEX:
- if (selectionStart != mWaitingCursorStart || selectionEnd != mWaitingCursorEnd) {
- mUiOperator.hideUi();
- return;
- }
- mMode = MODE_SHOWING_INDICATOR;
- break;
- case MODE_SHOWING_INDICATOR:
- if (selectionStart != mWaitingCursorStart || selectionEnd != mWaitingCursorEnd) {
- mUiOperator.hideUi();
- mMode = MODE_MONITOR;
- mWaitingCursorStart = INVALID_CURSOR_INDEX;
- mWaitingCursorEnd = INVALID_CURSOR_INDEX;
- return;
- }
- break;
- default:
- cancelLayoutInternalUnexpectedly("Unexpected internal mode=" + mMode);
- return;
- }
-
- if (!TextUtils.equals(mLastComposingText, mWaitingWord)) {
- cancelLayoutInternalUnexpectedly("mLastComposingText doesn't match mWaitingWord");
- return;
- }
-
- if ((info.getInsertionMarkerFlags() &
- CursorAnchorInfoCompatWrapper.FLAG_HAS_INVISIBLE_REGION) != 0) {
- mUiOperator.hideUi();
- return;
- }
-
- mUiOperator.layoutUi(matrix, mComposingTextBoundsForLastComposingText,
- mHasRtlCharsInLastComposingText);
- }
-
- void onClickIndicator() {
- if (mMode != MODE_SHOWING_INDICATOR) {
- return;
- }
- mListener.onClickComposingTextToAddToDictionary(mWaitingWord);
- }
-
- private final LayoutInvalidator mLayoutInvalidator = new LayoutInvalidator(this);
-
- /**
- * Used for managing pending layout tasks for {@link TextDecorator#layoutLater()}.
- */
- private static final class LayoutInvalidator {
- private final HandlerImpl mHandler;
- public LayoutInvalidator(@Nonnull final TextDecorator ownerInstance) {
- mHandler = new HandlerImpl(ownerInstance);
- }
-
- private static final int MSG_LAYOUT = 0;
-
- private static final class HandlerImpl
- extends LeakGuardHandlerWrapper<TextDecorator> {
- public HandlerImpl(@Nonnull final TextDecorator ownerInstance) {
- super(ownerInstance);
- }
-
- @Override
- public void handleMessage(final Message msg) {
- final TextDecorator owner = getOwnerInstance();
- if (owner == null) {
- return;
- }
- switch (msg.what) {
- case MSG_LAYOUT:
- owner.layoutMain();
- break;
- }
- }
- }
-
- /**
- * Puts a layout task into the scheduler. Does nothing if one or more layout tasks are
- * already scheduled.
- */
- public void invalidateLayout() {
- if (!mHandler.hasMessages(MSG_LAYOUT)) {
- mHandler.obtainMessage(MSG_LAYOUT).sendToTarget();
- }
- }
-
- /**
- * Clears the pending layout tasks.
- */
- public void cancelInvalidateLayout() {
- mHandler.removeMessages(MSG_LAYOUT);
- }
- }
-
- @Nonnull
- private final static Listener EMPTY_LISTENER = new Listener() {
- @Override
- public void onClickComposingTextToAddToDictionary(final String word) {
- }
- };
-
- @Nonnull
- private final static TextDecoratorUiOperator EMPTY_UI_OPERATOR = new TextDecoratorUiOperator() {
- @Override
- public void disposeUi() {
- }
- @Override
- public void hideUi() {
- }
- @Override
- public void setOnClickListener(Runnable listener) {
- }
- @Override
- public void layoutUi(Matrix matrix, RectF composingTextBounds, boolean useRtlLayout) {
- }
- };
-}
diff --git a/java/src/com/android/inputmethod/keyboard/TextDecoratorUi.java b/java/src/com/android/inputmethod/keyboard/TextDecoratorUi.java
deleted file mode 100644
index d87dc1bfa..000000000
--- a/java/src/com/android/inputmethod/keyboard/TextDecoratorUi.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2014 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.keyboard;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.RectF;
-import android.graphics.drawable.ColorDrawable;
-import android.inputmethodservice.InputMethodService;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.view.ViewParent;
-import android.widget.PopupWindow;
-import android.widget.RelativeLayout;
-
-import com.android.inputmethod.latin.R;
-
-/**
- * Used as the UI component of {@link TextDecorator}.
- */
-public final class TextDecoratorUi implements TextDecoratorUiOperator {
- private static final boolean VISUAL_DEBUG = false;
- private static final int VISUAL_DEBUG_HIT_AREA_COLOR = 0x80ff8000;
-
- private final RelativeLayout mLocalRootView;
- private final AddToDictionaryIndicatorView mAddToDictionaryIndicatorView;
- private final PopupWindow mTouchEventWindow;
- private final View mTouchEventWindowClickListenerView;
- private final float mHitAreaMarginInPixels;
- private final RectF mDisplayRect;
-
- /**
- * This constructor is designed to be called from {@link InputMethodService#setInputView(View)}.
- * Other usages are not supported.
- *
- * @param context the context of the input method.
- * @param inputView the view that is passed to {@link InputMethodService#setInputView(View)}.
- */
- public TextDecoratorUi(final Context context, final View inputView) {
- final Resources resources = context.getResources();
- final int hitAreaMarginInDP = resources.getInteger(
- R.integer.text_decorator_hit_area_margin_in_dp);
- mHitAreaMarginInPixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
- hitAreaMarginInDP, resources.getDisplayMetrics());
- final DisplayMetrics displayMetrics = resources.getDisplayMetrics();
- mDisplayRect = new RectF(0.0f, 0.0f, displayMetrics.widthPixels,
- displayMetrics.heightPixels);
-
- mLocalRootView = new RelativeLayout(context);
- mLocalRootView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT));
- // TODO: Use #setBackground(null) for API Level >= 16.
- mLocalRootView.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
-
- final ViewGroup contentView = getContentView(inputView);
- mAddToDictionaryIndicatorView = new AddToDictionaryIndicatorView(context);
- mLocalRootView.addView(mAddToDictionaryIndicatorView);
- if (contentView != null) {
- contentView.addView(mLocalRootView);
- }
-
- // This popup window is used to avoid the limitation that the input method is not able to
- // observe the touch events happening outside of InputMethodService.Insets#touchableRegion.
- // We don't use this popup window for rendering the UI for performance reasons though.
- mTouchEventWindow = new PopupWindow(context);
- if (VISUAL_DEBUG) {
- mTouchEventWindow.setBackgroundDrawable(new ColorDrawable(VISUAL_DEBUG_HIT_AREA_COLOR));
- } else {
- mTouchEventWindow.setBackgroundDrawable(null);
- }
- mTouchEventWindowClickListenerView = new View(context);
- mTouchEventWindow.setContentView(mTouchEventWindowClickListenerView);
- }
-
- @Override
- public void disposeUi() {
- if (mLocalRootView != null) {
- final ViewParent parent = mLocalRootView.getParent();
- if (parent != null && parent instanceof ViewGroup) {
- ((ViewGroup) parent).removeView(mLocalRootView);
- }
- mLocalRootView.removeAllViews();
- }
- if (mTouchEventWindow != null) {
- mTouchEventWindow.dismiss();
- }
- }
-
- @Override
- public void hideUi() {
- mAddToDictionaryIndicatorView.setVisibility(View.GONE);
- mTouchEventWindow.dismiss();
- }
-
- private static final RectF getIndicatorBoundsInScreenCoordinates(final Matrix matrix,
- final RectF composingTextBounds, final boolean showAtLeftSide) {
- final float indicatorSize = composingTextBounds.height();
- final RectF indicatorBounds;
- if (showAtLeftSide) {
- indicatorBounds = new RectF(composingTextBounds.left - indicatorSize,
- composingTextBounds.top, composingTextBounds.left,
- composingTextBounds.top + indicatorSize);
- } else {
- indicatorBounds = new RectF(composingTextBounds.right, composingTextBounds.top,
- composingTextBounds.right + indicatorSize,
- composingTextBounds.top + indicatorSize);
- }
- matrix.mapRect(indicatorBounds);
- return indicatorBounds;
- }
-
- @Override
- public void layoutUi(final Matrix matrix, final RectF composingTextBounds,
- final boolean useRtlLayout) {
- RectF indicatorBoundsInScreenCoordinates = getIndicatorBoundsInScreenCoordinates(matrix,
- composingTextBounds, useRtlLayout /* showAtLeftSide */);
- if (indicatorBoundsInScreenCoordinates.left < mDisplayRect.left ||
- mDisplayRect.right < indicatorBoundsInScreenCoordinates.right) {
- // The indicator is clipped by the screen. Show the indicator at the opposite side.
- indicatorBoundsInScreenCoordinates = getIndicatorBoundsInScreenCoordinates(matrix,
- composingTextBounds, !useRtlLayout /* showAtLeftSide */);
- }
-
- mAddToDictionaryIndicatorView.setBounds(indicatorBoundsInScreenCoordinates);
-
- final RectF hitAreaBoundsInScreenCoordinates = new RectF();
- matrix.mapRect(hitAreaBoundsInScreenCoordinates, composingTextBounds);
- hitAreaBoundsInScreenCoordinates.union(indicatorBoundsInScreenCoordinates);
- hitAreaBoundsInScreenCoordinates.inset(-mHitAreaMarginInPixels, -mHitAreaMarginInPixels);
-
- final int[] originScreen = new int[2];
- mLocalRootView.getLocationOnScreen(originScreen);
- final int viewOriginX = originScreen[0];
- final int viewOriginY = originScreen[1];
- mAddToDictionaryIndicatorView.setX(indicatorBoundsInScreenCoordinates.left - viewOriginX);
- mAddToDictionaryIndicatorView.setY(indicatorBoundsInScreenCoordinates.top - viewOriginY);
- mAddToDictionaryIndicatorView.setVisibility(View.VISIBLE);
-
- if (mTouchEventWindow.isShowing()) {
- mTouchEventWindow.update((int)hitAreaBoundsInScreenCoordinates.left - viewOriginX,
- (int)hitAreaBoundsInScreenCoordinates.top - viewOriginY,
- (int)hitAreaBoundsInScreenCoordinates.width(),
- (int)hitAreaBoundsInScreenCoordinates.height());
- } else {
- mTouchEventWindow.setWidth((int)hitAreaBoundsInScreenCoordinates.width());
- mTouchEventWindow.setHeight((int)hitAreaBoundsInScreenCoordinates.height());
- mTouchEventWindow.showAtLocation(mLocalRootView, Gravity.NO_GRAVITY,
- (int)hitAreaBoundsInScreenCoordinates.left - viewOriginX,
- (int)hitAreaBoundsInScreenCoordinates.top - viewOriginY);
- }
- }
-
- @Override
- public void setOnClickListener(final Runnable listener) {
- mTouchEventWindowClickListenerView.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(final View arg0) {
- listener.run();
- }
- });
- }
-
- private static class IndicatorView extends View {
- private final Path mPath;
- private final Path mTmpPath = new Path();
- private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- private final Matrix mMatrix = new Matrix();
- private final int mBackgroundColor;
- private final int mForegroundColor;
- private final RectF mBounds = new RectF();
- public IndicatorView(Context context, final int pathResourceId,
- final int sizeResourceId, final int backgroundColorResourceId,
- final int foregroundColroResourceId) {
- super(context);
- final Resources resources = context.getResources();
- mPath = createPath(resources, pathResourceId, sizeResourceId);
- mBackgroundColor = resources.getColor(backgroundColorResourceId);
- mForegroundColor = resources.getColor(foregroundColroResourceId);
- }
-
- public void setBounds(final RectF rect) {
- mBounds.set(rect);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- mPaint.setColor(mBackgroundColor);
- mPaint.setStyle(Paint.Style.FILL);
- canvas.drawRect(0.0f, 0.0f, mBounds.width(), mBounds.height(), mPaint);
-
- mMatrix.reset();
- mMatrix.postScale(mBounds.width(), mBounds.height());
- mPath.transform(mMatrix, mTmpPath);
- mPaint.setColor(mForegroundColor);
- canvas.drawPath(mTmpPath, mPaint);
- }
-
- private static Path createPath(final Resources resources, final int pathResourceId,
- final int sizeResourceId) {
- final int size = resources.getInteger(sizeResourceId);
- final float normalizationFactor = 1.0f / size;
- final int[] array = resources.getIntArray(pathResourceId);
-
- final Path path = new Path();
- for (int i = 0; i < array.length; i += 2) {
- if (i == 0) {
- path.moveTo(array[i] * normalizationFactor, array[i + 1] * normalizationFactor);
- } else {
- path.lineTo(array[i] * normalizationFactor, array[i + 1] * normalizationFactor);
- }
- }
- path.close();
- return path;
- }
- }
-
- private static ViewGroup getContentView(final View view) {
- final View rootView = view.getRootView();
- if (rootView == null) {
- return null;
- }
-
- final ViewGroup windowContentView = (ViewGroup)rootView.findViewById(android.R.id.content);
- if (windowContentView == null) {
- return null;
- }
- return windowContentView;
- }
-
- private static final class AddToDictionaryIndicatorView extends TextDecoratorUi.IndicatorView {
- public AddToDictionaryIndicatorView(final Context context) {
- super(context, R.array.text_decorator_add_to_dictionary_indicator_path,
- R.integer.text_decorator_add_to_dictionary_indicator_path_size,
- R.color.text_decorator_add_to_dictionary_indicator_background_color,
- R.color.text_decorator_add_to_dictionary_indicator_foreground_color);
- }
- }
-} \ No newline at end of file
diff --git a/java/src/com/android/inputmethod/keyboard/TextDecoratorUiOperator.java b/java/src/com/android/inputmethod/keyboard/TextDecoratorUiOperator.java
deleted file mode 100644
index 9e30e417e..000000000
--- a/java/src/com/android/inputmethod/keyboard/TextDecoratorUiOperator.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2014 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.keyboard;
-
-import android.graphics.Matrix;
-import android.graphics.RectF;
-
-/**
- * This interface defines how UI operations required for {@link TextDecorator} are delegated to
- * the actual UI implementation class.
- */
-public interface TextDecoratorUiOperator {
- /**
- * Called to notify that the UI is ready to be disposed.
- */
- void disposeUi();
-
- /**
- * Called when the UI should become invisible.
- */
- void hideUi();
-
- /**
- * Called to set the new click handler.
- * @param onClickListener the callback object whose {@link Runnable#run()} should be called when
- * the indicator is clicked.
- */
- void setOnClickListener(final Runnable onClickListener);
-
- /**
- * Called when the layout should be updated.
- * @param matrix The matrix that transforms the local coordinates into the screen coordinates.
- * @param composingTextBounds The bounding box of the composing text, in local coordinates.
- * @param useRtlLayout {@code true} if the indicator should be optimized for RTL layout.
- */
- void layoutUi(final Matrix matrix, final RectF composingTextBounds, final boolean useRtlLayout);
-}
diff --git a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java
index cf4dd3db3..f4c4f1aab 100644
--- a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java
+++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java
@@ -22,7 +22,6 @@ import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
-import android.os.CountDownTimer;
import android.preference.PreferenceManager;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
@@ -52,8 +51,6 @@ import com.android.inputmethod.latin.RichInputMethodSubtype;
import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.utils.ResourceUtils;
-import java.util.concurrent.TimeUnit;
-
/**
* View class to implement Emoji palettes.
* The Emoji keyboard consists of group of views layout/emoji_palettes_view.
@@ -75,9 +72,9 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
private final int mCategoryIndicatorBackgroundResId;
private final int mCategoryPageIndicatorColor;
private final int mCategoryPageIndicatorBackground;
- private final DeleteKeyOnTouchListener mDeleteKeyOnTouchListener;
private EmojiPalettesAdapter mEmojiPalettesAdapter;
private final EmojiLayoutParams mEmojiLayoutParams;
+ private final DeleteKeyOnTouchListener mDeleteKeyOnTouchListener;
private ImageButton mDeleteKey;
private TextView mAlphabetKeyLeft;
@@ -132,7 +129,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
mCategoryPageIndicatorBackground = emojiPalettesViewAttr.getColor(
R.styleable.EmojiPalettesView_categoryPageIndicatorBackground, 0);
emojiPalettesViewAttr.recycle();
- mDeleteKeyOnTouchListener = new DeleteKeyOnTouchListener(context);
+ mDeleteKeyOnTouchListener = new DeleteKeyOnTouchListener();
}
@Override
@@ -265,7 +262,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
@Override
public void onPageScrolled(final int position, final float positionOffset,
- final int positionOffsetPixels) {
+ final int positionOffsetPixels) {
mEmojiPalettesAdapter.onPageScrolled();
final Pair<Integer, Integer> newPos =
mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(position);
@@ -364,7 +361,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
}
private static void setupAlphabetKey(final TextView alphabetKey, final String label,
- final KeyDrawParams params) {
+ final KeyDrawParams params) {
alphabetKey.setText(label);
alphabetKey.setTextColor(params.mFunctionalTextColor);
alphabetKey.setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mLabelSize);
@@ -372,7 +369,8 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
}
public void startEmojiPalettes(final String switchToAlphaLabel,
- final KeyVisualAttributes keyVisualAttr, final KeyboardIconsSet iconSet) {
+ final KeyVisualAttributes keyVisualAttr,
+ final KeyboardIconsSet iconSet) {
final int deleteIconResId = iconSet.getIconResourceId(KeyboardIconsSet.NAME_DELETE_KEY);
if (deleteIconResId != 0) {
mDeleteKey.setImageResource(deleteIconResId);
@@ -398,7 +396,7 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
public void setKeyboardActionListener(final KeyboardActionListener listener) {
mKeyboardActionListener = listener;
- mDeleteKeyOnTouchListener.setKeyboardActionListener(mKeyboardActionListener);
+ mDeleteKeyOnTouchListener.setKeyboardActionListener(listener);
}
private void updateEmojiCategoryPageIdView() {
@@ -436,45 +434,9 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
}
private static class DeleteKeyOnTouchListener implements OnTouchListener {
- static final long MAX_REPEAT_COUNT_TIME = TimeUnit.SECONDS.toMillis(30);
- final long mKeyRepeatStartTimeout;
- final long mKeyRepeatInterval;
-
- public DeleteKeyOnTouchListener(Context context) {
- final Resources res = context.getResources();
- mKeyRepeatStartTimeout = res.getInteger(R.integer.config_key_repeat_start_timeout);
- mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval);
- mTimer = new CountDownTimer(MAX_REPEAT_COUNT_TIME, mKeyRepeatInterval) {
- @Override
- public void onTick(long millisUntilFinished) {
- final long elapsed = MAX_REPEAT_COUNT_TIME - millisUntilFinished;
- if (elapsed < mKeyRepeatStartTimeout) {
- return;
- }
- onKeyRepeat();
- }
- @Override
- public void onFinish() {
- onKeyRepeat();
- }
- };
- }
-
- /** Key-repeat state. */
- private static final int KEY_REPEAT_STATE_INITIALIZED = 0;
- // The key is touched but auto key-repeat is not started yet.
- private static final int KEY_REPEAT_STATE_KEY_DOWN = 1;
- // At least one key-repeat event has already been triggered and the key is not released.
- private static final int KEY_REPEAT_STATE_KEY_REPEAT = 2;
-
private KeyboardActionListener mKeyboardActionListener =
KeyboardActionListener.EMPTY_LISTENER;
- // TODO: Do the same things done in PointerTracker
- private final CountDownTimer mTimer;
- private int mState = KEY_REPEAT_STATE_INITIALIZED;
- private int mRepeatCount = 0;
-
public void setKeyboardActionListener(final KeyboardActionListener listener) {
mKeyboardActionListener = listener;
}
@@ -482,79 +444,40 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
@Override
public boolean onTouch(final View v, final MotionEvent event) {
switch (event.getActionMasked()) {
- case MotionEvent.ACTION_DOWN:
- onTouchDown(v);
- return true;
- case MotionEvent.ACTION_MOVE:
- final float x = event.getX();
- final float y = event.getY();
- if (x < 0.0f || v.getWidth() < x || y < 0.0f || v.getHeight() < y) {
- // Stop generating key events once the finger moves away from the view area.
- onTouchCanceled(v);
- }
- return true;
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP:
- onTouchUp(v);
- return true;
+ case MotionEvent.ACTION_DOWN:
+ onTouchDown(v);
+ return true;
+ case MotionEvent.ACTION_MOVE:
+ final float x = event.getX();
+ final float y = event.getY();
+ if (x < 0.0f || v.getWidth() < x || y < 0.0f || v.getHeight() < y) {
+ // Stop generating key events once the finger moves away from the view area.
+ onTouchCanceled(v);
+ }
+ return true;
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ onTouchUp(v);
+ return true;
}
return false;
}
- private void handleKeyDown() {
- mKeyboardActionListener.onPressKey(
- Constants.CODE_DELETE, mRepeatCount, true /* isSinglePointer */);
- }
-
- private void handleKeyUp() {
- mKeyboardActionListener.onCodeInput(Constants.CODE_DELETE,
- NOT_A_COORDINATE, NOT_A_COORDINATE, false /* isKeyRepeat */);
- mKeyboardActionListener.onReleaseKey(
- Constants.CODE_DELETE, false /* withSliding */);
- ++mRepeatCount;
- }
-
private void onTouchDown(final View v) {
- mTimer.cancel();
- mRepeatCount = 0;
- handleKeyDown();
+ mKeyboardActionListener.onPressKey(Constants.CODE_DELETE,
+ 0 /* repeatCount */, true /* isSinglePointer */);
v.setPressed(true /* pressed */);
- mState = KEY_REPEAT_STATE_KEY_DOWN;
- mTimer.start();
}
private void onTouchUp(final View v) {
- mTimer.cancel();
- if (mState == KEY_REPEAT_STATE_KEY_DOWN) {
- handleKeyUp();
- }
+ mKeyboardActionListener.onCodeInput(Constants.CODE_DELETE,
+ NOT_A_COORDINATE, NOT_A_COORDINATE, false /* isKeyRepeat */);
+ mKeyboardActionListener.onReleaseKey(Constants.CODE_DELETE, false /* withSliding */);
v.setPressed(false /* pressed */);
- mState = KEY_REPEAT_STATE_INITIALIZED;
}
private void onTouchCanceled(final View v) {
- mTimer.cancel();
v.setBackgroundColor(Color.TRANSPARENT);
- mState = KEY_REPEAT_STATE_INITIALIZED;
- }
-
- // Called by {@link #mTimer} in the UI thread as an auto key-repeat signal.
- void onKeyRepeat() {
- switch (mState) {
- case KEY_REPEAT_STATE_INITIALIZED:
- // Basically this should not happen.
- break;
- case KEY_REPEAT_STATE_KEY_DOWN:
- // Do not call {@link #handleKeyDown} here because it has already been called
- // in {@link #onTouchDown}.
- handleKeyUp();
- mState = KEY_REPEAT_STATE_KEY_REPEAT;
- break;
- case KEY_REPEAT_STATE_KEY_REPEAT:
- handleKeyDown();
- handleKeyUp();
- break;
- }
}
}
-}
+} \ No newline at end of file
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index b0eae0832..7e4d66583 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -27,6 +27,7 @@ import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.common.FileUtils;
import com.android.inputmethod.latin.common.InputPointers;
import com.android.inputmethod.latin.common.StringUtils;
+import com.android.inputmethod.latin.define.DecoderSpecificConstants;
import com.android.inputmethod.latin.makedict.DictionaryHeader;
import com.android.inputmethod.latin.makedict.FormatSpec;
import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions;
@@ -319,9 +320,9 @@ public final class BinaryDictionary extends Dictionary {
final int count = session.mOutputSuggestionCount[0];
final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<>();
for (int j = 0; j < count; ++j) {
- final int start = j * Constants.DICTIONARY_MAX_WORD_LENGTH;
+ final int start = j * DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH;
int len = 0;
- while (len < Constants.DICTIONARY_MAX_WORD_LENGTH
+ while (len < DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH
&& session.mOutputCodePoints[start + len] != 0) {
++len;
}
@@ -390,7 +391,7 @@ public final class BinaryDictionary extends Dictionary {
return null;
}
final int[] codePoints = StringUtils.toCodePointArray(word);
- final int[] outCodePoints = new int[Constants.DICTIONARY_MAX_WORD_LENGTH];
+ final int[] outCodePoints = new int[DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH];
final boolean[] outFlags = new boolean[FORMAT_WORD_PROPERTY_OUTPUT_FLAG_COUNT];
final int[] outProbabilityInfo =
new int[FORMAT_WORD_PROPERTY_OUTPUT_PROBABILITY_INFO_COUNT];
@@ -431,7 +432,7 @@ public final class BinaryDictionary extends Dictionary {
* If token is 0, this method newly starts iterating the dictionary.
*/
public GetNextWordPropertyResult getNextWordProperty(final int token) {
- final int[] codePoints = new int[Constants.DICTIONARY_MAX_WORD_LENGTH];
+ final int[] codePoints = new int[DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH];
final boolean[] isBeginningOfSentence = new boolean[1];
final int nextToken = getNextWordNative(mNativeDict, token, codePoints,
isBeginningOfSentence);
diff --git a/java/src/com/android/inputmethod/latin/DicTraverseSession.java b/java/src/com/android/inputmethod/latin/DicTraverseSession.java
index e7fd99ee8..6816f129a 100644
--- a/java/src/com/android/inputmethod/latin/DicTraverseSession.java
+++ b/java/src/com/android/inputmethod/latin/DicTraverseSession.java
@@ -16,8 +16,8 @@
package com.android.inputmethod.latin;
-import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.common.NativeSuggestOptions;
+import com.android.inputmethod.latin.define.DecoderSpecificConstants;
import com.android.inputmethod.latin.utils.JniUtils;
import java.util.Locale;
@@ -28,14 +28,15 @@ public final class DicTraverseSession {
}
// Must be equal to MAX_RESULTS in native/jni/src/defines.h
private static final int MAX_RESULTS = 18;
- public final int[] mInputCodePoints = new int[Constants.DICTIONARY_MAX_WORD_LENGTH];
+ public final int[] mInputCodePoints =
+ new int[DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH];
public final int[][] mPrevWordCodePointArrays =
- new int[Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM][];
+ new int[DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM][];
public final boolean[] mIsBeginningOfSentenceArray =
- new boolean[Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM];
+ new boolean[DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM];
public final int[] mOutputSuggestionCount = new int[1];
public final int[] mOutputCodePoints =
- new int[Constants.DICTIONARY_MAX_WORD_LENGTH * MAX_RESULTS];
+ new int[DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH * MAX_RESULTS];
public final int[] mSpaceIndices = new int[MAX_RESULTS];
public final int[] mOutputScores = new int[MAX_RESULTS];
public final int[] mOutputTypes = new int[MAX_RESULTS];
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index 7d7ed77e7..16dcb3208 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -49,8 +49,7 @@ public abstract class Dictionary {
// Spawned by resuming suggestions. Comes from a span that was in the TextView.
public static final String TYPE_RESUMED = "resumed";
- public static final PhonyDictionary DICTIONARY_RESUMED =
- new PhonyDictionary(TYPE_RESUMED);
+ public static final PhonyDictionary DICTIONARY_RESUMED = new PhonyDictionary(TYPE_RESUMED);
// The following types of dictionary have actual functional instances. We don't need final
// phony dictionary instances for them.
@@ -60,10 +59,6 @@ public abstract class Dictionary {
public static final String TYPE_USER = "user";
// User history dictionary internal to LatinIME.
public static final String TYPE_USER_HISTORY = "history";
- // Personalization dictionary.
- public static final String TYPE_PERSONALIZATION = "personalization";
- // Contextual dictionary.
- public static final String TYPE_CONTEXTUAL = "contextual";
public final String mDictType;
// The locale for this dictionary. May be null if unknown (phony dictionary for example).
public final Locale mLocale;
@@ -76,9 +71,7 @@ public abstract class Dictionary {
TYPE_USER_TYPED,
TYPE_USER,
TYPE_CONTACTS,
- TYPE_USER_HISTORY,
- TYPE_PERSONALIZATION,
- TYPE_CONTEXTUAL));
+ TYPE_USER_HISTORY));
public Dictionary(final String dictType, final Locale locale) {
mDictType = dictType;
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index a0a1d939e..3e4cda47a 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -17,21 +17,19 @@
package com.android.inputmethod.latin;
import android.content.Context;
-import android.view.inputmethod.InputMethodSubtype;
import android.util.Pair;
+import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.ExpandableBinaryDictionary.UpdateEntriesForInputEventsCallback;
-import com.android.inputmethod.latin.personalization.PersonalizationDataChunk;
+import com.android.inputmethod.keyboard.KeyboardLayout;
import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
-import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
import com.android.inputmethod.latin.utils.SuggestionResults;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Locale;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@@ -45,6 +43,35 @@ import javax.annotation.Nullable;
* DictionaryFacilitator as a client for interacting with dictionaries.
*/
public interface DictionaryFacilitator {
+
+ public static final String[] ALL_DICTIONARY_TYPES = new String[] {
+ Dictionary.TYPE_MAIN,
+ Dictionary.TYPE_USER_HISTORY,
+ Dictionary.TYPE_USER,
+ Dictionary.TYPE_CONTACTS};
+
+ public static final String[] DYNAMIC_DICTIONARY_TYPES = new String[] {
+ Dictionary.TYPE_USER_HISTORY,
+ Dictionary.TYPE_USER,
+ Dictionary.TYPE_CONTACTS};
+
+ /**
+ * {@link Dictionary#TYPE_USER} is deprecated, except for the spelling service.
+ */
+ public static final String[] DICTIONARY_TYPES_FOR_SPELLING = new String[] {
+ Dictionary.TYPE_MAIN,
+ Dictionary.TYPE_USER_HISTORY,
+ Dictionary.TYPE_USER,
+ Dictionary.TYPE_CONTACTS};
+
+ /**
+ * {@link Dictionary#TYPE_USER} is deprecated, except for the spelling service.
+ */
+ public static final String[] DICTIONARY_TYPES_FOR_SUGGESTIONS = new String[] {
+ Dictionary.TYPE_MAIN,
+ Dictionary.TYPE_USER_HISTORY,
+ Dictionary.TYPE_CONTACTS};
+
/**
* Returns whether this facilitator is exactly for this list of locales.
*
@@ -86,24 +113,22 @@ public interface DictionaryFacilitator {
boolean isConfidentAboutCurrentLanguageBeing(final Locale mLocale);
- void resetDictionaries(final Context context, final Locale[] newLocales,
- final boolean useContactsDict, final boolean usePersonalizedDicts,
- final boolean forceReloadMainDictionary,
- @Nullable final String account,
- final DictionaryInitializationListener listener);
-
- void resetDictionariesWithDictNamePrefix(final Context context,
+ void resetDictionaries(
+ final Context context,
final Locale[] newLocales,
final boolean useContactsDict,
final boolean usePersonalizedDicts,
final boolean forceReloadMainDictionary,
- @Nullable final DictionaryInitializationListener listener,
+ @Nullable final String account,
final String dictNamePrefix,
- @Nullable final String account);
+ @Nullable final DictionaryInitializationListener listener);
@UsedForTesting
- void resetDictionariesForTesting(final Context context, final Locale[] locales,
- final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles,
+ void resetDictionariesForTesting(
+ final Context context,
+ final Locale[] locales,
+ final ArrayList<String> dictionaryTypes,
+ final HashMap<String, File> dictionaryFiles,
final Map<String, Map<String, String>> additionalDictAttributes,
@Nullable final String account);
@@ -118,10 +143,6 @@ public interface DictionaryFacilitator {
boolean hasAtLeastOneUninitializedMainDictionary();
- boolean hasPersonalizationDictionary();
-
- void flushPersonalizationDictionary();
-
void waitForLoadingMainDictionaries(final long timeout, final TimeUnit unit)
throws InterruptedException;
@@ -129,10 +150,6 @@ public interface DictionaryFacilitator {
void waitForLoadingDictionariesForTesting(final long timeout, final TimeUnit unit)
throws InterruptedException;
- boolean isUserDictionaryEnabled();
-
- void addWordToUserDictionary(final Context context, final String word);
-
void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized,
@Nonnull final NgramContext ngramContext, final int timeStampInSeconds,
final boolean blockPotentiallyOffensive);
@@ -142,9 +159,12 @@ public interface DictionaryFacilitator {
// TODO: Revise the way to fusion suggestion results.
SuggestionResults getSuggestionResults(final WordComposer composer,
final NgramContext ngramContext, final long proximityInfoHandle,
- final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId);
+ final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId,
+ final int inputStyle, final KeyboardLayout keyboardLayout);
+
+ boolean isValidSpellingWord(final String word);
- boolean isValidWord(final String word, final boolean ignoreCase);
+ boolean isValidSuggestionWord(final String word);
int getFrequency(final String word);
@@ -152,21 +172,6 @@ public interface DictionaryFacilitator {
void clearUserHistoryDictionary();
- // This method gets called only when the IME receives a notification to remove the
- // personalization dictionary.
- void clearPersonalizationDictionary();
-
- void clearContextualDictionary();
-
- void addEntriesToPersonalizationDictionary(
- final PersonalizationDataChunk personalizationDataChunk,
- final SpacingAndPunctuations spacingAndPunctuations,
- final UpdateEntriesForInputEventsCallback callback);
-
- @UsedForTesting
- void addPhraseToContextualDictionary(final String[] phrase, final int probability,
- final int bigramProbabilityForWords, final int bigramProbabilityForPhrases);
-
void dumpDictionaryForDebug(final String dictName);
ArrayList<Pair<String, DictionaryStats>> getStatsOfEnabledSubDicts();
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
index 167501118..dd34faef8 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
@@ -23,16 +23,12 @@ import android.util.Pair;
import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.ExpandableBinaryDictionary.UpdateEntriesForInputEventsCallback;
+import com.android.inputmethod.keyboard.KeyboardLayout;
import com.android.inputmethod.latin.NgramContext.WordInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.common.Constants;
-import com.android.inputmethod.latin.personalization.ContextualDictionary;
-import com.android.inputmethod.latin.personalization.PersonalizationDataChunk;
-import com.android.inputmethod.latin.personalization.PersonalizationDictionary;
import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
-import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
import com.android.inputmethod.latin.utils.DistracterFilter;
import com.android.inputmethod.latin.utils.DistracterFilterCheckingExactMatchesAndSuggestions;
import com.android.inputmethod.latin.utils.DistracterFilterCheckingIsInDictionary;
@@ -43,7 +39,6 @@ import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -78,42 +73,24 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
private DictionaryGroup[] mDictionaryGroups = new DictionaryGroup[] { new DictionaryGroup() };
private DictionaryGroup mMostProbableDictionaryGroup = mDictionaryGroups[0];
- private boolean mIsUserDictEnabled = false;
private volatile CountDownLatch mLatchForWaitingLoadingMainDictionaries = new CountDownLatch(0);
// To synchronize assigning mDictionaryGroup to ensure closing dictionaries.
private final Object mLock = new Object();
private final DistracterFilter mDistracterFilter;
- private final PersonalizationHelperForDictionaryFacilitator mPersonalizationHelper;
-
- private static final String[] DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS =
- new String[] {
- Dictionary.TYPE_MAIN,
- Dictionary.TYPE_USER_HISTORY,
- Dictionary.TYPE_PERSONALIZATION,
- Dictionary.TYPE_USER,
- Dictionary.TYPE_CONTACTS,
- Dictionary.TYPE_CONTEXTUAL
- };
public static final Map<String, Class<? extends ExpandableBinaryDictionary>>
DICT_TYPE_TO_CLASS = new HashMap<>();
static {
DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_USER_HISTORY, UserHistoryDictionary.class);
- DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_PERSONALIZATION, PersonalizationDictionary.class);
DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_USER, UserBinaryDictionary.class);
DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_CONTACTS, ContactsBinaryDictionary.class);
- DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_CONTEXTUAL, ContextualDictionary.class);
}
private static final String DICT_FACTORY_METHOD_NAME = "getDictionary";
private static final Class<?>[] DICT_FACTORY_METHOD_ARG_TYPES =
new Class[] { Context.class, Locale.class, File.class, String.class, String.class };
- private static final String[] SUB_DICT_TYPES =
- Arrays.copyOfRange(DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS, 1 /* start */,
- DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS.length);
-
/**
* Returns whether this facilitator is exactly for this list of locales.
*
@@ -257,23 +234,18 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
public DictionaryFacilitatorImpl() {
mDistracterFilter = DistracterFilter.EMPTY_DISTRACTER_FILTER;
- mPersonalizationHelper = null;
}
public DictionaryFacilitatorImpl(final Context context) {
mDistracterFilter = new DistracterFilterCheckingExactMatchesAndSuggestions(context);
- mPersonalizationHelper =
- new PersonalizationHelperForDictionaryFacilitator(context, mDistracterFilter);
}
public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes) {
mDistracterFilter.updateEnabledSubtypes(enabledSubtypes);
- mPersonalizationHelper.updateEnabledSubtypes(enabledSubtypes);
}
// TODO: remove this, it's confusing with seamless multiple language switching
public void setIsMonolingualUser(final boolean isMonolingualUser) {
- mPersonalizationHelper.setIsMonolingualUser(isMonolingualUser);
}
public boolean isActive() {
@@ -370,16 +342,6 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
}
}
- public void resetDictionaries(final Context context, final Locale[] newLocales,
- final boolean useContactsDict, final boolean usePersonalizedDicts,
- final boolean forceReloadMainDictionary,
- @Nullable final String account,
- final DictionaryInitializationListener listener) {
- resetDictionariesWithDictNamePrefix(context, newLocales, useContactsDict,
- usePersonalizedDicts, forceReloadMainDictionary, listener, "" /* dictNamePrefix */,
- account);
- }
-
@Nullable
static DictionaryGroup findDictionaryGroupWithLocale(final DictionaryGroup[] dictionaryGroups,
final Locale locale) {
@@ -391,14 +353,15 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
return null;
}
- public void resetDictionariesWithDictNamePrefix(final Context context,
+ public void resetDictionaries(
+ final Context context,
final Locale[] newLocales,
final boolean useContactsDict,
final boolean usePersonalizedDicts,
final boolean forceReloadMainDictionary,
- @Nullable final DictionaryInitializationListener listener,
+ @Nullable final String account,
final String dictNamePrefix,
- @Nullable final String account) {
+ @Nullable final DictionaryInitializationListener listener) {
final HashMap<Locale, ArrayList<String>> existingDictionariesToCleanup = new HashMap<>();
// TODO: Make subDictTypesToUse configurable by resource or a static final list.
final HashSet<String> subDictTypesToUse = new HashSet<>();
@@ -408,8 +371,6 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
}
if (usePersonalizedDicts) {
subDictTypesToUse.add(Dictionary.TYPE_USER_HISTORY);
- subDictTypesToUse.add(Dictionary.TYPE_PERSONALIZATION);
- subDictTypesToUse.add(Dictionary.TYPE_CONTEXTUAL);
}
// Gather all dictionaries. We'll remove them from the list to clean up later.
@@ -421,7 +382,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
if (null == currentDictionaryGroupForLocale) {
continue;
}
- for (final String dictType : SUB_DICT_TYPES) {
+ for (final String dictType : DYNAMIC_DICTIONARY_TYPES) {
if (currentDictionaryGroupForLocale.hasDict(dictType, account)) {
dictTypeForLocale.add(dictType);
}
@@ -473,7 +434,6 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
oldDictionaryGroups = mDictionaryGroups;
mDictionaryGroups = newDictionaryGroups;
mMostProbableDictionaryGroup = newDictionaryGroups[0];
- mIsUserDictEnabled = UserBinaryDictionary.isEnabled(context);
if (hasAtLeastOneUninitializedMainDictionary()) {
asyncReloadUninitializedMainDictionaries(context, newLocales, listener);
}
@@ -581,14 +541,11 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
mDictionaryGroups = new DictionaryGroup[] { mMostProbableDictionaryGroup };
}
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
- for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
+ for (final String dictType : ALL_DICTIONARY_TYPES) {
dictionaryGroup.closeDict(dictType);
}
}
mDistracterFilter.close();
- if (mPersonalizationHelper != null) {
- mPersonalizationHelper.close();
- }
}
@UsedForTesting
@@ -620,30 +577,6 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
return false;
}
- public boolean hasPersonalizationDictionary() {
- final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
- for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
- if (dictionaryGroup.hasDict(Dictionary.TYPE_PERSONALIZATION, null /* account */)) {
- return true;
- }
- }
- return false;
- }
-
- public void flushPersonalizationDictionary() {
- final HashSet<ExpandableBinaryDictionary> personalizationDictsUsedForSuggestion =
- new HashSet<>();
- final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
- for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
- final ExpandableBinaryDictionary personalizationDictUsedForSuggestion =
- dictionaryGroup.getSubDict(Dictionary.TYPE_PERSONALIZATION);
- personalizationDictsUsedForSuggestion.add(personalizationDictUsedForSuggestion);
- }
- mPersonalizationHelper.flushPersonalizationDictionariesToUpdate(
- personalizationDictsUsedForSuggestion);
- mDistracterFilter.close();
- }
-
public void waitForLoadingMainDictionaries(final long timeout, final TimeUnit unit)
throws InterruptedException {
mLatchForWaitingLoadingMainDictionaries.await(timeout, unit);
@@ -661,19 +594,6 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
}
}
- public boolean isUserDictionaryEnabled() {
- return mIsUserDictEnabled;
- }
-
- public void addWordToUserDictionary(final Context context, final String word) {
- final Locale locale = getMostProbableLocale();
- if (locale == null) {
- return;
- }
- // TODO: add a toast telling what language this is being added to?
- UserBinaryDictionary.addWordToUserDictionary(context, locale, word);
- }
-
public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized,
@Nonnull final NgramContext ngramContext, final int timeStampInSeconds,
final boolean blockPotentiallyOffensive) {
@@ -706,8 +626,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
final String lowerCasedWord = word.toLowerCase(dictionaryGroup.mLocale);
final String secondWord;
if (wasAutoCapitalized) {
- if (isValidWord(word, false /* ignoreCase */)
- && !isValidWord(lowerCasedWord, false /* ignoreCase */)) {
+ if (isValidSuggestionWord(word) && !isValidSuggestionWord(lowerCasedWord)) {
// If the word was auto-capitalized and exists only as a capitalized word in the
// dictionary, then we must not downcase it before registering it. For example,
// the name of the contacts in start-of-sentence position would come here with the
@@ -755,21 +674,21 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
public void removeWordFromPersonalizedDicts(final String word) {
removeWord(Dictionary.TYPE_USER_HISTORY, word);
- removeWord(Dictionary.TYPE_PERSONALIZATION, word);
- removeWord(Dictionary.TYPE_CONTEXTUAL, word);
}
// TODO: Revise the way to fusion suggestion results.
- public SuggestionResults getSuggestionResults(final WordComposer composer,
- final NgramContext ngramContext, final long proximityInfoHandle,
- final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId) {
+ @Override
+ public SuggestionResults getSuggestionResults(WordComposer composer,
+ NgramContext ngramContext, long proximityInfoHandle,
+ SettingsValuesForSuggestion settingsValuesForSuggestion, int sessionId,
+ int inputStyle, KeyboardLayout keyboardLayout) {
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
final SuggestionResults suggestionResults = new SuggestionResults(
SuggestedWords.MAX_SUGGESTIONS, ngramContext.isBeginningOfSentenceContext());
final float[] weightOfLangModelVsSpatialModel =
new float[] { Dictionary.NOT_A_WEIGHT_OF_LANG_MODEL_VS_SPATIAL_MODEL };
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
- for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
+ for (final String dictType : DICTIONARY_TYPES_FOR_SUGGESTIONS) {
final Dictionary dictionary = dictionaryGroup.getDict(dictType);
if (null == dictionary) continue;
final float weightForLocale = composer.isBatchMode()
@@ -789,7 +708,15 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
return suggestionResults;
}
- public boolean isValidWord(final String word, final boolean ignoreCase) {
+ public boolean isValidSpellingWord(final String word) {
+ return isValidWord(word, DICTIONARY_TYPES_FOR_SPELLING);
+ }
+
+ public boolean isValidSuggestionWord(final String word) {
+ return isValidWord(word, DICTIONARY_TYPES_FOR_SUGGESTIONS);
+ }
+
+ private boolean isValidWord(final String word, final String[] dictionariesToCheck) {
if (TextUtils.isEmpty(word)) {
return false;
}
@@ -798,15 +725,13 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
if (dictionaryGroup.mLocale == null) {
continue;
}
- final String lowerCasedWord = word.toLowerCase(dictionaryGroup.mLocale);
- for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
+ for (final String dictType : dictionariesToCheck) {
final Dictionary dictionary = dictionaryGroup.getDict(dictType);
// Ideally the passed map would come out of a {@link java.util.concurrent.Future} and
// would be immutable once it's finished initializing, but concretely a null test is
// probably good enough for the time being.
if (null == dictionary) continue;
- if (dictionary.isValidWord(word)
- || (ignoreCase && dictionary.isValidWord(lowerCasedWord))) {
+ if (dictionary.isValidWord(word)) {
return true;
}
}
@@ -822,7 +747,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
int maxFreq = Dictionary.NOT_A_PROBABILITY;
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
- for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
+ for (final String dictType : ALL_DICTIONARY_TYPES) {
final Dictionary dictionary = dictionaryGroup.getDict(dictType);
if (dictionary == null) continue;
final int tempFreq;
@@ -861,64 +786,6 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
clearSubDictionary(Dictionary.TYPE_USER_HISTORY);
}
- // This method gets called only when the IME receives a notification to remove the
- // personalization dictionary.
- public void clearPersonalizationDictionary() {
- clearSubDictionary(Dictionary.TYPE_PERSONALIZATION);
- mPersonalizationHelper.clearDictionariesToUpdate();
- }
-
- public void clearContextualDictionary() {
- clearSubDictionary(Dictionary.TYPE_CONTEXTUAL);
- }
-
- public void addEntriesToPersonalizationDictionary(
- final PersonalizationDataChunk personalizationDataChunk,
- final SpacingAndPunctuations spacingAndPunctuations,
- final UpdateEntriesForInputEventsCallback callback) {
- mPersonalizationHelper.updateEntriesOfPersonalizationDictionaries(
- getMostProbableLocale(), personalizationDataChunk, spacingAndPunctuations,
- callback);
- }
-
- @UsedForTesting
- public void addPhraseToContextualDictionary(final String[] phrase, final int probability,
- final int bigramProbabilityForWords, final int bigramProbabilityForPhrases) {
- // TODO: we're inserting the phrase into the dictionary for the active language. Rethink
- // this a bit from a theoretical point of view.
- final ExpandableBinaryDictionary contextualDict =
- getDictionaryGroupForMostProbableLanguage().getSubDict(Dictionary.TYPE_CONTEXTUAL);
- if (contextualDict == null) {
- return;
- }
- NgramContext ngramContext = NgramContext.BEGINNING_OF_SENTENCE;
- for (int i = 0; i < phrase.length; i++) {
- final String[] subPhrase = Arrays.copyOfRange(phrase, i /* start */, phrase.length);
- final String subPhraseStr = TextUtils.join(Constants.WORD_SEPARATOR, subPhrase);
- contextualDict.addUnigramEntryWithCheckingDistracter(
- subPhraseStr, probability, null /* shortcutTarget */,
- Dictionary.NOT_A_PROBABILITY /* shortcutFreq */,
- false /* isNotAWord */, false /* isPossiblyOffensive */,
- BinaryDictionary.NOT_A_VALID_TIMESTAMP,
- DistracterFilter.EMPTY_DISTRACTER_FILTER);
- contextualDict.addNgramEntry(ngramContext, subPhraseStr,
- bigramProbabilityForPhrases, BinaryDictionary.NOT_A_VALID_TIMESTAMP);
-
- if (i < phrase.length - 1) {
- contextualDict.addUnigramEntryWithCheckingDistracter(
- phrase[i], probability, null /* shortcutTarget */,
- Dictionary.NOT_A_PROBABILITY /* shortcutFreq */,
- false /* isNotAWord */, false /* isPossiblyOffensive */,
- BinaryDictionary.NOT_A_VALID_TIMESTAMP,
- DistracterFilter.EMPTY_DISTRACTER_FILTER);
- contextualDict.addNgramEntry(ngramContext, phrase[i],
- bigramProbabilityForWords, BinaryDictionary.NOT_A_VALID_TIMESTAMP);
- }
- ngramContext =
- ngramContext.getNextNgramContext(new NgramContext.WordInfo(phrase[i]));
- }
- }
-
public void dumpDictionaryForDebug(final String dictName) {
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
@@ -936,7 +803,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
final ArrayList<Pair<String, DictionaryStats>> statsOfEnabledSubDicts = new ArrayList<>();
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
- for (final String dictType : SUB_DICT_TYPES) {
+ for (final String dictType : DYNAMIC_DICTIONARY_TYPES) {
final ExpandableBinaryDictionary dictionary = dictionaryGroup.getSubDict(dictType);
if (dictionary == null) continue;
statsOfEnabledSubDicts.add(new Pair<>(dictType, dictionary.getDictionaryStats()));
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java
index 13bd15101..85ecf93f3 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java
@@ -28,10 +28,11 @@ import android.util.LruCache;
/**
* Cache for dictionary facilitators of multiple locales.
- * This class automatically creates and releases facilitator instances using LRU policy.
+ * This class automatically creates and releases up to 3 facilitator instances using LRU policy.
*/
public class DictionaryFacilitatorLruCache {
- static final String TAG = DictionaryFacilitatorLruCache.class.getSimpleName();
+ private static final String TAG = "DictionaryFacilitatorLruCache";
+ private static final int MAX_DICTIONARY_FACILITATOR_COUNT = 3;
private static final int WAIT_FOR_LOADING_MAIN_DICT_IN_MILLISECONDS = 1000;
private static final int MAX_RETRY_COUNT_FOR_WAITING_FOR_LOADING_DICT = 5;
@@ -74,10 +75,10 @@ public class DictionaryFacilitatorLruCache {
private final Object mLock = new Object();
private boolean mUseContactsDictionary = false;
- public DictionaryFacilitatorLruCache(final Context context, final int maxSize,
- final String dictionaryNamePrefix) {
+ public DictionaryFacilitatorLruCache(final Context context, final String dictionaryNamePrefix) {
mContext = context;
- mLruCache = new DictionaryFacilitatorLruCacheInner(mCachedLocales, maxSize);
+ mLruCache = new DictionaryFacilitatorLruCacheInner(
+ mCachedLocales, MAX_DICTIONARY_FACILITATOR_COUNT);
mDictionaryNamePrefix = dictionaryNamePrefix;
}
@@ -103,11 +104,10 @@ public class DictionaryFacilitatorLruCache {
private void resetDictionariesForLocaleLocked(final DictionaryFacilitator dictionaryFacilitator,
final Locale locale) {
// Note: Given that personalized dictionaries are not used here; we can pass null account.
- dictionaryFacilitator.resetDictionariesWithDictNamePrefix(mContext, new Locale[] { locale },
+ dictionaryFacilitator.resetDictionaries(mContext, new Locale[]{locale},
mUseContactsDictionary, false /* usePersonalizedDicts */,
- false /* forceReloadMainDictionary */, null /* listener */,
- mDictionaryNamePrefix,
- null /* account */);
+ false /* forceReloadMainDictionary */, null /* account */,
+ mDictionaryNamePrefix, null /* listener */);
}
public void setUseContactsDictionary(final boolean useContectsDictionary) {
@@ -128,7 +128,7 @@ public class DictionaryFacilitatorLruCache {
public DictionaryFacilitator get(final Locale locale) {
DictionaryFacilitator dictionaryFacilitator = mLruCache.get(locale);
if (dictionaryFacilitator != null) {
- // dictionary falicitator for the locale is in the cache.
+ // dictionary facilitator for the locale is in the cache.
return dictionaryFacilitator;
}
synchronized (mLock) {
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 1c54a20e7..87d46e226 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -22,8 +22,8 @@ import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.common.ComposedData;
-import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.common.FileUtils;
+import com.android.inputmethod.latin.define.DecoderSpecificConstants;
import com.android.inputmethod.latin.makedict.DictionaryHeader;
import com.android.inputmethod.latin.makedict.FormatSpec;
import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
@@ -73,7 +73,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
/**
* The maximum length of a word in this dictionary.
*/
- protected static final int MAX_WORD_LENGTH = Constants.DICTIONARY_MAX_WORD_LENGTH;
+ protected static final int MAX_WORD_LENGTH =
+ DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH;
private static final int DICTIONARY_FORMAT_VERSION = FormatSpec.VERSION4;
diff --git a/java/src/com/android/inputmethod/latin/LastComposedWord.java b/java/src/com/android/inputmethod/latin/LastComposedWord.java
index 9fcdb2229..426d33e6d 100644
--- a/java/src/com/android/inputmethod/latin/LastComposedWord.java
+++ b/java/src/com/android/inputmethod/latin/LastComposedWord.java
@@ -19,8 +19,8 @@ package com.android.inputmethod.latin;
import android.text.TextUtils;
import com.android.inputmethod.event.Event;
-import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.common.InputPointers;
+import com.android.inputmethod.latin.define.DecoderSpecificConstants;
import java.util.ArrayList;
@@ -53,7 +53,7 @@ public final class LastComposedWord {
public final NgramContext mNgramContext;
public final int mCapitalizedMode;
public final InputPointers mInputPointers =
- new InputPointers(Constants.DICTIONARY_MAX_WORD_LENGTH);
+ new InputPointers(DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH);
private boolean mActive;
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 622cdb0a6..74ef6481a 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -20,7 +20,6 @@ import static com.android.inputmethod.latin.common.Constants.ImeOption.FORCE_ASC
import static com.android.inputmethod.latin.common.Constants.ImeOption.NO_MICROPHONE;
import static com.android.inputmethod.latin.common.Constants.ImeOption.NO_MICROPHONE_COMPAT;
-import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -32,13 +31,11 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.inputmethodservice.InputMethodService;
import android.media.AudioManager;
-import android.os.Build;
import android.os.Debug;
import android.os.IBinder;
import android.os.Message;
import android.preference.PreferenceManager;
import android.text.InputType;
-import android.text.TextUtils;
import android.util.Log;
import android.util.PrintWriterPrinter;
import android.util.Printer;
@@ -47,18 +44,14 @@ import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
-import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.CompletionInfo;
-import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodSubtype;
-import android.widget.TextView;
import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.compat.CursorAnchorInfoCompatWrapper;
import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
import com.android.inputmethod.compat.ViewOutlineProviderCompatUtils;
import com.android.inputmethod.compat.ViewOutlineProviderCompatUtils.InsetsUpdater;
@@ -72,7 +65,6 @@ import com.android.inputmethod.keyboard.KeyboardActionListener;
import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.MainKeyboardView;
-import com.android.inputmethod.keyboard.TextDecoratorUi;
import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.common.Constants;
@@ -81,9 +73,7 @@ import com.android.inputmethod.latin.common.InputPointers;
import com.android.inputmethod.latin.define.DebugFlags;
import com.android.inputmethod.latin.define.ProductionFlags;
import com.android.inputmethod.latin.inputlogic.InputLogic;
-import com.android.inputmethod.latin.personalization.ContextualDictionaryUpdater;
import com.android.inputmethod.latin.personalization.DictionaryDecayBroadcastReciever;
-import com.android.inputmethod.latin.personalization.PersonalizationDictionaryUpdater;
import com.android.inputmethod.latin.personalization.PersonalizationHelper;
import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.settings.SettingsActivity;
@@ -92,8 +82,6 @@ import com.android.inputmethod.latin.suggestions.SuggestionStripView;
import com.android.inputmethod.latin.suggestions.SuggestionStripViewAccessor;
import com.android.inputmethod.latin.touchinputconsumer.GestureConsumer;
import com.android.inputmethod.latin.utils.ApplicationUtils;
-import com.android.inputmethod.latin.utils.CapsModeUtils;
-import com.android.inputmethod.latin.utils.CursorAnchorInfoUtils;
import com.android.inputmethod.latin.utils.DialogUtils;
import com.android.inputmethod.latin.utils.ImportantNoticeUtils;
import com.android.inputmethod.latin.utils.IntentUtils;
@@ -139,19 +127,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private static final String SCHEME_PACKAGE = "package";
final Settings mSettings;
- private final DictionaryFacilitator mDictionaryFacilitator =
- DictionaryFacilitatorProvider.newDictionaryFacilitator(this /* context */);
- // TODO: Move from LatinIME.
- private final PersonalizationDictionaryUpdater mPersonalizationDictionaryUpdater =
- new PersonalizationDictionaryUpdater(this /* context */, mDictionaryFacilitator);
- private final ContextualDictionaryUpdater mContextualDictionaryUpdater =
- new ContextualDictionaryUpdater(this /* context */, mDictionaryFacilitator,
- new Runnable() {
- @Override
- public void run() {
- mHandler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_NONE);
- }
- });
+ private final DictionaryFacilitator mDictionaryFacilitator =
+ DictionaryFacilitatorProvider.newDictionaryFacilitator(this /* context */);
final InputLogic mInputLogic = new InputLogic(this /* LatinIME */,
this /* SuggestionStripViewAccessor */, mDictionaryFacilitator);
// We expect to have only one decoder in almost all cases, hence the default capacity of 1.
@@ -162,7 +139,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private View mInputView;
private InsetsUpdater mInsetsUpdater;
private SuggestionStripView mSuggestionStripView;
- private TextView mExtractEditText;
private RichInputMethodManager mRichImm;
@UsedForTesting final KeyboardSwitcher mKeyboardSwitcher;
@@ -642,11 +618,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void refreshPersonalizationDictionarySession(
final SettingsValues currentSettingsValues) {
+ // TODO: Remove all existing personalized dictionaries.
mDictionaryFacilitator.setIsMonolingualUser(
mRichImm.isSystemLocaleSameAsLocaleOfAllEnabledSubtypesOfEnabledImes());
- mPersonalizationDictionaryUpdater.onLoadSettings(
- currentSettingsValues.mUsePersonalizedDicts);
- mContextualDictionaryUpdater.onLoadSettings(currentSettingsValues.mUsePersonalizedDicts);
final boolean shouldKeepUserHistoryDictionaries;
if (currentSettingsValues.mUsePersonalizedDicts) {
shouldKeepUserHistoryDictionaries = true;
@@ -705,7 +679,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mDictionaryFacilitator.resetDictionaries(this /* context */, locales,
settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts,
false /* forceReloadMainDictionary */,
- settingsValues.mAccount,
+ settingsValues.mAccount, "" /* dictNamePrefix */,
this /* DictionaryInitializationListener */);
if (settingsValues.mAutoCorrectionEnabledPerUserSettings) {
mInputLogic.mSuggest.setAutoCorrectionThreshold(
@@ -723,15 +697,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mDictionaryFacilitator.getLocales(), settingsValues.mUseContactsDict,
settingsValues.mUsePersonalizedDicts,
true /* forceReloadMainDictionary */,
- settingsValues.mAccount,
+ settingsValues.mAccount, "" /* dictNamePrefix */,
this /* DictionaryInitializationListener */);
}
@Override
public void onDestroy() {
mDictionaryFacilitator.closeDictionaries();
- mPersonalizationDictionaryUpdater.onDestroy();
- mContextualDictionaryUpdater.onDestroy();
mSettings.onDestroy();
NetworkConnectivityUtils.onDestroy(this /* context */);
unregisterReceiver(mRingerModeChangeReceiver);
@@ -793,57 +765,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (hasSuggestionStripView()) {
mSuggestionStripView.setListener(this, view);
}
- mInputLogic.setTextDecoratorUi(new TextDecoratorUi(this, view));
}
@Override
- public void setExtractView(final View view) {
- final TextView prevExtractEditText = mExtractEditText;
- super.setExtractView(view);
- TextView nextExtractEditText = null;
- if (view != null) {
- final View extractEditText = view.findViewById(android.R.id.inputExtractEditText);
- if (extractEditText instanceof TextView) {
- nextExtractEditText = (TextView)extractEditText;
- }
- }
- if (prevExtractEditText == nextExtractEditText) {
- return;
- }
- if (prevExtractEditText != null) {
- prevExtractEditText.getViewTreeObserver().removeOnPreDrawListener(
- mExtractTextViewPreDrawListener);
- }
- mExtractEditText = nextExtractEditText;
- if (mExtractEditText != null) {
- mExtractEditText.getViewTreeObserver().addOnPreDrawListener(
- mExtractTextViewPreDrawListener);
- }
- }
-
- void updateCursorAnchorInfo() {
- // CursorAnchorInfo is used on L and later.
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- if (isFullscreenMode() && mExtractEditText != null) {
- mInputLogic.onUpdateCursorAnchorInfo(
- CursorAnchorInfoUtils.extractFromTextView(mExtractEditText));
- }
- }
- }
-
- private final ViewTreeObserver.OnPreDrawListener mExtractTextViewPreDrawListener =
- new ViewTreeObserver.OnPreDrawListener() {
- @Override
- public boolean onPreDraw() {
- updateCursorAnchorInfo();
- return true;
- }
- };
-
- @Override
public void setCandidatesView(final View view) {
// To ensure that CandidatesView will never be set.
- return;
}
@Override
@@ -1050,8 +976,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
currentSettingsValues.mGestureTrailEnabled,
currentSettingsValues.mGestureFloatingPreviewTextEnabled);
- // Contextual dictionary should be updated for the current application.
- mContextualDictionaryUpdater.onStartInputView(editorInfo.packageName);
if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
}
@@ -1114,15 +1038,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- @Override
- public void onUpdateCursorAnchorInfo(final CursorAnchorInfo info) {
- if (isFullscreenMode()) {
- return;
- }
- mInputLogic.onUpdateCursorAnchorInfo(CursorAnchorInfoCompatWrapper.wrap(info));
- }
-
/**
* This is called when the user has clicked on the extracted text view,
* when running in fullscreen mode. The default implementation hides
@@ -1303,7 +1218,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void updateFullscreenMode() {
super.updateFullscreenMode();
- mInputLogic.onUpdateFullscreenMode(isFullscreenMode());
updateSoftInputWindowLayoutParameters();
}
@@ -1351,18 +1265,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return keyboard.getCoordinates(codePoints);
}
- // Callback for the {@link SuggestionStripView}, to call when the "add to dictionary" hint is
- // pressed.
- @Override
- public void addWordToUserDictionary(final String word) {
- if (TextUtils.isEmpty(word)) {
- // Probably never supposed to happen, but just in case.
- return;
- }
- mDictionaryFacilitator.addWordToUserDictionary(this /* context */, word);
- mInputLogic.onAddWordToUserDictionary();
- }
-
// Callback for the {@link SuggestionStripView}, to call when the important notice strip is
// pressed.
@Override
@@ -1557,19 +1459,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return null != mSuggestionStripView;
}
- @Override
- public boolean isShowingAddToDictionaryHint() {
- return hasSuggestionStripView() && mSuggestionStripView.isShowingAddToDictionaryHint();
- }
-
- @Override
- public void dismissAddToDictionaryHint() {
- if (!hasSuggestionStripView()) {
- return;
- }
- mSuggestionStripView.dismissAddToDictionaryHint();
- }
-
private void setSuggestedWords(final SuggestedWords suggestedWords) {
final SettingsValues currentSettingsValues = mSettings.getCurrent();
mInputLogic.setSuggestedWords(suggestedWords);
@@ -1631,7 +1520,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return;
}
mInputLogic.getSuggestedWords(mSettings.getCurrent(), keyboard.getProximityInfo(),
- mKeyboardSwitcher.getKeyboardShiftMode(), inputStyle, sequenceNumber, callback);
+ mKeyboardSwitcher.getKeyboardShiftMode(), inputStyle, sequenceNumber, callback,
+ keyboard.getKeyboardLayout());
}
@Override
@@ -1658,21 +1548,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
updateStateAfterInputTransaction(completeInputTransaction);
}
- @Override
- public void suggestAddingToDictionary(final String word, final boolean isFromSuggestionStrip) {
- if (!hasSuggestionStripView()) {
- return;
- }
- final String wordToShow;
- if (CapsModeUtils.isAutoCapsMode(mInputLogic.mLastComposedWord.mCapitalizedMode)) {
- wordToShow = word.toLowerCase(mDictionaryFacilitator.getMostProbableLocale());
- } else {
- wordToShow = word;
- }
- mSuggestionStripView.showAddToDictionaryHint(wordToShow,
- isFromSuggestionStrip /* shouldShowWordToSave */);
- }
-
// This will show either an empty suggestion strip (if prediction is enabled) or
// punctuation suggestions (if it's disabled).
@Override
@@ -1935,7 +1810,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mDictionaryFacilitator.resetDictionaries(this, new Locale[] { locale },
settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts,
false /* forceReloadMainDictionary */,
- settingsValues.mAccount,
+ settingsValues.mAccount, "", /* dictionaryNamePrefix */
this /* DictionaryInitializationListener */);
}
@@ -1943,7 +1818,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@UsedForTesting
/* package for test */ void clearPersonalizedDictionariesForTest() {
mDictionaryFacilitator.clearUserHistoryDictionary();
- mDictionaryFacilitator.clearPersonalizationDictionary();
}
@UsedForTesting
diff --git a/java/src/com/android/inputmethod/latin/NgramContext.java b/java/src/com/android/inputmethod/latin/NgramContext.java
index b47731229..86155e0be 100644
--- a/java/src/com/android/inputmethod/latin/NgramContext.java
+++ b/java/src/com/android/inputmethod/latin/NgramContext.java
@@ -19,9 +19,10 @@ package com.android.inputmethod.latin;
import android.text.TextUtils;
import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.common.StringUtils;
+import com.android.inputmethod.latin.define.DecoderSpecificConstants;
+import java.util.ArrayList;
import java.util.Arrays;
import javax.annotation.Nonnull;
@@ -38,6 +39,10 @@ public class NgramContext {
public static final NgramContext BEGINNING_OF_SENTENCE =
new NgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO);
+ public static final String BEGINNING_OF_SENTENCE_TAG = "<S>";
+
+ public static final String CONTEXT_SEPARATOR = " ";
+
/**
* Word information used to represent previous words information.
*/
@@ -106,14 +111,39 @@ public class NgramContext {
// Create next prevWordsInfo using current prevWordsInfo.
@Nonnull
public NgramContext getNextNgramContext(final WordInfo wordInfo) {
- final int nextPrevWordCount = Math.min(Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM,
- mPrevWordsCount + 1);
+ final int nextPrevWordCount = Math.min(
+ DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM, mPrevWordsCount + 1);
final WordInfo[] prevWordsInfo = new WordInfo[nextPrevWordCount];
prevWordsInfo[0] = wordInfo;
System.arraycopy(mPrevWordsInfo, 0, prevWordsInfo, 1, nextPrevWordCount - 1);
return new NgramContext(prevWordsInfo);
}
+
+ /**
+ * Extracts the previous words context.
+ *
+ * @return a String with the previous words separated by white space.
+ */
+ public String extractPrevWordsContext() {
+ final ArrayList<String> terms = new ArrayList<>();
+ for (int i = mPrevWordsInfo.length - 1; i >= 0; --i) {
+ if (mPrevWordsInfo[i] != null && mPrevWordsInfo[i].isValid()) {
+ final NgramContext.WordInfo wordInfo = mPrevWordsInfo[i];
+ if (wordInfo.mIsBeginningOfSentence) {
+ terms.add(BEGINNING_OF_SENTENCE_TAG);
+ } else {
+ final String term = wordInfo.mWord.toString();
+ if (!term.isEmpty()) {
+ terms.add(term);
+ }
+ }
+ }
+ }
+ return terms.size() == 0 ? BEGINNING_OF_SENTENCE_TAG
+ : TextUtils.join(CONTEXT_SEPARATOR, terms);
+ }
+
public boolean isValid() {
return mPrevWordsCount > 0 && mPrevWordsInfo[0].isValid();
}
diff --git a/java/src/com/android/inputmethod/latin/PersonalizationHelperForDictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/PersonalizationHelperForDictionaryFacilitator.java
deleted file mode 100644
index 8926c06b1..000000000
--- a/java/src/com/android/inputmethod/latin/PersonalizationHelperForDictionaryFacilitator.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2014 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;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import android.content.Context;
-import android.view.inputmethod.InputMethodSubtype;
-
-import com.android.inputmethod.latin.ExpandableBinaryDictionary.UpdateEntriesForInputEventsCallback;
-import com.android.inputmethod.latin.personalization.PersonalizationDataChunk;
-import com.android.inputmethod.latin.personalization.PersonalizationDictionary;
-import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
-import com.android.inputmethod.latin.utils.DistracterFilter;
-import com.android.inputmethod.latin.utils.DistracterFilterCheckingIsInDictionary;
-import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
-import com.android.inputmethod.latin.utils.WordInputEventForPersonalization;
-
-/**
- * Class for managing and updating personalization dictionaries.
- */
-public class PersonalizationHelperForDictionaryFacilitator {
- private final Context mContext;
- private final DistracterFilter mDistracterFilter;
- private final HashMap<String, HashSet<Locale>> mLangToLocalesMap = new HashMap<>();
- private final HashMap<Locale, ExpandableBinaryDictionary> mPersonalizationDictsToUpdate =
- new HashMap<>();
- private boolean mIsMonolingualUser = false;
-
- PersonalizationHelperForDictionaryFacilitator(final Context context,
- final DistracterFilter distracterFilter) {
- mContext = context;
- mDistracterFilter = distracterFilter;
- }
-
- public void close() {
- mLangToLocalesMap.clear();
- for (final ExpandableBinaryDictionary dict : mPersonalizationDictsToUpdate.values()) {
- dict.close();
- }
- mPersonalizationDictsToUpdate.clear();
- }
-
- public void clearDictionariesToUpdate() {
- for (final ExpandableBinaryDictionary dict : mPersonalizationDictsToUpdate.values()) {
- dict.clear();
- }
- mPersonalizationDictsToUpdate.clear();
- }
-
- public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes) {
- for (final InputMethodSubtype subtype : enabledSubtypes) {
- final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
- final String language = locale.getLanguage();
- final HashSet<Locale> locales = mLangToLocalesMap.get(language);
- if (locales != null) {
- locales.add(locale);
- } else {
- final HashSet<Locale> localeSet = new HashSet<>();
- localeSet.add(locale);
- mLangToLocalesMap.put(language, localeSet);
- }
- }
- }
-
- public void setIsMonolingualUser(final boolean isMonolingualUser) {
- mIsMonolingualUser = isMonolingualUser;
- }
-
- /**
- * Flush personalization dictionaries to dictionary files. Close dictionaries after writing
- * files except the dictionaries that is used for generating suggestions.
- *
- * @param personalizationDictsUsedForSuggestion the personalization dictionaries used for
- * generating suggestions that won't be closed.
- */
- public void flushPersonalizationDictionariesToUpdate(
- final HashSet<ExpandableBinaryDictionary> personalizationDictsUsedForSuggestion) {
- for (final ExpandableBinaryDictionary personalizationDict :
- mPersonalizationDictsToUpdate.values()) {
- personalizationDict.asyncFlushBinaryDictionary();
- if (!personalizationDictsUsedForSuggestion.contains(personalizationDict)) {
- // Close if the dictionary is not being used for suggestion.
- personalizationDict.close();
- }
- }
- mDistracterFilter.close();
- mPersonalizationDictsToUpdate.clear();
- }
-
- private ExpandableBinaryDictionary getPersonalizationDictToUpdate(final Context context,
- final Locale locale) {
- ExpandableBinaryDictionary personalizationDict = mPersonalizationDictsToUpdate.get(locale);
- if (personalizationDict != null) {
- return personalizationDict;
- }
- personalizationDict = PersonalizationDictionary.getDictionary(context, locale,
- null /* dictFile */, "" /* dictNamePrefix */, null /* account */);
- mPersonalizationDictsToUpdate.put(locale, personalizationDict);
- return personalizationDict;
- }
-
- private void updateEntriesOfPersonalizationDictionariesForLocale(final Locale locale,
- final PersonalizationDataChunk personalizationDataChunk,
- final SpacingAndPunctuations spacingAndPunctuations,
- final UpdateEntriesForInputEventsCallback callback) {
- final ExpandableBinaryDictionary personalizationDict =
- getPersonalizationDictToUpdate(mContext, locale);
- if (personalizationDict == null) {
- if (callback != null) {
- callback.onFinished();
- }
- return;
- }
- final ArrayList<WordInputEventForPersonalization> inputEvents =
- WordInputEventForPersonalization.createInputEventFrom(
- personalizationDataChunk.mTokens,
- personalizationDataChunk.mTimestampInSeconds, spacingAndPunctuations,
- locale, new DistracterFilterCheckingIsInDictionary(
- mDistracterFilter, personalizationDict));
- if (inputEvents == null || inputEvents.isEmpty()) {
- if (callback != null) {
- callback.onFinished();
- }
- return;
- }
- personalizationDict.updateEntriesForInputEvents(inputEvents, callback);
- }
-
- public void updateEntriesOfPersonalizationDictionaries(final Locale defaultLocale,
- final PersonalizationDataChunk personalizationDataChunk,
- final SpacingAndPunctuations spacingAndPunctuations,
- final UpdateEntriesForInputEventsCallback callback) {
- final String language = personalizationDataChunk.mDetectedLanguage;
- final HashSet<Locale> locales;
- if (mIsMonolingualUser && PersonalizationDataChunk.LANGUAGE_UNKNOWN.equals(language)
- && mLangToLocalesMap.size() == 1) {
- locales = mLangToLocalesMap.get(defaultLocale.getLanguage());
- } else {
- locales = mLangToLocalesMap.get(language);
- }
- if (locales == null || locales.isEmpty()) {
- if (callback != null) {
- callback.onFinished();
- }
- return;
- }
- final AtomicInteger remainingTaskCount = new AtomicInteger(locales.size());
- final UpdateEntriesForInputEventsCallback callbackForLocales =
- new UpdateEntriesForInputEventsCallback() {
- @Override
- public void onFinished() {
- if (remainingTaskCount.decrementAndGet() == 0) {
- // Update tasks for all locales have been finished.
- if (callback != null) {
- callback.onFinished();
- }
- }
- }
- };
- for (final Locale locale : locales) {
- updateEntriesOfPersonalizationDictionariesForLocale(locale, personalizationDataChunk,
- spacingAndPunctuations, callbackForLocales);
- }
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index 834f747d9..0210d7e18 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -16,14 +16,14 @@
package com.android.inputmethod.latin;
-import android.graphics.Color;
+import static com.android.inputmethod.latin.define.DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH;
+
import android.inputmethodservice.InputMethodService;
import android.os.Build;
import android.os.Bundle;
import android.text.SpannableStringBuilder;
-import android.text.Spanned;
import android.text.TextUtils;
-import android.text.style.BackgroundColorSpan;
+import android.text.style.CharacterStyle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.inputmethod.CompletionInfo;
@@ -35,7 +35,9 @@ import android.view.inputmethod.InputMethodManager;
import com.android.inputmethod.compat.InputConnectionCompatUtils;
import com.android.inputmethod.latin.common.Constants;
+import com.android.inputmethod.latin.common.UnicodeSurrogate;
import com.android.inputmethod.latin.common.StringUtils;
+import com.android.inputmethod.latin.define.DecoderSpecificConstants;
import com.android.inputmethod.latin.inputlogic.PrivateCommandPerformer;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
import com.android.inputmethod.latin.utils.CapsModeUtils;
@@ -61,9 +63,9 @@ public final class RichInputConnection implements PrivateCommandPerformer {
private static final boolean DEBUG_PREVIOUS_TEXT = false;
private static final boolean DEBUG_BATCH_NESTING = false;
// Provision for long words and separators between the words.
- private static final int LOOKBACK_CHARACTER_NUM = Constants.DICTIONARY_MAX_WORD_LENGTH
- * (Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM + 1) /* words */
- + Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM /* separators */;
+ private static final int LOOKBACK_CHARACTER_NUM = DICTIONARY_MAX_WORD_LENGTH
+ * (DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM + 1) /* words */
+ + DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM /* separators */;
private static final int INVALID_CURSOR_POSITION = -1;
/**
@@ -91,16 +93,10 @@ public final class RichInputConnection implements PrivateCommandPerformer {
private final StringBuilder mComposingText = new StringBuilder();
/**
- * This variable is a temporary object used in
- * {@link #commitTextWithBackgroundColor(CharSequence,int,int,int)} to avoid object creation.
+ * This variable is a temporary object used in {@link #commitText(CharSequence,int)}
+ * to avoid object creation.
*/
private SpannableStringBuilder mTempObjectForCommitText = new SpannableStringBuilder();
- /**
- * This variable is used to track whether the last committed text had the background color or
- * not.
- * TODO: Omit this flag if possible.
- */
- private boolean mLastCommittedTextHasBackgroundColor = false;
private final InputMethodService mParent;
InputConnection mIC;
@@ -239,39 +235,18 @@ public final class RichInputConnection implements PrivateCommandPerformer {
// it works, but it's wrong and should be fixed.
mCommittedTextBeforeComposingText.append(mComposingText);
mComposingText.setLength(0);
- // TODO: Clear this flag in setComposingRegion() and setComposingText() as well if needed.
- mLastCommittedTextHasBackgroundColor = false;
if (null != mIC) {
mIC.finishComposingText();
}
}
/**
- * Synonym of {@code commitTextWithBackgroundColor(text, newCursorPosition, Color.TRANSPARENT}.
+ * Calls {@link InputConnection#commitText(CharSequence, int)}.
+ *
* @param text The text to commit. This may include styles.
- * See {@link InputConnection#commitText(CharSequence, int)}.
* @param newCursorPosition The new cursor position around the text.
- * See {@link InputConnection#commitText(CharSequence, int)}.
*/
public void commitText(final CharSequence text, final int newCursorPosition) {
- commitTextWithBackgroundColor(text, newCursorPosition, Color.TRANSPARENT, text.length());
- }
-
- /**
- * Calls {@link InputConnection#commitText(CharSequence, int)} with the given background color.
- * @param text The text to commit. This may include styles.
- * See {@link InputConnection#commitText(CharSequence, int)}.
- * @param newCursorPosition The new cursor position around the text.
- * See {@link InputConnection#commitText(CharSequence, int)}.
- * @param color The background color to be attached. Set {@link Color#TRANSPARENT} to disable
- * the background color. Note that this method specifies {@link BackgroundColorSpan} with
- * {@link Spanned#SPAN_COMPOSING} flag, meaning that the background color persists until
- * {@link #finishComposingText()} is called.
- * @param coloredTextLength the length of text, in Java chars, which should be rendered with
- * the given background color.
- */
- public void commitTextWithBackgroundColor(final CharSequence text, final int newCursorPosition,
- final int color, final int coloredTextLength) {
if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
mCommittedTextBeforeComposingText.append(text);
@@ -281,44 +256,32 @@ public final class RichInputConnection implements PrivateCommandPerformer {
mExpectedSelStart += text.length() - mComposingText.length();
mExpectedSelEnd = mExpectedSelStart;
mComposingText.setLength(0);
- mLastCommittedTextHasBackgroundColor = false;
if (null != mIC) {
- if (color == Color.TRANSPARENT) {
- mIC.commitText(text, newCursorPosition);
- } else {
- mTempObjectForCommitText.clear();
- mTempObjectForCommitText.append(text);
- final BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(color);
- final int spanLength = Math.min(coloredTextLength, text.length());
- mTempObjectForCommitText.setSpan(backgroundColorSpan, 0, spanLength,
- Spanned.SPAN_COMPOSING | Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- mIC.commitText(mTempObjectForCommitText, newCursorPosition);
- mLastCommittedTextHasBackgroundColor = true;
+ mTempObjectForCommitText.clear();
+ mTempObjectForCommitText.append(text);
+ final CharacterStyle[] spans = mTempObjectForCommitText.getSpans(
+ 0, text.length(), CharacterStyle.class);
+ for (final CharacterStyle span : spans) {
+ final int spanStart = mTempObjectForCommitText.getSpanStart(span);
+ final int spanEnd = mTempObjectForCommitText.getSpanEnd(span);
+ final int spanFlags = mTempObjectForCommitText.getSpanFlags(span);
+ // We have to adjust the end of the span to include an additional character.
+ // This is to avoid splitting a unicode surrogate pair.
+ // See com.android.inputmethod.latin.common.Constants.UnicodeSurrogate
+ // See https://b.corp.google.com/issues/19255233
+ if (0 < spanEnd && spanEnd < mTempObjectForCommitText.length()) {
+ final char spanEndChar = mTempObjectForCommitText.charAt(spanEnd - 1);
+ final char nextChar = mTempObjectForCommitText.charAt(spanEnd);
+ if (UnicodeSurrogate.isLowSurrogate(spanEndChar)
+ && UnicodeSurrogate.isHighSurrogate(nextChar)) {
+ mTempObjectForCommitText.setSpan(span, spanStart, spanEnd + 1, spanFlags);
+ }
+ }
}
+ mIC.commitText(mTempObjectForCommitText, newCursorPosition);
}
}
- /**
- * Removes the background color from the highlighted text if necessary. Should be called while
- * there is no on-going composing text.
- *
- * <p>CAVEAT: This method internally calls {@link InputConnection#finishComposingText()}.
- * Be careful of any unexpected side effects.</p>
- */
- public void removeBackgroundColorFromHighlightedTextIfNecessary() {
- // TODO: We haven't yet full tested if we really need to check this flag or not. Omit this
- // flag if everything works fine without this condition.
- if (!mLastCommittedTextHasBackgroundColor) {
- return;
- }
- if (mComposingText.length() > 0) {
- Log.e(TAG, "clearSpansWithComposingFlags should be called when composing text is " +
- "empty. mComposingText=" + mComposingText);
- return;
- }
- finishComposingText();
- }
-
public CharSequence getSelectedText(final int flags) {
return (null == mIC) ? null : mIC.getSelectedText(flags);
}
@@ -946,8 +909,6 @@ public final class RichInputConnection implements PrivateCommandPerformer {
}
}
- private boolean mCursorAnchorInfoMonitorEnabled = false;
-
/**
* Requests the editor to call back {@link InputMethodManager#updateCursorAnchorInfo}.
* @param enableMonitor {@code true} to request the editor to call back the method whenever the
@@ -962,23 +923,10 @@ public final class RichInputConnection implements PrivateCommandPerformer {
public boolean requestCursorUpdates(final boolean enableMonitor,
final boolean requestImmediateCallback) {
mIC = mParent.getCurrentInputConnection();
- final boolean scheduled;
- if (null != mIC) {
- scheduled = InputConnectionCompatUtils.requestCursorUpdates(mIC, enableMonitor,
- requestImmediateCallback);
- } else {
- scheduled = false;
+ if (mIC == null) {
+ return false;
}
- mCursorAnchorInfoMonitorEnabled = (scheduled && enableMonitor);
- return scheduled;
- }
-
- /**
- * @return {@code true} if the application reported that the monitor mode of
- * {@link InputMethodService#onUpdateCursorAnchorInfo(android.view.inputmethod.CursorAnchorInfo)}
- * is currently enabled.
- */
- public boolean isCursorAnchorInfoMonitorEnabled() {
- return mCursorAnchorInfoMonitorEnabled;
+ return InputConnectionCompatUtils.requestCursorUpdates(
+ mIC, enableMonitor, requestImmediateCallback);
}
}
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 0bf0f687a..ddb2b5358 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -18,6 +18,7 @@ package com.android.inputmethod.latin;
import android.text.TextUtils;
+import com.android.inputmethod.keyboard.KeyboardLayout;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.common.Constants;
@@ -97,14 +98,16 @@ public final class Suggest {
final NgramContext ngramContext, final ProximityInfo proximityInfo,
final SettingsValuesForSuggestion settingsValuesForSuggestion,
final boolean isCorrectionEnabled, final int inputStyle, final int sequenceNumber,
- final OnGetSuggestedWordsCallback callback) {
+ final OnGetSuggestedWordsCallback callback,
+ final KeyboardLayout keyboardLayout) {
if (wordComposer.isBatchMode()) {
getSuggestedWordsForBatchInput(wordComposer, ngramContext, proximityInfo,
- settingsValuesForSuggestion, inputStyle, sequenceNumber, callback);
+ settingsValuesForSuggestion, inputStyle, sequenceNumber, callback,
+ keyboardLayout);
} else {
getSuggestedWordsForNonBatchInput(wordComposer, ngramContext, proximityInfo,
settingsValuesForSuggestion, inputStyle, isCorrectionEnabled,
- sequenceNumber, callback);
+ sequenceNumber, callback, keyboardLayout);
}
}
@@ -163,7 +166,8 @@ public final class Suggest {
final NgramContext ngramContext, final ProximityInfo proximityInfo,
final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int inputStyleIfNotPrediction, final boolean isCorrectionEnabled,
- final int sequenceNumber, final OnGetSuggestedWordsCallback callback) {
+ final int sequenceNumber, final OnGetSuggestedWordsCallback callback,
+ final KeyboardLayout keyboardLayout) {
final String typedWordString = wordComposer.getTypedWord();
final int trailingSingleQuotesCount =
StringUtils.getTrailingSingleQuotesCount(typedWordString);
@@ -173,7 +177,8 @@ public final class Suggest {
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
wordComposer, ngramContext, proximityInfo.getNativeProximityInfo(),
- settingsValuesForSuggestion, SESSION_ID_TYPING);
+ settingsValuesForSuggestion, SESSION_ID_TYPING, inputStyleIfNotPrediction,
+ keyboardLayout);
final Locale mostProbableLocale = mDictionaryFacilitator.getMostProbableLocale();
final ArrayList<SuggestedWordInfo> suggestionsContainer =
getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
@@ -270,7 +275,9 @@ public final class Suggest {
hasAutoCorrection = false;
} else {
final SuggestedWordInfo firstSuggestion = suggestionResults.first();
- if (!AutoCorrectionUtils.suggestionExceedsThreshold(
+ if (suggestionResults.mAutocorrectRecommendation) {
+ hasAutoCorrection = true;
+ } else if (!AutoCorrectionUtils.suggestionExceedsThreshold(
firstSuggestion, consideredWord, mAutoCorrectionThreshold)) {
// Score is too low for autocorrect
hasAutoCorrection = false;
@@ -339,10 +346,11 @@ public final class Suggest {
final NgramContext ngramContext, final ProximityInfo proximityInfo,
final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int inputStyle, final int sequenceNumber,
- final OnGetSuggestedWordsCallback callback) {
+ final OnGetSuggestedWordsCallback callback,
+ final KeyboardLayout keyboardLayout) {
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
wordComposer, ngramContext, proximityInfo.getNativeProximityInfo(),
- settingsValuesForSuggestion, SESSION_ID_GESTURE);
+ settingsValuesForSuggestion, SESSION_ID_GESTURE, inputStyle, keyboardLayout);
// For transforming words that don't come from a dictionary, because it's our best bet
final Locale defaultLocale = mDictionaryFacilitator.getMostProbableLocale();
final ArrayList<SuggestedWordInfo> suggestionsContainer =
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index df8db0cd2..913b63a61 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -112,6 +112,14 @@ public class SuggestedWords {
}
/**
+ * Get {@link SuggestedWordInfo} object for the typed word.
+ * @return The {@link SuggestedWordInfo} object for the typed word.
+ */
+ public SuggestedWordInfo getTypedWordInfo() {
+ return mTypedWordInfo;
+ }
+
+ /**
* Get suggested word at <code>index</code>.
* @param index The index of the suggested word.
* @return The suggested word.
@@ -347,6 +355,14 @@ public class SuggestedWords {
return mDebugString;
}
+ public String getWord() {
+ return mWord;
+ }
+
+ public Dictionary getSourceDictionary() {
+ return mSourceDict;
+ }
+
public int codePointAt(int i) {
return mWord.codePointAt(i);
}
diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
index 2d2b3d0a6..1ed210377 100644
--- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
@@ -16,7 +16,6 @@
package com.android.inputmethod.latin;
-import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
@@ -29,7 +28,6 @@ import android.text.TextUtils;
import android.util.Log;
import com.android.inputmethod.annotations.ExternallyReferenced;
-import com.android.inputmethod.compat.UserDictionaryCompatUtils;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
import java.io.File;
@@ -54,13 +52,13 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
private static final int USER_DICT_SHORTCUT_FREQUENCY = 14;
private static final String[] PROJECTION_QUERY_WITH_SHORTCUT = new String[] {
- Words.WORD,
- Words.SHORTCUT,
- Words.FREQUENCY,
+ Words.WORD,
+ Words.SHORTCUT,
+ Words.FREQUENCY,
};
private static final String[] PROJECTION_QUERY_WITHOUT_SHORTCUT = new String[] {
- Words.WORD,
- Words.FREQUENCY,
+ Words.WORD,
+ Words.FREQUENCY,
};
private static final String NAME = "userunigram";
@@ -70,7 +68,8 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
final private boolean mAlsoUseMoreRestrictiveLocales;
protected UserBinaryDictionary(final Context context, final Locale locale,
- final boolean alsoUseMoreRestrictiveLocales, final File dictFile, final String name) {
+ final boolean alsoUseMoreRestrictiveLocales,
+ final File dictFile, final String name) {
super(context, getDictName(name, locale, dictFile), locale, Dictionary.TYPE_USER, dictFile);
if (null == locale) throw new NullPointerException(); // Catch the error earlier
final String localeStr = locale.toString();
@@ -105,9 +104,11 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
// Note: This method is called by {@link DictionaryFacilitator} using Java reflection.
@ExternallyReferenced
- public static UserBinaryDictionary getDictionary(final Context context, final Locale locale,
- final File dictFile, final String dictNamePrefix, @Nullable final String account) {
- return new UserBinaryDictionary(context, locale, false /* alsoUseMoreRestrictiveLocales */,
+ public static UserBinaryDictionary getDictionary(
+ final Context context, final Locale locale, final File dictFile,
+ final String dictNamePrefix, @Nullable final String account) {
+ return new UserBinaryDictionary(
+ context, locale, false /* alsoUseMoreRestrictiveLocales */,
dictFile, dictNamePrefix + NAME);
}
@@ -187,7 +188,8 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
}
private void addWordsFromProjectionLocked(final String[] query, String request,
- final String[] requestArguments) throws IllegalArgumentException {
+ final String[] requestArguments)
+ throws IllegalArgumentException {
Cursor cursor = null;
try {
cursor = mContext.getContentResolver().query(
@@ -204,31 +206,6 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
}
}
- public static boolean isEnabled(final Context context) {
- final ContentResolver cr = context.getContentResolver();
- final ContentProviderClient client = cr.acquireContentProviderClient(Words.CONTENT_URI);
- if (client != null) {
- client.release();
- return true;
- }
- return false;
- }
-
- /**
- * Adds a word to the user dictionary and makes it persistent.
- *
- * @param context the context
- * @param locale the locale
- * @param word the word to add. If the word is capitalized, then the dictionary will
- * recognize it as a capitalized word when searched.
- */
- public static void addWordToUserDictionary(final Context context, final Locale locale,
- final String word) {
- // Update the user dictionary provider
- UserDictionaryCompatUtils.addWord(context, word,
- HISTORICAL_DEFAULT_USER_DICTIONARY_FREQUENCY, null, locale);
- }
-
private static int scaleFrequencyFromDefaultToLatinIme(final int defaultFrequency) {
// The default frequency for the user dictionary is 250 for historical reasons.
// Latin IME considers a good value for the default user dictionary frequency
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index e80e3628f..32ef1021d 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.latin;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.event.CombinerChain;
import com.android.inputmethod.event.Event;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
@@ -25,6 +26,7 @@ import com.android.inputmethod.latin.common.CoordinateUtils;
import com.android.inputmethod.latin.common.InputPointers;
import com.android.inputmethod.latin.common.StringUtils;
import com.android.inputmethod.latin.define.DebugFlags;
+import com.android.inputmethod.latin.define.DecoderSpecificConstants;
import java.util.ArrayList;
import java.util.Collections;
@@ -35,7 +37,7 @@ import javax.annotation.Nonnull;
* A place to store the currently composing word with information such as adjacent key codes as well
*/
public final class WordComposer {
- private static final int MAX_WORD_LENGTH = Constants.DICTIONARY_MAX_WORD_LENGTH;
+ private static final int MAX_WORD_LENGTH = DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH;
private static final boolean DBG = DebugFlags.DEBUG_ENABLED;
public static final int CAPS_MODE_OFF = 0;
@@ -464,4 +466,14 @@ public final class WordComposer {
public String getRejectedBatchModeSuggestion() {
return mRejectedBatchModeSuggestion;
}
+
+ @UsedForTesting
+ void addInputPointerForTest(int index, int keyX, int keyY) {
+ mInputPointers.addPointerAt(index, keyX, keyY, 0, 0);
+ }
+
+ @UsedForTesting
+ void setTypedWordCacheForTests(String typedWordCacheForTests) {
+ mTypedWordCache = typedWordCacheForTests;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 4842438c8..9154cc35a 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -17,7 +17,6 @@
package com.android.inputmethod.latin.inputlogic;
import android.graphics.Color;
-import android.inputmethodservice.InputMethodService;
import android.os.SystemClock;
import android.text.SpannableString;
import android.text.Spanned;
@@ -28,17 +27,14 @@ import android.util.Log;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.inputmethod.CorrectionInfo;
-import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.EditorInfo;
-import com.android.inputmethod.compat.CursorAnchorInfoCompatWrapper;
import com.android.inputmethod.compat.SuggestionSpanUtils;
import com.android.inputmethod.event.Event;
import com.android.inputmethod.event.InputTransaction;
+import com.android.inputmethod.keyboard.KeyboardLayout;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.ProximityInfo;
-import com.android.inputmethod.keyboard.TextDecorator;
-import com.android.inputmethod.keyboard.TextDecoratorUiOperator;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.DictionaryFacilitator;
import com.android.inputmethod.latin.LastComposedWord;
@@ -91,14 +87,6 @@ public final class InputLogic {
public final Suggest mSuggest;
private final DictionaryFacilitator mDictionaryFacilitator;
- private final TextDecorator mTextDecorator = new TextDecorator(new TextDecorator.Listener() {
- @Override
- public void onClickComposingTextToAddToDictionary(final String word) {
- mLatinIME.addWordToUserDictionary(word);
- mLatinIME.dismissAddToDictionaryHint();
- }
- });
-
public LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
// This has package visibility so it can be accessed from InputLogicHandler.
/* package */ final WordComposer mWordComposer;
@@ -174,7 +162,6 @@ public final class InputLogic {
mConnection.requestCursorUpdates(true /* enableMonitor */,
true /* requestImmediateCallback */);
}
- mTextDecorator.reset();
}
/**
@@ -269,20 +256,6 @@ public final class InputLogic {
}
/**
- * Determines whether "Touch again to save" should be shown or not.
- * @param suggestionInfo the suggested word chosen by the user.
- * @return {@code true} if we should show the "Touch again to save" hint.
- */
- private boolean shouldShowAddToDictionaryHint(final SuggestedWordInfo suggestionInfo) {
- // We should show the "Touch again to save" hint if the user pressed the first entry
- // AND it's in none of our current dictionaries (main, user or otherwise).
- return (suggestionInfo.isKindOf(SuggestedWordInfo.KIND_TYPED)
- || suggestionInfo.isKindOf(SuggestedWordInfo.KIND_OOV_CORRECTION))
- && !mDictionaryFacilitator.isValidWord(suggestionInfo.mWord, true /* ignoreCase */)
- && mDictionaryFacilitator.isUserDictionaryEnabled();
- }
-
- /**
* A suggestion was picked from the suggestion strip.
* @param settingsValues the current values of the settings.
* @param suggestionInfo the suggestion info.
@@ -340,7 +313,6 @@ public final class InputLogic {
return inputTransaction;
}
- final boolean shouldShowAddToDictionaryHint = shouldShowAddToDictionaryHint(suggestionInfo);
commitChosenWord(settingsValues, suggestion, LastComposedWord.COMMIT_TYPE_MANUAL_PICK,
LastComposedWord.NOT_A_SEPARATOR);
mConnection.endBatchEdit();
@@ -350,14 +322,9 @@ public final class InputLogic {
mSpaceState = SpaceState.PHANTOM;
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
- if (shouldShowAddToDictionaryHint) {
- mSuggestionStripViewAccessor.suggestAddingToDictionary(suggestion,
- true /* isFromSuggestionStrip */);
- } else {
- // If we're not showing the "Touch again to save", then update the suggestion strip.
- // That's going to be predictions (or punctuation suggestions), so INPUT_STYLE_NONE.
- handler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_NONE);
- }
+ // If we're not showing the "Touch again to save", then update the suggestion strip.
+ // That's going to be predictions (or punctuation suggestions), so INPUT_STYLE_NONE.
+ handler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_NONE);
StatsUtils.onPickSuggestionManually(mSuggestedWords, suggestionInfo);
StatsUtils.onWordCommitSuggestionPickedManually(
@@ -431,11 +398,6 @@ public final class InputLogic {
// The cursor has been moved : we now accept to perform recapitalization
mRecapitalizeStatus.enable();
- // We moved the cursor and need to invalidate the indicator right now.
- mTextDecorator.reset();
- // Remaining background color that was used for the add-to-dictionary indicator should be
- // removed.
- mConnection.removeBackgroundColorFromHighlightedTextIfNecessary();
// We moved the cursor. If we are touching a word, we need to resume suggestion.
mLatinIME.mHandler.postResumeSuggestions(true /* shouldDelay */);
// Stop the last recapitalization, if started.
@@ -513,9 +475,7 @@ public final class InputLogic {
handler.cancelUpdateSuggestionStrip();
++mAutoCommitSequenceNumber;
mConnection.beginBatchEdit();
- if (!mWordComposer.isComposingWord()) {
- mConnection.removeBackgroundColorFromHighlightedTextIfNecessary();
- } else {
+ if (mWordComposer.isComposingWord()) {
if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
// If we are in the middle of a recorrection, we need to commit the recorrection
// first so that we can insert the batch input at the current cursor position.
@@ -806,16 +766,6 @@ public final class InputLogic {
final InputTransaction inputTransaction,
// TODO: remove this argument
final LatinIME.UIHandler handler) {
- if (!mWordComposer.isComposingWord()) {
- mConnection.removeBackgroundColorFromHighlightedTextIfNecessary();
- // In case the "add to dictionary" hint was still displayed.
- // TODO: Do we really need to check if we have composing text here?
- if (mSuggestionStripViewAccessor.isShowingAddToDictionaryHint()) {
- mSuggestionStripViewAccessor.dismissAddToDictionaryHint();
- mTextDecorator.reset();
- }
- }
-
final int codePoint = event.mCodePoint;
mSpaceState = SpaceState.NONE;
if (inputTransaction.mSettingsValues.isWordSeparator(codePoint)
@@ -1639,20 +1589,8 @@ public final class InputLogic {
0 /* start */, lastCharIndex /* end */, 0 /* flags */);
}
- final boolean shouldShowAddToDictionaryForTypedWord =
- shouldShowAddToDictionaryForTypedWord(mLastComposedWord, settingsValues);
-
if (inputTransaction.mSettingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces) {
- // For languages with spaces, we revert to the typed string, but the cursor is still
- // after the separator so we don't resume suggestions. If the user wants to correct
- // the word, they have to press backspace again.
- if (shouldShowAddToDictionaryForTypedWord) {
- mConnection.commitTextWithBackgroundColor(textToCommit, 1,
- settingsValues.mTextHighlightColorForAddToDictionaryIndicator,
- originallyTypedWordString.length());
- } else {
- mConnection.commitText(textToCommit, 1);
- }
+ mConnection.commitText(textToCommit, 1);
if (usePhantomSpace) {
mSpaceState = SpaceState.PHANTOM;
}
@@ -1662,33 +1600,13 @@ public final class InputLogic {
final int[] codePoints = StringUtils.toCodePointArray(stringToCommit);
mWordComposer.setComposingWord(codePoints,
mLatinIME.getCoordinatesForCurrentKeyboard(codePoints));
- if (shouldShowAddToDictionaryForTypedWord) {
- setComposingTextInternalWithBackgroundColor(textToCommit, 1,
- settingsValues.mTextHighlightColorForAddToDictionaryIndicator,
- originallyTypedWordString.length());
- } else {
- setComposingTextInternal(textToCommit, 1);
- }
+ setComposingTextInternal(textToCommit, 1);
}
// Don't restart suggestion yet. We'll restart if the user deletes the separator.
mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
- if (shouldShowAddToDictionaryForTypedWord) {
- // Due to the API limitation as of L, we cannot reliably retrieve the reverted text
- // when the separator causes line breaking. Until this API limitation is addressed in
- // the framework, show the indicator only when the separator doesn't contain
- // line-breaking characters.
- if (!StringUtils.hasLineBreakCharacter(separatorString)) {
- mTextDecorator.showAddToDictionaryIndicator(originallyTypedWordString,
- mConnection.getExpectedSelectionStart(),
- mConnection.getExpectedSelectionEnd());
- }
- mSuggestionStripViewAccessor.suggestAddingToDictionary(originallyTypedWordString,
- false /* isFromSuggestionStrip */);
- } else {
- // We have a separator between the word and the cursor: we should show predictions.
- inputTransaction.setRequiresUpdateSuggestions();
- }
+ // We have a separator between the word and the cursor: we should show predictions.
+ inputTransaction.setRequiresUpdateSuggestions();
}
/**
@@ -2192,7 +2110,8 @@ public final class InputLogic {
public void getSuggestedWords(final SettingsValues settingsValues,
final ProximityInfo proximityInfo, final int keyboardShiftMode, final int inputStyle,
- final int sequenceNumber, final OnGetSuggestedWordsCallback callback) {
+ final int sequenceNumber, final OnGetSuggestedWordsCallback callback,
+ final KeyboardLayout keyboardLayout) {
mWordComposer.adviseCapitalizedModeBeforeFetchingSuggestions(
getActualCapsMode(settingsValues, keyboardShiftMode));
mSuggest.getSuggestedWords(mWordComposer,
@@ -2206,7 +2125,7 @@ public final class InputLogic {
new SettingsValuesForSuggestion(settingsValues.mBlockPotentiallyOffensive,
settingsValues.mPhraseGestureEnabled),
settingsValues.mAutoCorrectionEnabledPerUserSettings,
- inputStyle, sequenceNumber, callback);
+ inputStyle, sequenceNumber, callback, keyboardLayout);
}
/**
@@ -2215,7 +2134,7 @@ public final class InputLogic {
*
* <p>Currently using this method is optional and you can still directly call
* {@link RichInputConnection#setComposingText(CharSequence, int)}, but it is recommended to
- * use this method whenever possible to optimize the behavior of {@link TextDecorator}.<p>
+ * use this method whenever possible.<p>
* <p>TODO: Should we move this mechanism to {@link RichInputConnection}?</p>
*
* @param newComposingText the composing text to be set
@@ -2300,71 +2219,4 @@ public final class InputLogic {
public int getComposingLength() {
return mWordComposer.size();
}
-
- //////////////////////////////////////////////////////////////////////////////////////////////
- // Following methods are tentatively placed in this class for the integration with
- // TextDecorator.
- // TODO: Decouple things that are not related to the input logic.
- //////////////////////////////////////////////////////////////////////////////////////////////
-
- /**
- * Sets the UI operator for {@link TextDecorator}.
- * @param uiOperator the UI operator which should be associated with {@link TextDecorator}.
- */
- public void setTextDecoratorUi(@Nonnull final TextDecoratorUiOperator uiOperator) {
- mTextDecorator.setUiOperator(uiOperator);
- }
-
- /**
- * Must be called from {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)} is
- * called.
- * @param info The wrapper object with which we can access cursor/anchor info.
- */
- public void onUpdateCursorAnchorInfo(final CursorAnchorInfoCompatWrapper info) {
- mTextDecorator.onUpdateCursorAnchorInfo(info);
- }
-
- /**
- * Must be called when {@link InputMethodService#updateFullscreenMode} is called.
- * @param isFullscreen {@code true} if the input method is in full-screen mode.
- */
- public void onUpdateFullscreenMode(final boolean isFullscreen) {
- mTextDecorator.notifyFullScreenMode(isFullscreen);
- }
-
- /**
- * Must be called from {@link LatinIME#addWordToUserDictionary(String)}.
- */
- public void onAddWordToUserDictionary() {
- mConnection.removeBackgroundColorFromHighlightedTextIfNecessary();
- mTextDecorator.reset();
- }
-
- /**
- * Returns whether the add to dictionary indicator should be shown or not.
- * @param lastComposedWord the last composed word information.
- * @param settingsValues the current settings value.
- * @return {@code true} if the commit indicator should be shown.
- */
- private boolean shouldShowAddToDictionaryForTypedWord(final LastComposedWord lastComposedWord,
- final SettingsValues settingsValues) {
- if (!mConnection.isCursorAnchorInfoMonitorEnabled()) {
- // We cannot help in this case because we are heavily relying on this new API.
- return false;
- }
- if (!settingsValues.mShouldShowLxxSuggestionUi) {
- return false;
- }
- if (TextUtils.isEmpty(lastComposedWord.mTypedWord)) {
- return false;
- }
- if (TextUtils.equals(lastComposedWord.mTypedWord, lastComposedWord.mCommittedWord)) {
- return false;
- }
- if (!mDictionaryFacilitator.isUserDictionaryEnabled()) {
- return false;
- }
- return !mDictionaryFacilitator.isValidWord(lastComposedWord.mTypedWord,
- true /* ignoreCase */);
- }
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index eba9654a5..3348a3767 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -17,7 +17,7 @@
package com.android.inputmethod.latin.makedict;
import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.common.Constants;
+import com.android.inputmethod.latin.define.DecoderSpecificConstants;
import java.util.Date;
import java.util.HashMap;
@@ -186,7 +186,7 @@ public final class FormatSpec {
// TODO: Make this value adaptative to content data, store it in the header, and
// use it in the reading code.
- static final int MAX_WORD_LENGTH = Constants.DICTIONARY_MAX_WORD_LENGTH;
+ static final int MAX_WORD_LENGTH = DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH;
// These flags are used only in the static dictionary.
static final int MASK_CHILDREN_ADDRESS_TYPE = 0xC0;
diff --git a/java/src/com/android/inputmethod/latin/personalization/ContextualDictionary.java b/java/src/com/android/inputmethod/latin/personalization/ContextualDictionary.java
deleted file mode 100644
index f663fe96a..000000000
--- a/java/src/com/android/inputmethod/latin/personalization/ContextualDictionary.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2014 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.personalization;
-
-import android.content.Context;
-
-import com.android.inputmethod.annotations.ExternallyReferenced;
-import com.android.inputmethod.latin.Dictionary;
-import com.android.inputmethod.latin.ExpandableBinaryDictionary;
-
-import java.io.File;
-import java.util.Locale;
-
-import javax.annotation.Nullable;
-
-public class ContextualDictionary extends ExpandableBinaryDictionary {
- /* package */ static final String NAME = ContextualDictionary.class.getSimpleName();
-
- private ContextualDictionary(final Context context, final Locale locale,
- final File dictFile) {
- super(context, getDictName(NAME, locale, dictFile), locale, Dictionary.TYPE_CONTEXTUAL,
- dictFile);
- // Always reset the contents.
- clear();
- }
-
- // Note: This method is called by {@link DictionaryFacilitator} using Java reflection.
- @SuppressWarnings("unused")
- @ExternallyReferenced
- public static ContextualDictionary getDictionary(final Context context, final Locale locale,
- final File dictFile, final String dictNamePrefix, @Nullable final String account) {
- return new ContextualDictionary(context, locale, dictFile);
- }
-
- @Override
- public boolean isValidWord(final String word) {
- // Strings out of this dictionary should not be considered existing words.
- return false;
- }
-
- @Override
- protected void loadInitialContentsLocked() {
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java b/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java
index e974f3320..0c5e5d010 100644
--- a/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java
+++ b/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java
@@ -84,7 +84,6 @@ public class DictionaryDecayBroadcastReciever extends BroadcastReceiver {
final String action = intent.getAction();
if (action.equals(DICTIONARY_DECAY_INTENT_ACTION)) {
PersonalizationHelper.runGCOnAllOpenedUserHistoryDictionaries();
- PersonalizationHelper.runGCOnAllOpenedPersonalizationDictionaries();
}
}
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDataChunk.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDataChunk.java
deleted file mode 100644
index 734ed5583..000000000
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDataChunk.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2014 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.personalization;
-
-import java.util.Collections;
-import java.util.List;
-
-public class PersonalizationDataChunk {
- public static final String LANGUAGE_UNKNOWN = "";
-
- public final boolean mInputByUser;
- public final List<String> mTokens;
- public final int mTimestampInSeconds;
- public final String mPackageName;
- public final String mDetectedLanguage;
-
- public PersonalizationDataChunk(boolean inputByUser, final List<String> tokens,
- final int timestampInSeconds, final String packageName, final String detectedLanguage) {
- mInputByUser = inputByUser;
- mTokens = Collections.unmodifiableList(tokens);
- mTimestampInSeconds = timestampInSeconds;
- mPackageName = packageName;
- mDetectedLanguage = detectedLanguage;
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java
deleted file mode 100644
index 76451cc6b..000000000
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.personalization;
-
-import android.content.Context;
-
-import com.android.inputmethod.annotations.ExternallyReferenced;
-import com.android.inputmethod.latin.Dictionary;
-
-import java.io.File;
-import java.util.Locale;
-
-import javax.annotation.Nullable;
-
-public class PersonalizationDictionary extends DecayingExpandableBinaryDictionaryBase {
- /* package */ static final String NAME = PersonalizationDictionary.class.getSimpleName();
-
- // TODO: Make this constructor private
- /* package */ PersonalizationDictionary(final Context context, final Locale locale) {
- super(context, getDictName(NAME, locale, null /* dictFile */), locale,
- Dictionary.TYPE_PERSONALIZATION, null /* dictFile */);
- }
-
- // Note: This method is called by {@link DictionaryFacilitator} using Java reflection.
- @SuppressWarnings("unused")
- @ExternallyReferenced
- public static PersonalizationDictionary getDictionary(final Context context,
- final Locale locale, final File dictFile, final String dictNamePrefix,
- @Nullable final String account) {
- return PersonalizationHelper.getPersonalizationDictionary(context, locale);
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
index 4231450c1..1c1cb4f95 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
@@ -32,8 +32,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
- * Helps handle and manage personalized dictionaries such as {@link UserHistoryDictionary} and
- * {@link PersonalizationDictionary}.
+ * Helps handle and manage personalized dictionaries such as {@link UserHistoryDictionary}.
*/
public class PersonalizationHelper {
private static final String TAG = PersonalizationHelper.class.getSimpleName();
@@ -41,8 +40,6 @@ public class PersonalizationHelper {
private static final ConcurrentHashMap<String, SoftReference<UserHistoryDictionary>>
sLangUserHistoryDictCache = new ConcurrentHashMap<>();
- private static final ConcurrentHashMap<String, SoftReference<PersonalizationDictionary>>
- sLangPersonalizationDictCache = new ConcurrentHashMap<>();
@Nonnull
public static UserHistoryDictionary getUserHistoryDictionary(
@@ -77,7 +74,6 @@ public class PersonalizationHelper {
DictionaryDecayBroadcastReciever.DICTIONARY_DECAY_INTERVAL_IN_MILLIS)
< currentTimestamp - sCurrentTimestampForTesting) {
runGCOnAllOpenedUserHistoryDictionaries();
- runGCOnAllOpenedPersonalizationDictionaries();
}
}
@@ -85,10 +81,6 @@ public class PersonalizationHelper {
runGCOnAllDictionariesIfRequired(sLangUserHistoryDictCache);
}
- public static void runGCOnAllOpenedPersonalizationDictionaries() {
- runGCOnAllDictionariesIfRequired(sLangPersonalizationDictCache);
- }
-
private static <T extends DecayingExpandableBinaryDictionaryBase>
void runGCOnAllDictionariesIfRequired(
final ConcurrentHashMap<String, SoftReference<T>> dictionaryMap) {
@@ -103,32 +95,6 @@ public class PersonalizationHelper {
}
}
- public static PersonalizationDictionary getPersonalizationDictionary(
- final Context context, final Locale locale) {
- final String localeStr = locale.toString();
- synchronized (sLangPersonalizationDictCache) {
- if (sLangPersonalizationDictCache.containsKey(localeStr)) {
- final SoftReference<PersonalizationDictionary> ref =
- sLangPersonalizationDictCache.get(localeStr);
- final PersonalizationDictionary dict = ref == null ? null : ref.get();
- if (dict != null) {
- if (DEBUG) {
- Log.w(TAG, "Use cached PersonalizationDictionary for " + locale);
- }
- return dict;
- }
- }
- final PersonalizationDictionary dict = new PersonalizationDictionary(context, locale);
- sLangPersonalizationDictCache.put(localeStr, new SoftReference<>(dict));
- return dict;
- }
- }
-
- public static void removeAllPersonalizationDictionaries(final Context context) {
- removeAllDictionaries(context, sLangPersonalizationDictCache,
- PersonalizationDictionary.NAME);
- }
-
public static void removeAllUserHistoryDictionaries(final Context context) {
removeAllDictionaries(context, sLangUserHistoryDictCache,
UserHistoryDictionary.NAME);
diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
index 2e41027a4..1d75a3098 100644
--- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
@@ -17,17 +17,14 @@
package com.android.inputmethod.latin.personalization;
import android.content.Context;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
import com.android.inputmethod.annotations.ExternallyReferenced;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.ExpandableBinaryDictionary;
import com.android.inputmethod.latin.NgramContext;
-import com.android.inputmethod.latin.common.Constants;
+import com.android.inputmethod.latin.define.DecoderSpecificConstants;
import com.android.inputmethod.latin.define.ProductionFlags;
-import com.android.inputmethod.latin.settings.LocalSettingsConstants;
import com.android.inputmethod.latin.utils.DistracterFilter;
import java.io.File;
@@ -102,7 +99,7 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas
public static void addToDictionary(final ExpandableBinaryDictionary userHistoryDictionary,
@Nonnull final NgramContext ngramContext, final String word, final boolean isValid,
final int timestamp, @Nonnull final DistracterFilter distracterFilter) {
- if (word.length() > Constants.DICTIONARY_MAX_WORD_LENGTH) {
+ if (word.length() > DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH) {
return;
}
userHistoryDictionary.updateEntriesForWordWithCheckingDistracter(ngramContext, word,
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index a080515dd..9a1bb7784 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -102,9 +102,6 @@ public class SettingsValues {
private final boolean mSuggestionsEnabledPerUserSettings;
private final AsyncResultHolder<AppWorkaroundsUtils> mAppWorkarounds;
- // TextDecorator
- public final int mTextHighlightColorForAddToDictionaryIndicator;
-
// Debug settings
public final boolean mIsInternal;
public final boolean mHasCustomKeyPreviewAnimationParams;
@@ -183,8 +180,6 @@ public class SettingsValues {
mAutoCorrectionEnabledPerUserSettings = mAutoCorrectEnabled
&& !mInputAttributes.mInputTypeNoAutoCorrect;
mSuggestionsEnabledPerUserSettings = readSuggestionsEnabled(prefs);
- mTextHighlightColorForAddToDictionaryIndicator = res.getColor(
- R.color.text_decorator_add_to_dictionary_indicator_text_highlight_color);
mIsInternal = Settings.isInternal(prefs);
mHasCustomKeyPreviewAnimationParams = prefs.getBoolean(
DebugSettings.PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS, false);
@@ -431,8 +426,6 @@ public class SettingsValues {
sb.append("\n mAppWorkarounds = ");
final AppWorkaroundsUtils awu = mAppWorkarounds.get(null, 0);
sb.append("" + (null == awu ? "null" : awu.toString()));
- sb.append("\n mTextHighlightColorForAddToDictionaryIndicator = ");
- sb.append("" + mTextHighlightColorForAddToDictionaryIndicator);
sb.append("\n mIsInternal = ");
sb.append("" + mIsInternal);
sb.append("\n mKeyPreviewShowUpDuration = ");
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 8744020b1..02151522d 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -27,6 +27,7 @@ import android.view.textservice.SuggestionsInfo;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardId;
+import com.android.inputmethod.keyboard.KeyboardLayout;
import com.android.inputmethod.keyboard.KeyboardLayoutSet;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.DictionaryFacilitator;
@@ -34,6 +35,7 @@ import com.android.inputmethod.latin.DictionaryFacilitatorLruCache;
import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.RichInputMethodSubtype;
+import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
import com.android.inputmethod.latin.utils.ScriptUtils;
@@ -65,10 +67,8 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
// TODO: Make each spell checker session has its own session id.
private final ConcurrentLinkedQueue<Integer> mSessionIdPool = new ConcurrentLinkedQueue<>();
- private static final int MAX_DICTIONARY_FACILITATOR_COUNT = 3;
private final DictionaryFacilitatorLruCache mDictionaryFacilitatorCache =
- new DictionaryFacilitatorLruCache(this /* context */, MAX_DICTIONARY_FACILITATOR_COUNT,
- DICTIONARY_NAME_PREFIX);
+ new DictionaryFacilitatorLruCache(this /* context */, DICTIONARY_NAME_PREFIX);
private final ConcurrentHashMap<Locale, Keyboard> mKeyboardCache = new ConcurrentHashMap<>();
// The threshold for a suggestion to be considered "recommended".
@@ -152,14 +152,15 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
try {
DictionaryFacilitator dictionaryFacilitatorForLocale =
mDictionaryFacilitatorCache.get(locale);
- return dictionaryFacilitatorForLocale.isValidWord(word, false /* igroreCase */);
+ return dictionaryFacilitatorForLocale.isValidSpellingWord(word);
} finally {
mSemaphore.release();
}
}
public SuggestionResults getSuggestionResults(final Locale locale, final WordComposer composer,
- final NgramContext ngramContext, final ProximityInfo proximityInfo) {
+ final NgramContext ngramContext, final ProximityInfo proximityInfo,
+ final KeyboardLayout keyboardLayout) {
Integer sessionId = null;
mSemaphore.acquireUninterruptibly();
try {
@@ -168,7 +169,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
mDictionaryFacilitatorCache.get(locale);
return dictionaryFacilitatorForLocale.getSuggestionResults(composer, ngramContext,
proximityInfo.getNativeProximityInfo(), mSettingsValuesForSuggestion,
- sessionId);
+ sessionId, SuggestedWords.INPUT_STYLE_TYPING, keyboardLayout);
} finally {
if (sessionId != null) {
mSessionIdPool.add(sessionId);
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
index 832bfd066..0b5e12f03 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
@@ -29,6 +29,7 @@ import android.view.textservice.TextInfo;
import com.android.inputmethod.compat.SuggestionsInfoCompatUtils;
import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardLayout;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
@@ -271,18 +272,21 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
final int[] codePoints = StringUtils.toCodePointArray(text);
final int[] coordinates;
final ProximityInfo proximityInfo;
+ final KeyboardLayout keyboardLayout;
if (null == keyboard) {
coordinates = CoordinateUtils.newCoordinateArray(codePoints.length,
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
proximityInfo = null;
+ keyboardLayout = null;
} else {
coordinates = keyboard.getCoordinates(codePoints);
proximityInfo = keyboard.getProximityInfo();
+ keyboardLayout = keyboard.getKeyboardLayout();
}
composer.setComposingWord(codePoints, coordinates);
// TODO: Don't gather suggestions if the limit is <= 0 unless necessary
final SuggestionResults suggestionResults = mService.getSuggestionResults(
- mLocale, composer, ngramContext, proximityInfo);
+ mLocale, composer, ngramContext, proximityInfo, keyboardLayout);
final Result result = getResult(capitalizeType, mLocale, suggestionsLimit,
mService.getRecommendedThreshold(), text, suggestionResults);
isInDict = isInDictForAnyCapitalization(text, capitalizeType);
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index 7991a2473..a9d1207f1 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -28,7 +28,6 @@ import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
-import android.support.v4.view.ViewCompat;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
@@ -50,7 +49,6 @@ import com.android.inputmethod.latin.PunctuationSuggestions;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.common.LocaleUtils;
import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.settings.SettingsValues;
import com.android.inputmethod.latin.utils.ResourceUtils;
@@ -95,8 +93,6 @@ final class SuggestionStripLayoutHelper {
private final int mTypedWordPositionWhenAutocorrect;
private final Drawable mMoreSuggestionsHint;
private static final String MORE_SUGGESTIONS_HINT = "\u2026";
- private static final String LEFTWARDS_ARROW = "\u2190";
- private static final String RIGHTWARDS_ARROW = "\u2192";
private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD);
private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan();
@@ -540,55 +536,6 @@ final class SuggestionStripLayoutHelper {
return countInStrip;
}
- public void layoutAddToDictionaryHint(final String word, final ViewGroup addToDictionaryStrip,
- final boolean shouldShowWordToSave) {
- final boolean showsHintWithWord = shouldShowWordToSave
- || !Settings.getInstance().getCurrent().mShouldShowLxxSuggestionUi;
- final int stripWidth = addToDictionaryStrip.getWidth();
- final int width = stripWidth - (showsHintWithWord ? mDividerWidth + mPadding * 2 : 0);
-
- final TextView wordView = (TextView)addToDictionaryStrip.findViewById(R.id.word_to_save);
- wordView.setTextColor(mColorTypedWord);
- final int wordWidth = (int)(width * mCenterSuggestionWeight);
- final CharSequence wordToSave = getEllipsizedTextWithSettingScaleX(
- word, wordWidth, wordView.getPaint());
- final float wordScaleX = wordView.getTextScaleX();
- wordView.setText(wordToSave);
- wordView.setTextScaleX(wordScaleX);
- setLayoutWeight(wordView, mCenterSuggestionWeight, ViewGroup.LayoutParams.MATCH_PARENT);
- final int wordVisibility = showsHintWithWord ? View.VISIBLE : View.GONE;
- wordView.setVisibility(wordVisibility);
- addToDictionaryStrip.findViewById(R.id.word_to_save_divider).setVisibility(wordVisibility);
-
- final Resources res = addToDictionaryStrip.getResources();
- final CharSequence hintText;
- final int hintWidth;
- final float hintWeight;
- final TextView hintView = (TextView)addToDictionaryStrip.findViewById(
- R.id.hint_add_to_dictionary);
- if (showsHintWithWord) {
- final boolean isRtlLanguage = (ViewCompat.getLayoutDirection(addToDictionaryStrip)
- == ViewCompat.LAYOUT_DIRECTION_RTL);
- final String arrow = isRtlLanguage ? RIGHTWARDS_ARROW : LEFTWARDS_ARROW;
- final boolean isRtlSystem = LocaleUtils.isRtlLanguage(res.getConfiguration().locale);
- final CharSequence hint = res.getText(R.string.hint_add_to_dictionary);
- hintText = (isRtlLanguage == isRtlSystem) ? (arrow + hint) : (hint + arrow);
- hintWidth = width - wordWidth;
- hintWeight = 1.0f - mCenterSuggestionWeight;
- hintView.setGravity(Gravity.CENTER_VERTICAL | Gravity.START);
- } else {
- hintText = res.getText(R.string.hint_add_to_dictionary_without_word);
- hintWidth = width;
- hintWeight = 1.0f;
- hintView.setGravity(Gravity.CENTER);
- }
- hintView.setTextColor(mColorAutoCorrect);
- final float hintScaleX = getTextScaleX(hintText, hintWidth, hintView.getPaint());
- hintView.setText(hintText); // TextView.setText() resets text scale x to 1.0.
- hintView.setTextScaleX(hintScaleX);
- setLayoutWeight(hintView, hintWeight, ViewGroup.LayoutParams.MATCH_PARENT);
- }
-
public void layoutImportantNotice(final View importantNoticeStrip,
final String importantNoticeTitle) {
final TextView titleView = (TextView)importantNoticeStrip.findViewById(
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index b71bd1f50..4b849496c 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -58,7 +58,6 @@ import java.util.ArrayList;
public final class SuggestionStripView extends RelativeLayout implements OnClickListener,
OnLongClickListener {
public interface Listener {
- public void addWordToUserDictionary(String word);
public void showImportantNoticeContents();
public void pickSuggestionManually(SuggestedWordInfo word);
public void onCodeInput(int primaryCode, int x, int y, boolean isKeyRepeat);
@@ -69,7 +68,6 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
private final ViewGroup mSuggestionsStrip;
private final ImageButton mVoiceKey;
- private final ViewGroup mAddToDictionaryStrip;
private final View mImportantNoticeStrip;
MainKeyboardView mMainKeyboardView;
@@ -91,15 +89,12 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
private static class StripVisibilityGroup {
private final View mSuggestionStripView;
private final View mSuggestionsStrip;
- private final View mAddToDictionaryStrip;
private final View mImportantNoticeStrip;
public StripVisibilityGroup(final View suggestionStripView,
- final ViewGroup suggestionsStrip, final ViewGroup addToDictionaryStrip,
- final View importantNoticeStrip) {
+ final ViewGroup suggestionsStrip, final View importantNoticeStrip) {
mSuggestionStripView = suggestionStripView;
mSuggestionsStrip = suggestionsStrip;
- mAddToDictionaryStrip = addToDictionaryStrip;
mImportantNoticeStrip = importantNoticeStrip;
showSuggestionsStrip();
}
@@ -109,35 +104,22 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
: ViewCompat.LAYOUT_DIRECTION_LTR;
ViewCompat.setLayoutDirection(mSuggestionStripView, layoutDirection);
ViewCompat.setLayoutDirection(mSuggestionsStrip, layoutDirection);
- ViewCompat.setLayoutDirection(mAddToDictionaryStrip, layoutDirection);
ViewCompat.setLayoutDirection(mImportantNoticeStrip, layoutDirection);
}
public void showSuggestionsStrip() {
mSuggestionsStrip.setVisibility(VISIBLE);
- mAddToDictionaryStrip.setVisibility(INVISIBLE);
- mImportantNoticeStrip.setVisibility(INVISIBLE);
- }
-
- public void showAddToDictionaryStrip() {
- mSuggestionsStrip.setVisibility(INVISIBLE);
- mAddToDictionaryStrip.setVisibility(VISIBLE);
mImportantNoticeStrip.setVisibility(INVISIBLE);
}
public void showImportantNoticeStrip() {
mSuggestionsStrip.setVisibility(INVISIBLE);
- mAddToDictionaryStrip.setVisibility(INVISIBLE);
mImportantNoticeStrip.setVisibility(VISIBLE);
}
public boolean isShowingImportantNoticeStrip() {
return mImportantNoticeStrip.getVisibility() == VISIBLE;
}
-
- public boolean isShowingAddToDictionaryStrip() {
- return mAddToDictionaryStrip.getVisibility() == VISIBLE;
- }
}
/**
@@ -158,10 +140,9 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
mSuggestionsStrip = (ViewGroup)findViewById(R.id.suggestions_strip);
mVoiceKey = (ImageButton)findViewById(R.id.suggestions_strip_voice_key);
- mAddToDictionaryStrip = (ViewGroup)findViewById(R.id.add_to_dictionary_strip);
mImportantNoticeStrip = findViewById(R.id.important_notice_strip);
mStripVisibilityGroup = new StripVisibilityGroup(this, mSuggestionsStrip,
- mAddToDictionaryStrip, mImportantNoticeStrip);
+ mImportantNoticeStrip);
for (int pos = 0; pos < SuggestedWords.MAX_SUGGESTIONS; pos++) {
final TextView word = new TextView(context, null, R.attr.suggestionWordStyle);
@@ -227,27 +208,6 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
mLayoutHelper.setMoreSuggestionsHeight(remainingHeight);
}
- public boolean isShowingAddToDictionaryHint() {
- return mStripVisibilityGroup.isShowingAddToDictionaryStrip();
- }
-
- public void showAddToDictionaryHint(final String word, final boolean shouldShowWordToSave) {
- mLayoutHelper.layoutAddToDictionaryHint(word, mAddToDictionaryStrip, shouldShowWordToSave);
- // {@link TextView#setTag()} is used to hold the word to be added to dictionary. The word
- // will be extracted at {@link #onClick(View)}.
- mAddToDictionaryStrip.setTag(word);
- mAddToDictionaryStrip.setOnClickListener(this);
- mStripVisibilityGroup.showAddToDictionaryStrip();
- }
-
- public boolean dismissAddToDictionaryHint() {
- if (isShowingAddToDictionaryHint()) {
- clear();
- return true;
- }
- return false;
- }
-
// This method checks if we should show the important notice (checks on permanent storage if
// it has been shown once already or not, and if in the setup wizard). If applicable, it shows
// the notice. In all cases, it returns true if it was shown, false otherwise.
@@ -494,15 +454,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
false /* isKeyRepeat */);
return;
}
- final Object tag = view.getTag();
- // {@link String} tag is set at {@link #suggestAddingToDictionary(String,CharSequence)}.
- if (tag instanceof String) {
- final String wordToSave = (String)tag;
- mListener.addWordToUserDictionary(wordToSave);
- clear();
- return;
- }
+ final Object tag = view.getTag();
// {@link Integer} tag is set at
// {@link SuggestionStripLayoutHelper#setupWordViewsTextAndColor(SuggestedWords,int)} and
// {@link SuggestionStripLayoutHelper#layoutPunctuationSuggestions(SuggestedWords,ViewGroup}
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java
index 5c86a02af..68f417e84 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java
@@ -22,9 +22,6 @@ import com.android.inputmethod.latin.SuggestedWords;
* An object that gives basic control of a suggestion strip and some info on it.
*/
public interface SuggestionStripViewAccessor {
- public void suggestAddingToDictionary(final String word, final boolean isFromSuggestionStrip);
- public boolean isShowingAddToDictionaryHint();
- public void dismissAddToDictionaryHint();
public void setNeutralSuggestionStrip();
public void showSuggestionStrip(final SuggestedWords suggestedWords);
}
diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java
deleted file mode 100644
index 163443036..000000000
--- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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.userdictionary;
-
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.userdictionary.UserDictionaryAddWordContents.LocaleRenderer;
-import com.android.inputmethod.latin.userdictionary.UserDictionaryLocalePicker.LocationChangedListener;
-
-import android.app.Fragment;
-import android.os.Bundle;
-import android.preference.PreferenceActivity;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.Spinner;
-
-import java.util.ArrayList;
-import java.util.Locale;
-
-// Caveat: This class is basically taken from
-// packages/apps/Settings/src/com/android/settings/inputmethod/UserDictionaryAddWordFragment.java
-// in order to deal with some devices that have issues with the user dictionary handling
-
-/**
- * Fragment to add a word/shortcut to the user dictionary.
- *
- * As opposed to the UserDictionaryActivity, this is only invoked within Settings
- * from the UserDictionarySettings.
- */
-public class UserDictionaryAddWordFragment extends Fragment
- implements AdapterView.OnItemSelectedListener, LocationChangedListener {
-
- private static final int OPTIONS_MENU_ADD = Menu.FIRST;
- private static final int OPTIONS_MENU_DELETE = Menu.FIRST + 1;
-
- private UserDictionaryAddWordContents mContents;
- private View mRootView;
- private boolean mIsDeleting = false;
-
- @Override
- public void onActivityCreated(final Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- setHasOptionsMenu(true);
- getActivity().getActionBar().setTitle(R.string.edit_personal_dictionary);
- // Keep the instance so that we remember mContents when configuration changes (eg rotation)
- setRetainInstance(true);
- }
-
- @Override
- public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
- final Bundle savedState) {
- mRootView = inflater.inflate(R.layout.user_dictionary_add_word_fullscreen, null);
- mIsDeleting = false;
- // If we have a non-null mContents object, it's the old value before a configuration
- // change (eg rotation) so we need to use its values. Otherwise, read from the arguments.
- if (null == mContents) {
- mContents = new UserDictionaryAddWordContents(mRootView, getArguments());
- } else {
- // We create a new mContents object to account for the new situation : a word has
- // been added to the user dictionary when we started rotating, and we are now editing
- // it. That means in particular if the word undergoes any change, the old version should
- // be updated, so the mContents object needs to switch to EDIT mode if it was in
- // INSERT mode.
- mContents = new UserDictionaryAddWordContents(mRootView,
- mContents /* oldInstanceToBeEdited */);
- }
- getActivity().getActionBar().setSubtitle(UserDictionarySettingsUtils.getLocaleDisplayName(
- getActivity(), mContents.getCurrentUserDictionaryLocale()));
- return mRootView;
- }
-
- @Override
- public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
- final MenuItem actionItemAdd = menu.add(0, OPTIONS_MENU_ADD, 0,
- R.string.user_dict_settings_add_menu_title).setIcon(R.drawable.ic_menu_add);
- actionItemAdd.setShowAsAction(
- MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
- final MenuItem actionItemDelete = menu.add(0, OPTIONS_MENU_DELETE, 0,
- R.string.user_dict_settings_delete).setIcon(android.R.drawable.ic_menu_delete);
- actionItemDelete.setShowAsAction(
- MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
- }
-
- /**
- * Callback for the framework when a menu option is pressed.
- *
- * @param item the item that was pressed
- * @return false to allow normal menu processing to proceed, true to consume it here
- */
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == OPTIONS_MENU_ADD) {
- // added the entry in "onPause"
- getActivity().onBackPressed();
- return true;
- }
- if (item.getItemId() == OPTIONS_MENU_DELETE) {
- mContents.delete(getActivity());
- mIsDeleting = true;
- getActivity().onBackPressed();
- return true;
- }
- return false;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- // We are being shown: display the word
- updateSpinner();
- }
-
- private void updateSpinner() {
- final ArrayList<LocaleRenderer> localesList = mContents.getLocalesList(getActivity());
-
- final Spinner localeSpinner =
- (Spinner)mRootView.findViewById(R.id.user_dictionary_add_locale);
- final ArrayAdapter<LocaleRenderer> adapter = new ArrayAdapter<>(
- getActivity(), android.R.layout.simple_spinner_item, localesList);
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- localeSpinner.setAdapter(adapter);
- localeSpinner.setOnItemSelectedListener(this);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- // We are being hidden: commit changes to the user dictionary, unless we were deleting it
- if (!mIsDeleting) {
- mContents.apply(getActivity(), null);
- }
- }
-
- @Override
- public void onItemSelected(final AdapterView<?> parent, final View view, final int pos,
- final long id) {
- final LocaleRenderer locale = (LocaleRenderer)parent.getItemAtPosition(pos);
- if (locale.isMoreLanguages()) {
- PreferenceActivity preferenceActivity = (PreferenceActivity)getActivity();
- preferenceActivity.startPreferenceFragment(new UserDictionaryLocalePicker(), true);
- } else {
- mContents.updateLocale(locale.getLocaleString());
- }
- }
-
- @Override
- public void onNothingSelected(final AdapterView<?> parent) {
- // I'm not sure we can come here, but if we do, that's the right thing to do.
- final Bundle args = getArguments();
- mContents.updateLocale(args.getString(UserDictionaryAddWordContents.EXTRA_LOCALE));
- }
-
- // Called by the locale picker
- @Override
- public void onLocaleSelected(final Locale locale) {
- mContents.updateLocale(locale.toString());
- getActivity().onBackPressed();
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionarySettings.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionarySettings.java
index 1d7e7d683..fabd49f46 100644
--- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionarySettings.java
+++ b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionarySettings.java
@@ -240,8 +240,6 @@ public class UserDictionarySettings extends ListFragment {
args.putString(UserDictionaryAddWordContents.EXTRA_LOCALE, mLocale);
android.preference.PreferenceActivity pa =
(android.preference.PreferenceActivity)getActivity();
- pa.startPreferencePanel(UserDictionaryAddWordFragment.class.getName(),
- args, R.string.user_dict_settings_add_dialog_title, null, null, 0);
}
private String getWord(final int position) {
diff --git a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
index fcce1ecdd..e355b7e1f 100644
--- a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
@@ -27,8 +27,8 @@ import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.AssetFileAddress;
import com.android.inputmethod.latin.BinaryDictionaryGetter;
import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.common.LocaleUtils;
+import com.android.inputmethod.latin.define.DecoderSpecificConstants;
import com.android.inputmethod.latin.makedict.DictionaryHeader;
import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
@@ -450,7 +450,7 @@ public class DictionaryInfoUtils {
return false;
}
final int length = text.length();
- if (length > Constants.DICTIONARY_MAX_WORD_LENGTH) {
+ if (length > DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH) {
return false;
}
int i = 0;
diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java
index 56a04a856..becf13fd9 100644
--- a/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java
@@ -38,6 +38,7 @@ import com.android.inputmethod.latin.DictionaryFacilitator;
import com.android.inputmethod.latin.DictionaryFacilitatorLruCache;
import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.RichInputMethodSubtype;
+import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.WordComposer;
import com.android.inputmethod.latin.common.StringUtils;
@@ -52,7 +53,6 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr
DistracterFilterCheckingExactMatchesAndSuggestions.class.getSimpleName();
private static final boolean DEBUG = false;
- private static final int MAX_DICTIONARY_FACILITATOR_CACHE_SIZE = 3;
private static final int MAX_DISTRACTERS_CACHE_SIZE = 1024;
private final Context mContext;
@@ -80,8 +80,8 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr
mContext = context;
mLocaleToSubtypeCache = new ConcurrentHashMap<>();
mLocaleToKeyboardCache = new ConcurrentHashMap<>();
- mDictionaryFacilitatorLruCache = new DictionaryFacilitatorLruCache(context,
- MAX_DICTIONARY_FACILITATOR_CACHE_SIZE, "" /* dictionaryNamePrefix */);
+ mDictionaryFacilitatorLruCache = new DictionaryFacilitatorLruCache(
+ context, "" /* dictionaryNamePrefix */);
mDistractersCache = new LruCache<>(MAX_DISTRACTERS_CACHE_SIZE);
}
@@ -195,8 +195,7 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr
mDistractersCache.put(cacheKey, Boolean.TRUE);
return true;
}
- final boolean Word = dictionaryFacilitator.isValidWord(testedWord, false /* ignoreCase */);
- if (Word) {
+ if (dictionaryFacilitator.isValidSuggestionWord(testedWord)) {
// Valid word is not a distracter.
if (DEBUG) {
Log.d(TAG, "isDistracter: false (valid word)");
@@ -252,7 +251,9 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr
suggestionResults = dictionaryFacilitator.getSuggestionResults(composer,
NgramContext.EMPTY_PREV_WORDS_INFO,
keyboard.getProximityInfo().getNativeProximityInfo(),
- settingsValuesForSuggestion, 0 /* sessionId */);
+ settingsValuesForSuggestion, 0 /* sessionId */,
+ SuggestedWords.INPUT_STYLE_TYPING,
+ keyboard.getKeyboardLayout());
}
if (suggestionResults.isEmpty()) {
return false;
@@ -288,14 +289,14 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr
final Locale locale) {
final DictionaryFacilitator dictionaryFacilitator =
mDictionaryFacilitatorLruCache.get(locale);
- if (dictionaryFacilitator.isValidWord(testedWord, false /* ignoreCase */)) {
+ if (dictionaryFacilitator.isValidSuggestionWord(testedWord)) {
return false;
}
- final String lowerCaseTargetWord = testedWord.toLowerCase(locale);
- if (testedWord.equals(lowerCaseTargetWord)) {
+ final String lowerCaseWord = testedWord.toLowerCase(locale);
+ if (testedWord.equals(lowerCaseWord)) {
return false;
}
- if (dictionaryFacilitator.isValidWord(lowerCaseTargetWord, false /* ignoreCase */)) {
+ if (dictionaryFacilitator.isValidSuggestionWord(lowerCaseWord)) {
return true;
}
if (StringUtils.getCapitalizationType(testedWord) == StringUtils.CAPITALIZE_FIRST
@@ -314,10 +315,10 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr
return HandlingType.getHandlingType(false /* shouldBeLowerCased */, false /* isOov */);
}
final boolean shouldBeLowerCased = shouldBeLowerCased(ngramContext, testedWord, locale);
- final String caseModifiedWord =
- shouldBeLowerCased ? testedWord.toLowerCase(locale) : testedWord;
- final boolean isOov = !mDictionaryFacilitatorLruCache.get(locale).isValidWord(
- caseModifiedWord, false /* ignoreCase */);
+ final String caseModifiedWord = shouldBeLowerCased
+ ? testedWord.toLowerCase(locale) : testedWord;
+ final boolean isOov = !mDictionaryFacilitatorLruCache.get(locale).isValidSuggestionWord(
+ caseModifiedWord);
return HandlingType.getHandlingType(shouldBeLowerCased, isOov);
}
}
diff --git a/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java b/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java
index 147e57b13..c87a7c05c 100644
--- a/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java
@@ -29,7 +29,6 @@ import com.android.inputmethod.latin.settings.PreferencesSettingsFragment;
import com.android.inputmethod.latin.settings.SettingsFragment;
import com.android.inputmethod.latin.settings.ThemeSettingsFragment;
import com.android.inputmethod.latin.spellcheck.SpellCheckerSettingsFragment;
-import com.android.inputmethod.latin.userdictionary.UserDictionaryAddWordFragment;
import com.android.inputmethod.latin.userdictionary.UserDictionaryList;
import com.android.inputmethod.latin.userdictionary.UserDictionaryLocalePicker;
import com.android.inputmethod.latin.userdictionary.UserDictionarySettings;
@@ -52,7 +51,6 @@ public class FragmentUtils {
sLatinImeFragments.add(DebugSettingsFragment.class.getName());
sLatinImeFragments.add(SettingsFragment.class.getName());
sLatinImeFragments.add(SpellCheckerSettingsFragment.class.getName());
- sLatinImeFragments.add(UserDictionaryAddWordFragment.class.getName());
sLatinImeFragments.add(UserDictionaryList.class.getName());
sLatinImeFragments.add(UserDictionaryLocalePicker.class.getName());
sLatinImeFragments.add(UserDictionarySettings.class.getName());
diff --git a/java/src/com/android/inputmethod/latin/utils/NgramContextUtils.java b/java/src/com/android/inputmethod/latin/utils/NgramContextUtils.java
index 7d2ddd268..727df1a93 100644
--- a/java/src/com/android/inputmethod/latin/utils/NgramContextUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/NgramContextUtils.java
@@ -18,7 +18,7 @@ package com.android.inputmethod.latin.utils;
import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.NgramContext.WordInfo;
-import com.android.inputmethod.latin.common.Constants;
+import com.android.inputmethod.latin.define.DecoderSpecificConstants;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
import java.util.Arrays;
@@ -59,7 +59,8 @@ public final class NgramContextUtils {
final SpacingAndPunctuations spacingAndPunctuations, final int n) {
if (prev == null) return NgramContext.EMPTY_PREV_WORDS_INFO;
final String[] w = SPACE_REGEX.split(prev);
- final WordInfo[] prevWordsInfo = new WordInfo[Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM];
+ final WordInfo[] prevWordsInfo =
+ new WordInfo[DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM];
Arrays.fill(prevWordsInfo, WordInfo.EMPTY_WORD_INFO);
for (int i = 0; i < prevWordsInfo.length; i++) {
final int focusedWordIndex = w.length - n - i;
diff --git a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
index b319aeb8a..10e3994b6 100644
--- a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
+++ b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
@@ -33,14 +33,21 @@ public final class SuggestionResults extends TreeSet<SuggestedWordInfo> {
// TODO: Instead of a boolean , we may want to include the context of this suggestion results,
// such as {@link NgramContext}.
public final boolean mIsBeginningOfSentence;
+ public final boolean mAutocorrectRecommendation;
private final int mCapacity;
public SuggestionResults(final int capacity, final boolean isBeginningOfSentence) {
- this(sSuggestedWordInfoComparator, capacity, isBeginningOfSentence);
+ this(sSuggestedWordInfoComparator, capacity, isBeginningOfSentence, false);
}
- private SuggestionResults(final Comparator<SuggestedWordInfo> comparator,
- final int capacity, final boolean isBeginningOfSentence) {
+ public SuggestionResults(final int capacity, final boolean isBeginningOfSentence,
+ final boolean autocorrectRecommendation) {
+ this(sSuggestedWordInfoComparator, capacity, isBeginningOfSentence,
+ autocorrectRecommendation);
+ }
+
+ private SuggestionResults(final Comparator<SuggestedWordInfo> comparator, final int capacity,
+ final boolean isBeginningOfSentence, final boolean autocorrectRecommendation) {
super(comparator);
mCapacity = capacity;
if (ProductionFlags.INCLUDE_RAW_SUGGESTIONS) {
@@ -49,6 +56,7 @@ public final class SuggestionResults extends TreeSet<SuggestedWordInfo> {
mRawSuggestions = null;
}
mIsBeginningOfSentence = isBeginningOfSentence;
+ mAutocorrectRecommendation = autocorrectRecommendation;
}
@Override
diff --git a/java/src/com/android/inputmethod/latin/utils/WordInputEventForPersonalization.java b/java/src/com/android/inputmethod/latin/utils/WordInputEventForPersonalization.java
index 86a5b19ec..e9a0e7a61 100644
--- a/java/src/com/android/inputmethod/latin/utils/WordInputEventForPersonalization.java
+++ b/java/src/com/android/inputmethod/latin/utils/WordInputEventForPersonalization.java
@@ -20,8 +20,8 @@ import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.NgramContext;
-import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.common.StringUtils;
+import com.android.inputmethod.latin.define.DecoderSpecificConstants;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
import com.android.inputmethod.latin.utils.DistracterFilter.HandlingType;
@@ -37,9 +37,10 @@ public final class WordInputEventForPersonalization {
public final int[] mTargetWord;
public final int mPrevWordsCount;
- public final int[][] mPrevWordArray = new int[Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM][];
+ public final int[][] mPrevWordArray =
+ new int[DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM][];
public final boolean[] mIsPrevWordBeginningOfSentenceArray =
- new boolean[Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM];
+ new boolean[DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM];
public final boolean mIsValid;
// Time stamp in seconds.
public final int mTimestamp;