aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--java-overridable/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java12
-rw-r--r--java/res/layout/input_view.xml3
-rw-r--r--java/res/values-v21/themes-lxx.xml28
-rw-r--r--java/res/values/attrs.xml2
-rw-r--r--java/res/values/themes-common.xml1
-rw-r--r--java/res/values/themes-holo.xml4
-rw-r--r--java/res/values/themes-ics.xml1
-rw-r--r--java/res/values/themes-klp.xml1
-rw-r--r--java/res/values/themes-lxx-dark.xml1
-rw-r--r--java/res/values/themes-lxx-light.xml1
-rw-r--r--java/res/values/themes-lxx.xml4
-rw-r--r--java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java186
-rw-r--r--java/src/com/android/inputmethod/compat/ViewCompatUtils.java7
-rw-r--r--java/src/com/android/inputmethod/compat/ViewOutlineProviderCompatUtils.java42
-rw-r--r--java/src/com/android/inputmethod/compat/ViewOutlineProviderCompatUtilsLXX.java72
-rw-r--r--java/src/com/android/inputmethod/keyboard/MainKeyboardView.java21
-rw-r--r--java/src/com/android/inputmethod/keyboard/TextDecorator.java6
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java31
-rw-r--r--java/src/com/android/inputmethod/latin/Dictionary.java16
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitator.java6
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java35
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputMethodManager.java4
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java22
-rw-r--r--java/src/com/android/inputmethod/latin/WordComposer.java18
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java83
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/WordProperty.java17
-rw-r--r--java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java6
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java24
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java6
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java2
-rw-r--r--java/src/com/android/inputmethod/latin/utils/CursorAnchorInfoUtils.java31
-rw-r--r--native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp53
-rw-r--r--native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp10
-rw-r--r--native/jni/src/suggest/core/dictionary/dictionary.cpp42
-rw-r--r--native/jni/src/suggest/core/dictionary/dictionary.h18
-rw-r--r--native/jni/src/suggest/core/dictionary/dictionary_utils.cpp8
-rw-r--r--native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h8
-rw-r--r--native/jni/src/suggest/core/session/dic_traverse_session.cpp6
-rw-r--r--native/jni/src/suggest/core/session/dic_traverse_session.h4
-rw-r--r--native/jni/src/suggest/core/session/ngram_context.h (renamed from native/jni/src/suggest/core/session/prev_words_info.h)31
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.cpp2
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp41
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h6
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp2
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h9
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_patricia_trie_node_reader.cpp2
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_patricia_trie_node_reader.h4
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp2
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp47
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h6
-rw-r--r--native/jni/src/utils/jni_data_utils.h6
-rw-r--r--tests/src/com/android/inputmethod/latin/InputTestsBase.java8
-rw-r--r--tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java45
53 files changed, 607 insertions, 446 deletions
diff --git a/java-overridable/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java b/java-overridable/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java
index 1c02d7d63..204d5f357 100644
--- a/java-overridable/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java
+++ b/java-overridable/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java
@@ -19,6 +19,12 @@ package com.android.inputmethod.latin.settings;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceFragment;
+import android.view.inputmethod.InputMethodSubtype;
+
+import com.android.inputmethod.latin.RichInputMethodSubtype;
+import com.android.inputmethod.latin.RichInputMethodManager;
+
+import javax.annotation.Nonnull;
/**
* Utility class for managing additional features settings.
@@ -39,4 +45,10 @@ public class AdditionalFeaturesSettingUtils {
final SharedPreferences prefs, final int[] additionalFeaturesPreferences) {
// do nothing.
}
+
+ public static RichInputMethodSubtype getRichInputMethodSubtype(
+ @Nonnull final RichInputMethodManager imm,
+ @Nonnull final InputMethodSubtype subtype) {
+ return new RichInputMethodSubtype(subtype);
+ }
}
diff --git a/java/res/layout/input_view.xml b/java/res/layout/input_view.xml
index 46551f63f..ae3c19db5 100644
--- a/java/res/layout/input_view.xml
+++ b/java/res/layout/input_view.xml
@@ -21,7 +21,8 @@
<com.android.inputmethod.latin.InputView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="wrap_content">
+ android:layout_height="wrap_content"
+ style="?attr/inputViewStyle">
<include
android:id="@+id/main_keyboard_frame"
layout="@layout/main_keyboard_frame" />
diff --git a/java/res/values-v21/themes-lxx.xml b/java/res/values-v21/themes-lxx.xml
new file mode 100644
index 000000000..5a6017cce
--- /dev/null
+++ b/java/res/values-v21/themes-lxx.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <style
+ name="InputView.LXX"
+ parent="InputView"
+ >
+ <item name="android:elevation">8dp</item>
+ </style>
+</resources>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index f2072fd37..be35d131d 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -20,6 +20,8 @@
<resources>
<declare-styleable name="KeyboardTheme">
+ <!-- InputView style -->
+ <attr name="inputViewStyle" format="reference" />
<!-- Keyboard style -->
<attr name="keyboardStyle" format="reference" />
<!-- KeyboardView style -->
diff --git a/java/res/values/themes-common.xml b/java/res/values/themes-common.xml
index 110f6b792..f7cb10f93 100644
--- a/java/res/values/themes-common.xml
+++ b/java/res/values/themes-common.xml
@@ -20,6 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="KeyboardIcons" />
+ <style name="InputView" />
<!-- Default theme values -->
<style name="Keyboard">
<item name="rowHeight">25%p</item>
diff --git a/java/res/values/themes-holo.xml b/java/res/values/themes-holo.xml
index 9f1bd2f78..efac65627 100644
--- a/java/res/values/themes-holo.xml
+++ b/java/res/values/themes-holo.xml
@@ -19,6 +19,10 @@
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <style
+ name="InputView.Holo"
+ parent="InputView"
+ />
<!-- Holo KeyboardView theme (ICS and KLP) -->
<style
name="KeyboardView.Holo"
diff --git a/java/res/values/themes-ics.xml b/java/res/values/themes-ics.xml
index bfbac0a94..ecf40e4e6 100644
--- a/java/res/values/themes-ics.xml
+++ b/java/res/values/themes-ics.xml
@@ -20,6 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="KeyboardTheme.ICS" parent="KeyboardIcons.Holo">
+ <item name="inputViewStyle">@style/InputView.Holo</item>
<item name="keyboardStyle">@style/Keyboard.ICS</item>
<item name="keyboardViewStyle">@style/KeyboardView.ICS</item>
<item name="mainKeyboardViewStyle">@style/MainKeyboardView.ICS</item>
diff --git a/java/res/values/themes-klp.xml b/java/res/values/themes-klp.xml
index 36b1fc117..de1cd9bf1 100644
--- a/java/res/values/themes-klp.xml
+++ b/java/res/values/themes-klp.xml
@@ -20,6 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="KeyboardTheme.KLP" parent="KeyboardIcons.Holo">
+ <item name="inputViewStyle">@style/InputView.Holo</item>
<item name="keyboardStyle">@style/Keyboard.KLP</item>
<item name="keyboardViewStyle">@style/KeyboardView.KLP</item>
<item name="mainKeyboardViewStyle">@style/MainKeyboardView.KLP</item>
diff --git a/java/res/values/themes-lxx-dark.xml b/java/res/values/themes-lxx-dark.xml
index 67f94f329..b081772e9 100644
--- a/java/res/values/themes-lxx-dark.xml
+++ b/java/res/values/themes-lxx-dark.xml
@@ -20,6 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="KeyboardTheme.LXX_Dark" parent="KeyboardIcons.LXX_Dark">
+ <item name="inputViewStyle">@style/InputView.LXX</item>
<item name="keyboardStyle">@style/Keyboard.LXX_Dark</item>
<item name="keyboardViewStyle">@style/KeyboardView.LXX_Dark</item>
<item name="mainKeyboardViewStyle">@style/MainKeyboardView.LXX_Dark</item>
diff --git a/java/res/values/themes-lxx-light.xml b/java/res/values/themes-lxx-light.xml
index be817f46a..3d294e450 100644
--- a/java/res/values/themes-lxx-light.xml
+++ b/java/res/values/themes-lxx-light.xml
@@ -20,6 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="KeyboardTheme.LXX_Light" parent="KeyboardIcons.LXX_Light">
+ <item name="inputViewStyle">@style/InputView.LXX</item>
<item name="keyboardStyle">@style/Keyboard.LXX_Light</item>
<item name="keyboardViewStyle">@style/KeyboardView.LXX_Light</item>
<item name="mainKeyboardViewStyle">@style/MainKeyboardView.LXX_Light</item>
diff --git a/java/res/values/themes-lxx.xml b/java/res/values/themes-lxx.xml
index c72188871..463306b43 100644
--- a/java/res/values/themes-lxx.xml
+++ b/java/res/values/themes-lxx.xml
@@ -19,6 +19,10 @@
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <style
+ name="InputView.LXX"
+ parent="InputView"
+ />
<!-- LXX KeyboardView theme (LXX_Light and LXX_Dark) -->
<style
name="KeyboardView.LXX"
diff --git a/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java b/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java
index 5af31795c..f4f54b624 100644
--- a/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java
+++ b/java/src/com/android/inputmethod/compat/CursorAnchorInfoCompatWrapper.java
@@ -16,13 +16,20 @@
package com.android.inputmethod.compat;
+import android.annotation.TargetApi;
import android.graphics.Matrix;
import android.graphics.RectF;
+import android.os.Build;
+import android.view.inputmethod.CursorAnchorInfo;
-import com.android.inputmethod.annotations.UsedForTesting;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
-@UsedForTesting
-public final class CursorAnchorInfoCompatWrapper {
+/**
+ * A wrapper for {@link CursorAnchorInfo}, which has been introduced in API Level 21. You can use
+ * this wrapper to avoid direct dependency on newly introduced types.
+ */
+public class CursorAnchorInfoCompatWrapper {
/**
* The insertion marker or character bounds have at least one visible region.
@@ -39,123 +46,138 @@ public final class CursorAnchorInfoCompatWrapper {
*/
public static final int FLAG_IS_RTL = 0x04;
- // Note that CursorAnchorInfo has been introduced in API level XX (Build.VERSION_CODE.LXX).
- private static final CompatUtils.ClassWrapper sCursorAnchorInfoClass;
- private static final CompatUtils.ToIntMethodWrapper sGetSelectionStartMethod;
- private static final CompatUtils.ToIntMethodWrapper sGetSelectionEndMethod;
- private static final CompatUtils.ToObjectMethodWrapper<RectF> sGetCharacterBoundsMethod;
- private static final CompatUtils.ToIntMethodWrapper sGetCharacterBoundsFlagsMethod;
- private static final CompatUtils.ToObjectMethodWrapper<CharSequence> sGetComposingTextMethod;
- private static final CompatUtils.ToIntMethodWrapper sGetComposingTextStartMethod;
- private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerBaselineMethod;
- private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerBottomMethod;
- private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerHorizontalMethod;
- private static final CompatUtils.ToFloatMethodWrapper sGetInsertionMarkerTopMethod;
- private static final CompatUtils.ToObjectMethodWrapper<Matrix> sGetMatrixMethod;
- private static final CompatUtils.ToIntMethodWrapper sGetInsertionMarkerFlagsMethod;
-
- private static int INVALID_TEXT_INDEX = -1;
- static {
- sCursorAnchorInfoClass = CompatUtils.getClassWrapper(
- "android.view.inputmethod.CursorAnchorInfo");
- sGetSelectionStartMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getSelectionStart", INVALID_TEXT_INDEX);
- sGetSelectionEndMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getSelectionEnd", INVALID_TEXT_INDEX);
- sGetCharacterBoundsMethod = sCursorAnchorInfoClass.getMethod(
- "getCharacterBounds", (RectF)null, int.class);
- sGetCharacterBoundsFlagsMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getCharacterBoundsFlags", 0, int.class);
- sGetComposingTextMethod = sCursorAnchorInfoClass.getMethod(
- "getComposingText", (CharSequence)null);
- sGetComposingTextStartMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getComposingTextStart", INVALID_TEXT_INDEX);
- sGetInsertionMarkerBaselineMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getInsertionMarkerBaseline", 0.0f);
- sGetInsertionMarkerBottomMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getInsertionMarkerBottom", 0.0f);
- sGetInsertionMarkerHorizontalMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getInsertionMarkerHorizontal", 0.0f);
- sGetInsertionMarkerTopMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getInsertionMarkerTop", 0.0f);
- sGetMatrixMethod = sCursorAnchorInfoClass.getMethod("getMatrix", (Matrix)null);
- sGetInsertionMarkerFlagsMethod = sCursorAnchorInfoClass.getPrimitiveMethod(
- "getInsertionMarkerFlags", 0);
- }
-
- @UsedForTesting
- public boolean isAvailable() {
- return sCursorAnchorInfoClass.exists() && mInstance != null;
- }
-
- private Object mInstance;
-
- private CursorAnchorInfoCompatWrapper(final Object instance) {
- mInstance = instance;
+ private CursorAnchorInfoCompatWrapper() {
+ // This class is not publicly instantiable.
}
- @UsedForTesting
- public static CursorAnchorInfoCompatWrapper fromObject(final Object instance) {
- if (!sCursorAnchorInfoClass.exists()) {
- return new CursorAnchorInfoCompatWrapper(null);
+ @TargetApi(BuildCompatUtils.VERSION_CODES_LXX)
+ @Nullable
+ public static CursorAnchorInfoCompatWrapper wrap(@Nullable final CursorAnchorInfo instance) {
+ if (Build.VERSION.SDK_INT < BuildCompatUtils.VERSION_CODES_LXX) {
+ return null;
}
- return new CursorAnchorInfoCompatWrapper(instance);
- }
-
- private static final class FakeHolder {
- static CursorAnchorInfoCompatWrapper sInstance = new CursorAnchorInfoCompatWrapper(null);
- }
-
- @UsedForTesting
- public static CursorAnchorInfoCompatWrapper getFake() {
- return FakeHolder.sInstance;
+ if (instance == null) {
+ return null;
+ }
+ return new RealWrapper(instance);
}
public int getSelectionStart() {
- return sGetSelectionStartMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
public int getSelectionEnd() {
- return sGetSelectionEndMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
public CharSequence getComposingText() {
- return sGetComposingTextMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
public int getComposingTextStart() {
- return sGetComposingTextStartMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
public Matrix getMatrix() {
- return sGetMatrixMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
public RectF getCharacterBounds(final int index) {
- return sGetCharacterBoundsMethod.invoke(mInstance, index);
+ throw new UnsupportedOperationException("not supported.");
}
public int getCharacterBoundsFlags(final int index) {
- return sGetCharacterBoundsFlagsMethod.invoke(mInstance, index);
+ throw new UnsupportedOperationException("not supported.");
}
public float getInsertionMarkerBaseline() {
- return sGetInsertionMarkerBaselineMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
public float getInsertionMarkerBottom() {
- return sGetInsertionMarkerBottomMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
public float getInsertionMarkerHorizontal() {
- return sGetInsertionMarkerHorizontalMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
public float getInsertionMarkerTop() {
- return sGetInsertionMarkerTopMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
}
public int getInsertionMarkerFlags() {
- return sGetInsertionMarkerFlagsMethod.invoke(mInstance);
+ throw new UnsupportedOperationException("not supported.");
+ }
+
+ @TargetApi(BuildCompatUtils.VERSION_CODES_LXX)
+ private static final class RealWrapper extends CursorAnchorInfoCompatWrapper {
+
+ @Nonnull
+ private final CursorAnchorInfo mInstance;
+
+ public RealWrapper(@Nonnull final CursorAnchorInfo info) {
+ mInstance = info;
+ }
+
+ @Override
+ public int getSelectionStart() {
+ return mInstance.getSelectionStart();
+ }
+
+ @Override
+ public int getSelectionEnd() {
+ return mInstance.getSelectionEnd();
+ }
+
+ @Override
+ public CharSequence getComposingText() {
+ return mInstance.getComposingText();
+ }
+
+ @Override
+ public int getComposingTextStart() {
+ return mInstance.getComposingTextStart();
+ }
+
+ @Override
+ public Matrix getMatrix() {
+ return mInstance.getMatrix();
+ }
+
+ @Override
+ public RectF getCharacterBounds(final int index) {
+ return mInstance.getCharacterBounds(index);
+ }
+
+ @Override
+ public int getCharacterBoundsFlags(final int index) {
+ return mInstance.getCharacterBoundsFlags(index);
+ }
+
+ @Override
+ public float getInsertionMarkerBaseline() {
+ return mInstance.getInsertionMarkerBaseline();
+ }
+
+ @Override
+ public float getInsertionMarkerBottom() {
+ return mInstance.getInsertionMarkerBottom();
+ }
+
+ @Override
+ public float getInsertionMarkerHorizontal() {
+ return mInstance.getInsertionMarkerHorizontal();
+ }
+
+ @Override
+ public float getInsertionMarkerTop() {
+ return mInstance.getInsertionMarkerTop();
+ }
+
+ @Override
+ public int getInsertionMarkerFlags() {
+ return mInstance.getInsertionMarkerFlags();
+ }
}
}
diff --git a/java/src/com/android/inputmethod/compat/ViewCompatUtils.java b/java/src/com/android/inputmethod/compat/ViewCompatUtils.java
index 0f00be133..16260ab6a 100644
--- a/java/src/com/android/inputmethod/compat/ViewCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/ViewCompatUtils.java
@@ -31,9 +31,6 @@ public final class ViewCompatUtils {
private static final Method METHOD_setPaddingRelative = CompatUtils.getMethod(
View.class, "setPaddingRelative",
int.class, int.class, int.class, int.class);
- // Note that View.setElevation(float) has been introduced in API level 21.
- private static final Method METHOD_setElevation = CompatUtils.getMethod(
- View.class, "setElevation", float.class);
// Note that View.setTextAlignment(int) has been introduced in API level 17.
private static final Method METHOD_setTextAlignment = CompatUtils.getMethod(
View.class, "setTextAlignment", int.class);
@@ -58,10 +55,6 @@ public final class ViewCompatUtils {
CompatUtils.invoke(view, null, METHOD_setPaddingRelative, start, top, end, bottom);
}
- public static void setElevation(final View view, final float elevation) {
- CompatUtils.invoke(view, null, METHOD_setElevation, elevation);
- }
-
// These TEXT_ALIGNMENT_* constants have been introduced in API 17.
public static final int TEXT_ALIGNMENT_INHERIT = 0;
public static final int TEXT_ALIGNMENT_GRAVITY = 1;
diff --git a/java/src/com/android/inputmethod/compat/ViewOutlineProviderCompatUtils.java b/java/src/com/android/inputmethod/compat/ViewOutlineProviderCompatUtils.java
new file mode 100644
index 000000000..52b8b74e8
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/ViewOutlineProviderCompatUtils.java
@@ -0,0 +1,42 @@
+/*
+ * 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.compat;
+
+import android.inputmethodservice.InputMethodService;
+import android.view.View;
+
+public class ViewOutlineProviderCompatUtils {
+ private ViewOutlineProviderCompatUtils() {
+ // This utility class is not publicly instantiable.
+ }
+
+ public interface InsetsUpdater {
+ public void setInsets(final InputMethodService.Insets insets);
+ }
+
+ private static final InsetsUpdater EMPTY_INSETS_UPDATER = new InsetsUpdater() {
+ @Override
+ public void setInsets(final InputMethodService.Insets insets) {}
+ };
+
+ public static InsetsUpdater setInsetsOutlineProvider(final View view) {
+ if (BuildCompatUtils.EFFECTIVE_SDK_INT < BuildCompatUtils.VERSION_CODES_LXX) {
+ return EMPTY_INSETS_UPDATER;
+ }
+ return ViewOutlineProviderCompatUtilsLXX.setInsetsOutlineProvider(view);
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/ViewOutlineProviderCompatUtilsLXX.java b/java/src/com/android/inputmethod/compat/ViewOutlineProviderCompatUtilsLXX.java
new file mode 100644
index 000000000..f9917ac11
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/ViewOutlineProviderCompatUtilsLXX.java
@@ -0,0 +1,72 @@
+/*
+ * 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.compat;
+
+import android.annotation.TargetApi;
+import android.graphics.Outline;
+import android.inputmethodservice.InputMethodService;
+import android.os.Build;
+import android.view.View;
+import android.view.ViewOutlineProvider;
+
+import com.android.inputmethod.compat.ViewOutlineProviderCompatUtils.InsetsUpdater;
+
+@TargetApi(Build.VERSION_CODES.L)
+class ViewOutlineProviderCompatUtilsLXX {
+ private ViewOutlineProviderCompatUtilsLXX() {
+ // This utility class is not publicly instantiable.
+ }
+
+ static InsetsUpdater setInsetsOutlineProvider(final View view) {
+ final InsetsOutlineProvider provider = new InsetsOutlineProvider(view);
+ view.setOutlineProvider(provider);
+ return provider;
+ }
+
+ private static class InsetsOutlineProvider extends ViewOutlineProvider
+ implements InsetsUpdater {
+ private final View mView;
+ private static final int NO_DATA = -1;
+ private int mLastVisibleTopInsets = NO_DATA;
+
+ public InsetsOutlineProvider(final View view) {
+ mView = view;
+ view.setOutlineProvider(this);
+ }
+
+ @Override
+ public void setInsets(final InputMethodService.Insets insets) {
+ final int visibleTopInsets = insets.visibleTopInsets;
+ if (mLastVisibleTopInsets != visibleTopInsets) {
+ mLastVisibleTopInsets = visibleTopInsets;
+ mView.invalidateOutline();
+ }
+ }
+
+ @Override
+ public void getOutline(final View view, final Outline outline) {
+ if (mLastVisibleTopInsets == NO_DATA) {
+ // Call default implementation.
+ ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
+ return;
+ }
+ // TODO: Revisit this when floating/resize keyboard is supported.
+ outline.setRect(
+ view.getLeft(), mLastVisibleTopInsets, view.getRight(), view.getBottom());
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index ad30b746e..e7be6de4c 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -146,7 +146,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
// More keys keyboard
private final Paint mBackgroundDimAlphaPaint = new Paint();
- private boolean mNeedsToDimEntireKeyboard;
private final View mMoreKeysKeyboardContainer;
private final View mMoreKeysKeyboardForActionContainer;
private final WeakHashMap<Key, Keyboard> mMoreKeysKeyboardCache = new WeakHashMap<>();
@@ -673,7 +672,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
locatePreviewPlacerView();
panel.showInParent(mDrawingPreviewPlacerView);
mMoreKeysPanel = panel;
- dimEntireKeyboard(true /* dimmed */);
}
public boolean isShowingMoreKeysPanel() {
@@ -687,7 +685,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
@Override
public void onDismissMoreKeysPanel() {
- dimEntireKeyboard(false /* dimmed */);
if (isShowingMoreKeysPanel()) {
mMoreKeysPanel.removeFromParent();
mMoreKeysPanel = null;
@@ -815,24 +812,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
invalidateKey(mSpaceKey);
}
- private void dimEntireKeyboard(final boolean dimmed) {
- final boolean needsRedrawing = mNeedsToDimEntireKeyboard != dimmed;
- mNeedsToDimEntireKeyboard = dimmed;
- if (needsRedrawing) {
- invalidateAllKeys();
- }
- }
-
- @Override
- protected void onDraw(final Canvas canvas) {
- super.onDraw(canvas);
-
- // Overlay a dark rectangle to dim.
- if (mNeedsToDimEntireKeyboard) {
- canvas.drawRect(0.0f, 0.0f, getWidth(), getHeight(), mBackgroundDimAlphaPaint);
- }
- }
-
@Override
protected void onDrawKeyTopVisuals(final Key key, final Canvas canvas, final Paint paint,
final KeyDrawParams params) {
diff --git a/java/src/com/android/inputmethod/keyboard/TextDecorator.java b/java/src/com/android/inputmethod/keyboard/TextDecorator.java
index c22717f95..ddc65bf36 100644
--- a/java/src/com/android/inputmethod/keyboard/TextDecorator.java
+++ b/java/src/com/android/inputmethod/keyboard/TextDecorator.java
@@ -30,6 +30,7 @@ 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
@@ -56,6 +57,7 @@ public class TextDecorator {
private String mWaitingWord = null;
private int mWaitingCursorStart = INVALID_CURSOR_INDEX;
private int mWaitingCursorEnd = INVALID_CURSOR_INDEX;
+ @Nullable
private CursorAnchorInfoCompatWrapper mCursorAnchorInfoWrapper = null;
@Nonnull
@@ -150,7 +152,7 @@ public class TextDecorator {
* mode.</p>
* @param info the compatibility wrapper object for the received {@link CursorAnchorInfo}.
*/
- public void onUpdateCursorAnchorInfo(final CursorAnchorInfoCompatWrapper info) {
+ public void onUpdateCursorAnchorInfo(@Nullable final CursorAnchorInfoCompatWrapper info) {
mCursorAnchorInfoWrapper = info;
// Do not use layoutLater() to minimize the latency.
layoutImmediately();
@@ -182,7 +184,7 @@ public class TextDecorator {
private void layoutMain() {
final CursorAnchorInfoCompatWrapper info = mCursorAnchorInfoWrapper;
- if (info == null || !info.isAvailable()) {
+ if (info == null) {
cancelLayoutInternalExpectedly("CursorAnchorInfo isn't available.");
return;
}
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 10dea749d..931f98a65 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -70,7 +70,7 @@ public final class BinaryDictionary extends Dictionary {
private static final int FORMAT_WORD_PROPERTY_OUTPUT_FLAG_COUNT = 5;
private static final int FORMAT_WORD_PROPERTY_IS_NOT_A_WORD_INDEX = 0;
private static final int FORMAT_WORD_PROPERTY_IS_BLACKLISTED_INDEX = 1;
- private static final int FORMAT_WORD_PROPERTY_HAS_BIGRAMS_INDEX = 2;
+ private static final int FORMAT_WORD_PROPERTY_HAS_NGRAMS_INDEX = 2;
private static final int FORMAT_WORD_PROPERTY_HAS_SHORTCUTS_INDEX = 3;
private static final int FORMAT_WORD_PROPERTY_IS_BEGINNING_OF_SENTENCE_INDEX = 4;
@@ -179,9 +179,10 @@ public final class BinaryDictionary extends Dictionary {
boolean[] isBeginningOfSentenceArray, int[] word);
private static native void getWordPropertyNative(long dict, int[] word,
boolean isBeginningOfSentence, int[] outCodePoints, boolean[] outFlags,
- int[] outProbabilityInfo, ArrayList<int[]> outBigramTargets,
- ArrayList<int[]> outBigramProbabilityInfo, ArrayList<int[]> outShortcutTargets,
- ArrayList<Integer> outShortcutProbabilities);
+ int[] outProbabilityInfo, ArrayList<int[][]> outNgramPrevWordsArray,
+ ArrayList<boolean[]> outNgramPrevWordIsBeginningOfSentenceArray,
+ ArrayList<int[]> outNgramTargets, ArrayList<int[]> outNgramProbabilityInfo,
+ ArrayList<int[]> outShortcutTargets, ArrayList<Integer> outShortcutProbabilities);
private static native int getNextWordNative(long dict, int token, int[] outCodePoints,
boolean[] outIsBeginningOfSentence);
private static native void getSuggestionsNative(long dict, long proximityInfo,
@@ -201,8 +202,7 @@ public final class BinaryDictionary extends Dictionary {
int[] word, int probability, int timestamp);
private static native boolean removeNgramEntryNative(long dict,
int[][] prevWordCodePointArrays, boolean[] isBeginningOfSentenceArray, int[] word);
- // TODO: Rename to updateEntriesForWordWithNgramContextNative.
- private static native boolean updateCounterNative(long dict,
+ private static native boolean updateEntriesForWordWithNgramContextNative(long dict,
int[][] prevWordCodePointArrays, boolean[] isBeginningOfSentenceArray,
int[] word, boolean isValidWord, int count, int timestamp);
private static native int addMultipleDictionaryEntriesNative(long dict,
@@ -388,20 +388,25 @@ public final class BinaryDictionary extends Dictionary {
final boolean[] outFlags = new boolean[FORMAT_WORD_PROPERTY_OUTPUT_FLAG_COUNT];
final int[] outProbabilityInfo =
new int[FORMAT_WORD_PROPERTY_OUTPUT_PROBABILITY_INFO_COUNT];
- final ArrayList<int[]> outBigramTargets = new ArrayList<>();
- final ArrayList<int[]> outBigramProbabilityInfo = new ArrayList<>();
+ final ArrayList<int[][]> outNgramPrevWordsArray = new ArrayList<>();
+ final ArrayList<boolean[]> outNgramPrevWordIsBeginningOfSentenceArray =
+ new ArrayList<>();
+ final ArrayList<int[]> outNgramTargets = new ArrayList<>();
+ final ArrayList<int[]> outNgramProbabilityInfo = new ArrayList<>();
final ArrayList<int[]> outShortcutTargets = new ArrayList<>();
final ArrayList<Integer> outShortcutProbabilities = new ArrayList<>();
getWordPropertyNative(mNativeDict, codePoints, isBeginningOfSentence, outCodePoints,
- outFlags, outProbabilityInfo, outBigramTargets, outBigramProbabilityInfo,
- outShortcutTargets, outShortcutProbabilities);
+ outFlags, outProbabilityInfo, outNgramPrevWordsArray,
+ outNgramPrevWordIsBeginningOfSentenceArray, outNgramTargets,
+ outNgramProbabilityInfo, outShortcutTargets, outShortcutProbabilities);
return new WordProperty(codePoints,
outFlags[FORMAT_WORD_PROPERTY_IS_NOT_A_WORD_INDEX],
outFlags[FORMAT_WORD_PROPERTY_IS_BLACKLISTED_INDEX],
- outFlags[FORMAT_WORD_PROPERTY_HAS_BIGRAMS_INDEX],
+ outFlags[FORMAT_WORD_PROPERTY_HAS_NGRAMS_INDEX],
outFlags[FORMAT_WORD_PROPERTY_HAS_SHORTCUTS_INDEX],
outFlags[FORMAT_WORD_PROPERTY_IS_BEGINNING_OF_SENTENCE_INDEX], outProbabilityInfo,
- outBigramTargets, outBigramProbabilityInfo, outShortcutTargets,
+ outNgramPrevWordsArray, outNgramPrevWordIsBeginningOfSentenceArray,
+ outNgramTargets, outNgramProbabilityInfo, outShortcutTargets,
outShortcutProbabilities);
}
@@ -506,7 +511,7 @@ public final class BinaryDictionary extends Dictionary {
final boolean[] isBeginningOfSentenceArray = new boolean[ngramContext.getPrevWordCount()];
ngramContext.outputToArray(prevWordCodePointArrays, isBeginningOfSentenceArray);
final int[] wordCodePoints = StringUtils.toCodePointArray(word);
- if (!updateCounterNative(mNativeDict, prevWordCodePointArrays,
+ if (!updateEntriesForWordWithNgramContextNative(mNativeDict, prevWordCodePointArrays,
isBeginningOfSentenceArray, wordCodePoints, isValidWord, count, timestamp)) {
return false;
}
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index 43561ba4b..e66847b56 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.latin;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
@@ -36,19 +37,19 @@ public abstract class Dictionary {
// The following types do not actually come from real dictionary instances, so we create
// corresponding instances.
public static final String TYPE_USER_TYPED = "user_typed";
- public static final Dictionary DICTIONARY_USER_TYPED = new PhonyDictionary(TYPE_USER_TYPED);
+ public static final PhonyDictionary DICTIONARY_USER_TYPED = new PhonyDictionary(TYPE_USER_TYPED);
public static final String TYPE_APPLICATION_DEFINED = "application_defined";
- public static final Dictionary DICTIONARY_APPLICATION_DEFINED =
+ public static final PhonyDictionary DICTIONARY_APPLICATION_DEFINED =
new PhonyDictionary(TYPE_APPLICATION_DEFINED);
public static final String TYPE_HARDCODED = "hardcoded"; // punctuation signs and such
- public static final Dictionary DICTIONARY_HARDCODED =
+ public static final PhonyDictionary DICTIONARY_HARDCODED =
new PhonyDictionary(TYPE_HARDCODED);
// Spawned by resuming suggestions. Comes from a span that was in the TextView.
public static final String TYPE_RESUMED = "resumed";
- public static final Dictionary DICTIONARY_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
@@ -182,9 +183,10 @@ public abstract class Dictionary {
* Not a true dictionary. A placeholder used to indicate suggestions that don't come from any
* real dictionary.
*/
- private static class PhonyDictionary extends Dictionary {
- // This class is not publicly instantiable.
- private PhonyDictionary(final String type) {
+ @UsedForTesting
+ static class PhonyDictionary extends Dictionary {
+ @UsedForTesting
+ PhonyDictionary(final String type) {
super(type, null);
}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index 6a63bfda7..08035dfd6 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -257,6 +257,12 @@ public class DictionaryFacilitator {
}
public void switchMostProbableLanguage(final Locale locale) {
+ if (null == locale) {
+ // In many cases, there is no locale to a committed word. For example, a typed word
+ // that does not auto-correct has no locale. In this case we simply do not change
+ // the most probable language.
+ return;
+ }
final DictionaryGroup newMostProbableDictionaryGroup =
findDictionaryGroupWithLocale(mDictionaryGroups, locale);
mMostProbableDictionaryGroup.mWeightForTypingInLocale =
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 77477d2d3..743b570ac 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -60,6 +60,8 @@ 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;
import com.android.inputmethod.dictionarypack.DictionaryPackConstants;
import com.android.inputmethod.event.Event;
import com.android.inputmethod.event.HardwareEventDecoder;
@@ -154,6 +156,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// TODO: Move these {@link View}s to {@link KeyboardSwitcher}.
private View mInputView;
+ private InsetsUpdater mInsetsUpdater;
private SuggestionStripView mSuggestionStripView;
private TextView mExtractEditText;
@@ -754,6 +757,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void setInputView(final View view) {
super.setInputView(view);
mInputView = view;
+ mInsetsUpdater = ViewOutlineProviderCompatUtils.setInsetsOutlineProvider(view);
updateSoftInputWindowLayoutParameters();
mSuggestionStripView = (SuggestionStripView)view.findViewById(R.id.suggestion_strip_view);
if (hasSuggestionStripView()) {
@@ -791,23 +795,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
- onExtractTextViewPreDraw();
+ // CursorAnchorInfo is used on L and later.
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.L) {
+ if (isFullscreenMode() && mExtractEditText != null) {
+ mInputLogic.onUpdateCursorAnchorInfo(
+ CursorAnchorInfoUtils.extractFromTextView(mExtractEditText));
+ }
+ }
return true;
}
};
- private void onExtractTextViewPreDraw() {
- // CursorAnchorInfo is available on L and later.
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.L) {
- return;
- }
- if (!isFullscreenMode() || mExtractEditText == null) {
- return;
- }
- final CursorAnchorInfo info = CursorAnchorInfoUtils.getCursorAnchorInfo(mExtractEditText);
- mInputLogic.onUpdateCursorAnchorInfo(CursorAnchorInfoCompatWrapper.fromObject(info));
- }
-
@Override
public void setCandidatesView(final View view) {
// To ensure that CandidatesView will never be set.
@@ -1090,7 +1088,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (isFullscreenMode()) {
return;
}
- mInputLogic.onUpdateCursorAnchorInfo(CursorAnchorInfoCompatWrapper.fromObject(info));
+ mInputLogic.onUpdateCursorAnchorInfo(CursorAnchorInfoCompatWrapper.wrap(info));
}
/**
@@ -1191,6 +1189,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// no visual element will be shown on the screen.
outInsets.touchableInsets = inputHeight;
outInsets.visibleTopInsets = inputHeight;
+ mInsetsUpdater.setInsets(outInsets);
return;
}
final int suggestionsHeight = (!mKeyboardSwitcher.isShowingEmojiPalettes()
@@ -1211,6 +1210,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
outInsets.contentTopInsets = visibleTopY;
outInsets.visibleTopInsets = visibleTopY;
+ mInsetsUpdater.setInsets(outInsets);
}
public void startShowingInputView(final boolean needsToLoadKeyboard) {
@@ -1539,7 +1539,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void setSuggestedWords(final SuggestedWords suggestedWords) {
final SettingsValues currentSettingsValues = mSettings.getCurrent();
- mInputLogic.setSuggestedWords(suggestedWords, currentSettingsValues, mHandler);
+ mInputLogic.setSuggestedWords(suggestedWords);
// TODO: Modify this when we support suggestions with hard keyboard
if (!hasSuggestionStripView()) {
return;
@@ -1627,7 +1627,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
@Override
- public void showAddToDictionaryHint(final String word) {
+ public void suggestAddingToDictionary(final String word, final boolean isFromSuggestionStrip) {
if (!hasSuggestionStripView()) {
return;
}
@@ -1637,7 +1637,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} else {
wordToShow = word;
}
- mSuggestionStripView.showAddToDictionaryHint(wordToShow);
+ mSuggestionStripView.showAddToDictionaryHint(wordToShow,
+ isFromSuggestionStrip /* shouldShowWordToSave */);
}
// This will show either an empty suggestion strip (if prediction is enabled) or
diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
index 0d5ce7d6d..b4ec8d674 100644
--- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
+++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
@@ -29,6 +29,7 @@ import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
+import com.android.inputmethod.latin.settings.AdditionalFeaturesSettingUtils;
import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
@@ -304,8 +305,7 @@ public class RichInputMethodManager {
if (currentSubtype == null) {
return defaultSubtype;
}
- // TODO: Determine locales to use for multi-lingual use.
- return new RichInputMethodSubtype(currentSubtype);
+ return AdditionalFeaturesSettingUtils.getRichInputMethodSubtype(this, currentSubtype);
}
public boolean hasMultipleEnabledIMEsOrSubtypes(final boolean shouldIncludeAuxiliarySubtypes) {
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 466576465..e0c06925c 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -413,28 +413,6 @@ public class SuggestedWords {
return isPrediction(mInputStyle);
}
- // SuggestedWords is an immutable object, as much as possible. We must not just remove
- // words from the member ArrayList as some other parties may expect the object to never change.
- // This is only ever called by recorrection at the moment, hence the ForRecorrection moniker.
- public SuggestedWords getSuggestedWordsExcludingTypedWordForRecorrection() {
- final ArrayList<SuggestedWordInfo> newSuggestions = new ArrayList<>();
- String typedWord = null;
- for (int i = 0; i < mSuggestedWordInfoList.size(); ++i) {
- final SuggestedWordInfo info = mSuggestedWordInfoList.get(i);
- if (!info.isKindOf(SuggestedWordInfo.KIND_TYPED)) {
- newSuggestions.add(info);
- } else {
- assert(null == typedWord);
- typedWord = info.mWord;
- }
- }
- // We should never autocorrect, so we say the typed word is valid. Also, in this case,
- // no auto-correction should take place hence willAutoCorrect = false.
- return new SuggestedWords(newSuggestions, null /* rawSuggestions */, typedWord,
- true /* typedWordValid */, false /* willAutoCorrect */, mIsObsoleteSuggestions,
- SuggestedWords.INPUT_STYLE_RECORRECTION, NOT_A_SEQUENCE_NUMBER);
- }
-
// Creates a new SuggestedWordInfo from the currently suggested words that removes all but the
// last word of all suggestions, separated by a space. This is necessary because when we commit
// a multiple-word suggestion, the IME only retains the last word as the composing word, and
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index 157bd1565..5eb338eb3 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -18,6 +18,7 @@ package com.android.inputmethod.latin;
import com.android.inputmethod.event.CombinerChain;
import com.android.inputmethod.event.Event;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.define.DebugFlags;
import com.android.inputmethod.latin.utils.CoordinateUtils;
import com.android.inputmethod.latin.utils.StringUtils;
@@ -48,8 +49,7 @@ public final class WordComposer {
// The list of events that served to compose this string.
private final ArrayList<Event> mEvents;
private final InputPointers mInputPointers = new InputPointers(MAX_WORD_LENGTH);
- private String mAutoCorrection;
- private String mAutoCorrectionDictionaryType;
+ private SuggestedWordInfo mAutoCorrection;
private boolean mIsResumed;
private boolean mIsBatchMode;
// A memory of the last rejected batch mode suggestion, if any. This goes like this: the user
@@ -418,26 +418,18 @@ public final class WordComposer {
/**
* Sets the auto-correction for this word.
*/
- public void setAutoCorrection(final String correction, String dictType) {
- mAutoCorrection = correction;
- mAutoCorrectionDictionaryType = dictType;
+ public void setAutoCorrection(final SuggestedWordInfo autoCorrection) {
+ mAutoCorrection = autoCorrection;
}
/**
* @return the auto-correction for this word, or null if none.
*/
- public String getAutoCorrectionOrNull() {
+ public SuggestedWordInfo getAutoCorrectionOrNull() {
return mAutoCorrection;
}
/**
- * @return the auto-correction dictionary type or null if none.
- */
- public String getAutoCorrectionDictionaryTypeOrNull() {
- return mAutoCorrectionDictionaryType;
- }
-
- /**
* @return whether we started composing this word by resuming suggestion on an existing string
*/
public boolean isResumed() {
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 07bfd0dee..f67b8de84 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -305,6 +305,7 @@ public final class InputLogic {
currentKeyboardScriptId, handler);
}
+ mDictionaryFacilitator.switchMostProbableLanguage(suggestionInfo.mSourceDict.mLocale);
final Event event = Event.createSuggestionPickedEvent(suggestionInfo);
final InputTransaction inputTransaction = new InputTransaction(settingsValues,
event, SystemClock.uptimeMillis(), mSpaceState, keyboardShiftState);
@@ -348,7 +349,8 @@ public final class InputLogic {
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
if (shouldShowAddToDictionaryHint) {
- mSuggestionStripViewAccessor.showAddToDictionaryHint(suggestion);
+ 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.
@@ -607,25 +609,21 @@ public final class InputLogic {
// TODO: on the long term, this method should become private, but it will be difficult.
// Especially, how do we deal with InputMethodService.onDisplayCompletions?
- public void setSuggestedWords(final SuggestedWords suggestedWords,
- final SettingsValues settingsValues, final LatinIME.UIHandler handler) {
+ public void setSuggestedWords(final SuggestedWords suggestedWords) {
if (!suggestedWords.isEmpty()) {
- final String autoCorrection;
- final String dictType;
+ final SuggestedWordInfo suggestedWordInfo;
if (suggestedWords.mWillAutoCorrect) {
- SuggestedWordInfo info = suggestedWords.getInfo(
- SuggestedWords.INDEX_OF_AUTO_CORRECTION);
- autoCorrection = info.mWord;
- dictType = info.mSourceDict.mDictType;
+ suggestedWordInfo = suggestedWords.getInfo(SuggestedWords.INDEX_OF_AUTO_CORRECTION);
} else {
// We can't use suggestedWords.getWord(SuggestedWords.INDEX_OF_TYPED_WORD)
// because it may differ from mWordComposer.mTypedWord.
- autoCorrection = suggestedWords.mTypedWord;
- dictType = Dictionary.TYPE_USER_TYPED;
+ suggestedWordInfo = new SuggestedWordInfo(suggestedWords.mTypedWord,
+ SuggestedWordInfo.MAX_SCORE,
+ SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED,
+ SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
+ SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */);
}
- // TODO: Use the SuggestedWordInfo to set the auto correction when
- // user typed word is available via SuggestedWordInfo.
- mWordComposer.setAutoCorrection(autoCorrection, dictType);
+ mWordComposer.setAutoCorrection(suggestedWordInfo);
}
mSuggestedWords = suggestedWords;
final boolean newAutoCorrectionIndicator = suggestedWords.mWillAutoCorrect;
@@ -1488,6 +1486,11 @@ public final class InputLogic {
if (numberOfCharsInWordBeforeCursor > expectedCursorPosition) return;
final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<>();
final String typedWord = range.mWord.toString();
+ suggestions.add(new SuggestedWordInfo(typedWord,
+ SuggestedWords.MAX_SUGGESTIONS + 1,
+ SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED,
+ SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
+ SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */));
if (!isResumableWord(settingsValues, typedWord)) {
mSuggestionStripViewAccessor.setNeutralSuggestionStrip();
return;
@@ -1520,30 +1523,14 @@ public final class InputLogic {
mConnection.maybeMoveTheCursorAroundAndRestoreToWorkaroundABug();
mConnection.setComposingRegion(expectedCursorPosition - numberOfCharsInWordBeforeCursor,
expectedCursorPosition + range.getNumberOfCharsInWordAfterCursor());
- if (suggestions.size() <= 0) {
+ if (suggestions.size() <= 1) {
// If there weren't any suggestion spans on this word, suggestions#size() will be 1
// if shouldIncludeResumedWordInSuggestions is true, 0 otherwise. In this case, we
// have no useful suggestions, so we will try to compute some for it instead.
mInputLogicHandler.getSuggestedWords(Suggest.SESSION_ID_TYPING,
SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() {
@Override
- public void onGetSuggestedWords(
- final SuggestedWords suggestedWordsIncludingTypedWord) {
- final SuggestedWords suggestedWords;
- if (suggestedWordsIncludingTypedWord.size() > 1) {
- // We were able to compute new suggestions for this word.
- // Remove the typed word, since we don't want to display it in this
- // case. The #getSuggestedWordsExcludingTypedWordForRecorrection()
- // method sets willAutoCorrect to false.
- suggestedWords = suggestedWordsIncludingTypedWord
- .getSuggestedWordsExcludingTypedWordForRecorrection();
- } else {
- // No saved suggestions, and we were unable to compute any good one
- // either. Rather than displaying an empty suggestion strip, we'll
- // display the original word alone in the middle.
- // Since there is only one word, willAutoCorrect is false.
- suggestedWords = suggestedWordsIncludingTypedWord;
- }
+ public void onGetSuggestedWords(final SuggestedWords suggestedWords) {
mIsAutoCorrectionIndicatorOn = false;
mLatinIME.mHandler.showSuggestionStrip(suggestedWords);
}});
@@ -1687,7 +1674,8 @@ public final class InputLogic {
mConnection.getExpectedSelectionStart(),
mConnection.getExpectedSelectionEnd());
}
- mSuggestionStripViewAccessor.showAddToDictionaryHint(originallyTypedWordString);
+ mSuggestionStripViewAccessor.suggestAddingToDictionary(originallyTypedWordString,
+ false /* isFromSuggestionStrip */);
} else {
// We have a separator between the word and the cursor: we should show predictions.
inputTransaction.setRequiresUpdateSuggestions();
@@ -2092,19 +2080,23 @@ public final class InputLogic {
// INPUT_STYLE_TYPING.
performUpdateSuggestionStripSync(settingsValues, SuggestedWords.INPUT_STYLE_TYPING);
}
- final String typedAutoCorrection = mWordComposer.getAutoCorrectionOrNull();
+ final SuggestedWordInfo autoCorrectionOrNull = mWordComposer.getAutoCorrectionOrNull();
final String typedWord = mWordComposer.getTypedWord();
- final String autoCorrection = (typedAutoCorrection != null)
- ? typedAutoCorrection : typedWord;
- if (autoCorrection != null) {
+ final String stringToCommit = (autoCorrectionOrNull != null)
+ ? autoCorrectionOrNull.mWord : typedWord;
+ if (stringToCommit != null) {
if (TextUtils.isEmpty(typedWord)) {
throw new RuntimeException("We have an auto-correction but the typed word "
+ "is empty? Impossible! I must commit suicide.");
}
final boolean isBatchMode = mWordComposer.isBatchMode();
- commitChosenWord(settingsValues, autoCorrection,
+ commitChosenWord(settingsValues, stringToCommit,
LastComposedWord.COMMIT_TYPE_DECIDED_WORD, separator);
- if (!typedWord.equals(autoCorrection)) {
+ if (null != autoCorrectionOrNull) {
+ mDictionaryFacilitator.switchMostProbableLanguage(
+ autoCorrectionOrNull.mSourceDict.mLocale);
+ }
+ if (!typedWord.equals(stringToCommit)) {
// This will make the correction flash for a short while as a visual clue
// to the user that auto-correction happened. It has no other effect; in particular
// note that this won't affect the text inside the text field AT ALL: it only makes
@@ -2112,13 +2104,14 @@ public final class InputLogic {
// of the auto-correction flash. At this moment, the "typedWord" argument is
// ignored by TextView.
mConnection.commitCorrection(new CorrectionInfo(
- mConnection.getExpectedSelectionEnd() - autoCorrection.length(),
- typedWord, autoCorrection));
- StatsUtils.onAutoCorrection(typedWord, autoCorrection, isBatchMode,
- mWordComposer.getAutoCorrectionDictionaryTypeOrNull());
- StatsUtils.onWordCommitAutoCorrect(autoCorrection, isBatchMode);
+ mConnection.getExpectedSelectionEnd() - stringToCommit.length(),
+ typedWord, stringToCommit));
+ StatsUtils.onAutoCorrection(typedWord, stringToCommit, isBatchMode,
+ null == autoCorrectionOrNull
+ ? null : autoCorrectionOrNull.mSourceDict.mDictType);
+ StatsUtils.onWordCommitAutoCorrect(stringToCommit, isBatchMode);
} else {
- StatsUtils.onWordCommitUserTyped(autoCorrection, isBatchMode);
+ StatsUtils.onWordCommitUserTyped(stringToCommit, isBatchMode);
}
}
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/WordProperty.java b/java/src/com/android/inputmethod/latin/makedict/WordProperty.java
index a180d060e..1e6cadf03 100644
--- a/java/src/com/android/inputmethod/latin/makedict/WordProperty.java
+++ b/java/src/com/android/inputmethod/latin/makedict/WordProperty.java
@@ -26,6 +26,8 @@ import com.android.inputmethod.latin.utils.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
+import javax.annotation.Nullable;
+
/**
* Utility class for a word with a probability.
*
@@ -49,7 +51,7 @@ public final class WordProperty implements Comparable<WordProperty> {
@UsedForTesting
public WordProperty(final String word, final ProbabilityInfo probabilityInfo,
final ArrayList<WeightedString> shortcutTargets,
- final ArrayList<WeightedString> bigrams,
+ @Nullable final ArrayList<WeightedString> bigrams,
final boolean isNotAWord, final boolean isBlacklistEntry) {
mWord = word;
mProbabilityInfo = probabilityInfo;
@@ -85,7 +87,9 @@ public final class WordProperty implements Comparable<WordProperty> {
public WordProperty(final int[] codePoints, final boolean isNotAWord,
final boolean isBlacklisted, final boolean hasBigram, final boolean hasShortcuts,
final boolean isBeginningOfSentence, final int[] probabilityInfo,
- final ArrayList<int[]> bigramTargets, final ArrayList<int[]> bigramProbabilityInfo,
+ final ArrayList<int[][]> ngramPrevWordsArray,
+ final ArrayList<boolean[]> outNgramPrevWordIsBeginningOfSentenceArray,
+ final ArrayList<int[]> ngramTargets, final ArrayList<int[]> ngramProbabilityInfo,
final ArrayList<int[]> shortcutTargets,
final ArrayList<Integer> shortcutProbabilities) {
mWord = StringUtils.getStringFromNullTerminatedCodePointArray(codePoints);
@@ -98,15 +102,15 @@ public final class WordProperty implements Comparable<WordProperty> {
mHasShortcuts = hasShortcuts;
mHasNgrams = hasBigram;
- final int relatedNgramCount = bigramTargets.size();
+ final int relatedNgramCount = ngramTargets.size();
final WordInfo currentWordInfo =
mIsBeginningOfSentence ? WordInfo.BEGINNING_OF_SENTENCE : new WordInfo(mWord);
final NgramContext ngramContext = new NgramContext(currentWordInfo);
for (int i = 0; i < relatedNgramCount; i++) {
final String ngramTargetString =
- StringUtils.getStringFromNullTerminatedCodePointArray(bigramTargets.get(i));
+ StringUtils.getStringFromNullTerminatedCodePointArray(ngramTargets.get(i));
final WeightedString ngramTarget = new WeightedString(ngramTargetString,
- createProbabilityInfoFromArray(bigramProbabilityInfo.get(i)));
+ createProbabilityInfoFromArray(ngramProbabilityInfo.get(i)));
// TODO: Support n-gram.
ngrams.add(new NgramProperty(ngramTarget, ngramContext));
}
@@ -180,7 +184,8 @@ public final class WordProperty implements Comparable<WordProperty> {
&& mHasNgrams == w.mHasNgrams && mHasShortcuts && w.mHasNgrams;
}
- private <T> boolean equals(final ArrayList<T> a, final ArrayList<T> b) {
+ // TDOO: Have a utility method like java.util.Objects.equals.
+ private static <T> boolean equals(final ArrayList<T> a, final ArrayList<T> b) {
if (null == a) {
return null == b;
}
diff --git a/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java
index a02cb5539..45792fe0e 100644
--- a/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java
@@ -28,6 +28,7 @@ import android.text.TextUtils;
import android.widget.ListView;
import android.widget.Toast;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SubtypeSwitcher;
import com.android.inputmethod.latin.accounts.LoginAccountUtils;
@@ -157,10 +158,10 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
final String currentAccount = getCurrentlySelectedAccount();
if (currentAccount == null) {
syncNowPreference.setEnabled(false);
- syncNowPreference.setSummary(R.string.sync_now_summary);
+ syncNowPreference.setSummary(R.string.sync_now_summary_disabled_signed_out);
} else {
syncNowPreference.setEnabled(true);
- syncNowPreference.setSummary(R.string.sync_now_summary_disabled_signed_out);
+ syncNowPreference.setSummary(R.string.sync_now_summary);
}
}
@@ -176,6 +177,7 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
*
* Package-private for testing.
*/
+ @UsedForTesting
AlertDialog createAccountPicker(final String[] accounts,
final String selectedAccount) {
if (accounts == null || accounts.length == 0) {
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index d55939971..0c8441454 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -553,12 +553,12 @@ final class SuggestionStripLayoutHelper {
return countInStrip;
}
- public void layoutAddToDictionaryHint(final String word, final ViewGroup addToDictionaryStrip) {
- final boolean shouldShowUiToAcceptTypedWord = Settings.getInstance().getCurrent()
- .mShouldShowLxxSuggestionUi;
+ 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 = shouldShowUiToAcceptTypedWord ? stripWidth
- : stripWidth - mDividerWidth - mPadding * 2;
+ final int width = stripWidth - (showsHintWithWord ? mDividerWidth + mPadding * 2 : 0);
final TextView wordView = (TextView)addToDictionaryStrip.findViewById(R.id.word_to_save);
wordView.setTextColor(mColorTypedWord);
@@ -569,7 +569,7 @@ final class SuggestionStripLayoutHelper {
wordView.setText(wordToSave);
wordView.setTextScaleX(wordScaleX);
setLayoutWeight(wordView, mCenterSuggestionWeight, ViewGroup.LayoutParams.MATCH_PARENT);
- final int wordVisibility = shouldShowUiToAcceptTypedWord ? View.GONE : View.VISIBLE;
+ final int wordVisibility = showsHintWithWord ? View.VISIBLE : View.GONE;
wordView.setVisibility(wordVisibility);
addToDictionaryStrip.findViewById(R.id.word_to_save_divider).setVisibility(wordVisibility);
@@ -579,12 +579,7 @@ final class SuggestionStripLayoutHelper {
final float hintWeight;
final TextView hintView = (TextView)addToDictionaryStrip.findViewById(
R.id.hint_add_to_dictionary);
- if (shouldShowUiToAcceptTypedWord) {
- hintText = res.getText(R.string.hint_add_to_dictionary_without_word);
- hintWidth = width;
- hintWeight = 1.0f;
- hintView.setGravity(Gravity.CENTER);
- } else {
+ if (showsHintWithWord) {
final boolean isRtlLanguage = (ViewCompat.getLayoutDirection(addToDictionaryStrip)
== ViewCompat.LAYOUT_DIRECTION_RTL);
final String arrow = isRtlLanguage ? RIGHTWARDS_ARROW : LEFTWARDS_ARROW;
@@ -595,6 +590,11 @@ final class SuggestionStripLayoutHelper {
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());
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index e40fd8800..789d549d7 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -231,8 +231,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
return mStripVisibilityGroup.isShowingAddToDictionaryStrip();
}
- public void showAddToDictionaryHint(final String word) {
- mLayoutHelper.layoutAddToDictionaryHint(word, mAddToDictionaryStrip);
+ 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);
@@ -501,7 +501,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
return;
}
final Object tag = view.getTag();
- // {@link String} tag is set at {@link #showAddToDictionaryHint(String,CharSequence)}.
+ // {@link String} tag is set at {@link #suggestAddingToDictionary(String,CharSequence)}.
if (tag instanceof String) {
final String wordToSave = (String)tag;
mListener.addWordToUserDictionary(wordToSave);
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java
index 52708455e..5c86a02af 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java
@@ -22,7 +22,7 @@ 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 showAddToDictionaryHint(final String word);
+ public void suggestAddingToDictionary(final String word, final boolean isFromSuggestionStrip);
public boolean isShowingAddToDictionaryHint();
public void dismissAddToDictionaryHint();
public void setNeutralSuggestionStrip();
diff --git a/java/src/com/android/inputmethod/latin/utils/CursorAnchorInfoUtils.java b/java/src/com/android/inputmethod/latin/utils/CursorAnchorInfoUtils.java
index 9dc0524a2..e05618901 100644
--- a/java/src/com/android/inputmethod/latin/utils/CursorAnchorInfoUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CursorAnchorInfoUtils.java
@@ -16,10 +16,12 @@
package com.android.inputmethod.latin.utils;
+import android.annotation.TargetApi;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.inputmethodservice.ExtractEditText;
import android.inputmethodservice.InputMethodService;
+import android.os.Build;
import android.text.Layout;
import android.text.Spannable;
import android.view.View;
@@ -27,6 +29,12 @@ import android.view.ViewParent;
import android.view.inputmethod.CursorAnchorInfo;
import android.widget.TextView;
+import com.android.inputmethod.compat.BuildCompatUtils;
+import com.android.inputmethod.compat.CursorAnchorInfoCompatWrapper;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
/**
* This class allows input methods to extract {@link CursorAnchorInfo} directly from the given
* {@link TextView}. This is useful and even necessary to support full-screen mode where the default
@@ -77,13 +85,32 @@ public final class CursorAnchorInfoUtils {
}
/**
+ * Extracts {@link CursorAnchorInfoCompatWrapper} from the given {@link TextView}.
+ * @param textView the target text view from which {@link CursorAnchorInfoCompatWrapper} is to
+ * be extracted.
+ * @return the {@link CursorAnchorInfoCompatWrapper} object based on the current layout.
+ * {@code null} if {@code Build.VERSION.SDK_INT} is 20 or prior or {@link TextView} is not
+ * ready to provide layout information.
+ */
+ @Nullable
+ public static CursorAnchorInfoCompatWrapper extractFromTextView(
+ @Nonnull final TextView textView) {
+ if (Build.VERSION.SDK_INT < BuildCompatUtils.VERSION_CODES_LXX) {
+ return null;
+ }
+ return CursorAnchorInfoCompatWrapper.wrap(extractFromTextViewInternal(textView));
+ }
+
+ /**
* Returns {@link CursorAnchorInfo} from the given {@link TextView}.
* @param textView the target text view from which {@link CursorAnchorInfo} is to be extracted.
* @return the {@link CursorAnchorInfo} object based on the current layout. {@code null} if it
* is not feasible.
*/
- public static CursorAnchorInfo getCursorAnchorInfo(final TextView textView) {
- Layout layout = textView.getLayout();
+ @TargetApi(BuildCompatUtils.VERSION_CODES_LXX)
+ @Nullable
+ private static CursorAnchorInfo extractFromTextViewInternal(@Nonnull final TextView textView) {
+ final Layout layout = textView.getLayout();
if (layout == null) {
return null;
}
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index 76c7fdd6f..f8dadb488 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -28,7 +28,7 @@
#include "suggest/core/dictionary/property/unigram_property.h"
#include "suggest/core/dictionary/property/word_property.h"
#include "suggest/core/result/suggestion_results.h"
-#include "suggest/core/session/prev_words_info.h"
+#include "suggest/core/session/ngram_context.h"
#include "suggest/core/suggest_options.h"
#include "suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.h"
#include "utils/char_utils.h"
@@ -242,15 +242,15 @@ static void latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jclass clazz,
env->GetFloatArrayRegion(inOutWeightOfLangModelVsSpatialModel, 0, 1 /* len */,
&weightOfLangModelVsSpatialModel);
SuggestionResults suggestionResults(MAX_RESULTS);
- const PrevWordsInfo prevWordsInfo = JniDataUtils::constructPrevWordsInfo(env,
+ const NgramContext ngramContext = JniDataUtils::constructNgramContext(env,
prevWordCodePointArrays, isBeginningOfSentenceArray, prevWordCount);
if (givenSuggestOptions.isGesture() || inputSize > 0) {
// TODO: Use SuggestionResults to return suggestions.
dictionary->getSuggestions(pInfo, traverseSession, xCoordinates, yCoordinates,
- times, pointerIds, inputCodePoints, inputSize, &prevWordsInfo,
+ times, pointerIds, inputCodePoints, inputSize, &ngramContext,
&givenSuggestOptions, weightOfLangModelVsSpatialModel, &suggestionResults);
} else {
- dictionary->getPredictions(&prevWordsInfo, &suggestionResults);
+ dictionary->getPredictions(&ngramContext, &suggestionResults);
}
if (DEBUG_DICT) {
suggestionResults.dumpSuggestions();
@@ -289,10 +289,10 @@ static jint latinime_BinaryDictionary_getNgramProbability(JNIEnv *env, jclass cl
const jsize wordLength = env->GetArrayLength(word);
int wordCodePoints[wordLength];
env->GetIntArrayRegion(word, 0, wordLength, wordCodePoints);
- const PrevWordsInfo prevWordsInfo = JniDataUtils::constructPrevWordsInfo(env,
+ const NgramContext ngramContext = JniDataUtils::constructNgramContext(env,
prevWordCodePointArrays, isBeginningOfSentenceArray,
env->GetArrayLength(prevWordCodePointArrays));
- return dictionary->getNgramProbability(&prevWordsInfo,
+ return dictionary->getNgramProbability(&ngramContext,
CodePointArrayView(wordCodePoints, wordLength));
}
@@ -327,8 +327,9 @@ static jint latinime_BinaryDictionary_getNextWord(JNIEnv *env, jclass clazz,
static void latinime_BinaryDictionary_getWordProperty(JNIEnv *env, jclass clazz,
jlong dict, jintArray word, jboolean isBeginningOfSentence, jintArray outCodePoints,
- jbooleanArray outFlags, jintArray outProbabilityInfo, jobject outBigramTargets,
- jobject outBigramProbabilityInfo, jobject outShortcutTargets,
+ jbooleanArray outFlags, jintArray outProbabilityInfo, jobject /* outNgramPrevWordsArray */,
+ jobject /* outNgramPrevWordIsBeginningOfSentenceArray */, jobject outNgramTargets,
+ jobject outNgramProbabilityInfo, jobject outShortcutTargets,
jobject outShortcutProbabilities) {
Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict);
if (!dictionary) return;
@@ -351,7 +352,7 @@ static void latinime_BinaryDictionary_getWordProperty(JNIEnv *env, jclass clazz,
const WordProperty wordProperty = dictionary->getWordProperty(
CodePointArrayView(wordCodePoints, codePointCount));
wordProperty.outputProperties(env, outCodePoints, outFlags, outProbabilityInfo,
- outBigramTargets, outBigramProbabilityInfo, outShortcutTargets,
+ outNgramTargets, outNgramProbabilityInfo, outShortcutTargets,
outShortcutProbabilities);
}
@@ -401,7 +402,7 @@ static bool latinime_BinaryDictionary_addNgramEntry(JNIEnv *env, jclass clazz, j
if (!dictionary) {
return false;
}
- const PrevWordsInfo prevWordsInfo = JniDataUtils::constructPrevWordsInfo(env,
+ const NgramContext ngramContext = JniDataUtils::constructNgramContext(env,
prevWordCodePointArrays, isBeginningOfSentenceArray,
env->GetArrayLength(prevWordCodePointArrays));
jsize wordLength = env->GetArrayLength(word);
@@ -410,7 +411,7 @@ static bool latinime_BinaryDictionary_addNgramEntry(JNIEnv *env, jclass clazz, j
// Use 1 for count to indicate the ngram has inputted.
const NgramProperty ngramProperty(CodePointArrayView(wordCodePoints, wordLength).toVector(),
probability, HistoricalInfo(timestamp, 0 /* level */, 1 /* count */));
- return dictionary->addNgramEntry(&prevWordsInfo, &ngramProperty);
+ return dictionary->addNgramEntry(&ngramContext, &ngramProperty);
}
static bool latinime_BinaryDictionary_removeNgramEntry(JNIEnv *env, jclass clazz, jlong dict,
@@ -420,31 +421,32 @@ static bool latinime_BinaryDictionary_removeNgramEntry(JNIEnv *env, jclass clazz
if (!dictionary) {
return false;
}
- const PrevWordsInfo prevWordsInfo = JniDataUtils::constructPrevWordsInfo(env,
+ const NgramContext ngramContext = JniDataUtils::constructNgramContext(env,
prevWordCodePointArrays, isBeginningOfSentenceArray,
env->GetArrayLength(prevWordCodePointArrays));
jsize codePointCount = env->GetArrayLength(word);
int wordCodePoints[codePointCount];
env->GetIntArrayRegion(word, 0, codePointCount, wordCodePoints);
- return dictionary->removeNgramEntry(&prevWordsInfo,
+ return dictionary->removeNgramEntry(&ngramContext,
CodePointArrayView(wordCodePoints, codePointCount));
}
-static bool latinime_BinaryDictionary_updateCounter(JNIEnv *env, jclass clazz, jlong dict,
- jobjectArray prevWordCodePointArrays, jbooleanArray isBeginningOfSentenceArray,
- jintArray word, jboolean isValidWord, jint count, jint timestamp) {
+static bool latinime_BinaryDictionary_updateEntriesForWordWithNgramContext(JNIEnv *env,
+ jclass clazz, jlong dict, jobjectArray prevWordCodePointArrays,
+ jbooleanArray isBeginningOfSentenceArray, jintArray word, jboolean isValidWord, jint count,
+ jint timestamp) {
Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict);
if (!dictionary) {
return false;
}
- const PrevWordsInfo prevWordsInfo = JniDataUtils::constructPrevWordsInfo(env,
+ const NgramContext ngramContext = JniDataUtils::constructNgramContext(env,
prevWordCodePointArrays, isBeginningOfSentenceArray,
env->GetArrayLength(prevWordCodePointArrays));
jsize codePointCount = env->GetArrayLength(word);
int wordCodePoints[codePointCount];
env->GetIntArrayRegion(word, 0, codePointCount, wordCodePoints);
const HistoricalInfo historicalInfo(timestamp, 0 /* level */, count);
- return dictionary->updateCounter(&prevWordsInfo,
+ return dictionary->updateEntriesForWordWithNgramContext(&ngramContext,
CodePointArrayView(wordCodePoints, codePointCount), isValidWord == JNI_TRUE,
historicalInfo);
}
@@ -527,9 +529,9 @@ static int latinime_BinaryDictionary_addMultipleDictionaryEntries(JNIEnv *env, j
const NgramProperty ngramProperty(
CodePointArrayView(word1CodePoints, word1Length).toVector(),
bigramProbability, HistoricalInfo(timestamp, 0 /* level */, 1 /* count */));
- const PrevWordsInfo prevWordsInfo(word0CodePoints, word0Length,
+ const NgramContext ngramContext(word0CodePoints, word0Length,
false /* isBeginningOfSentence */);
- dictionary->addNgramEntry(&prevWordsInfo, &ngramProperty);
+ dictionary->addNgramEntry(&ngramContext, &ngramProperty);
}
if (dictionary->needsToRunGC(true /* mindsBlockByGC */)) {
return i + 1;
@@ -639,10 +641,10 @@ static bool latinime_BinaryDictionary_migrateNative(JNIEnv *env, jclass clazz, j
return false;
}
}
- const PrevWordsInfo prevWordsInfo(wordCodePoints, wordCodePointCount,
+ const NgramContext ngramContext(wordCodePoints, wordCodePointCount,
wordProperty.getUnigramProperty()->representsBeginningOfSentence());
for (const NgramProperty &ngramProperty : *wordProperty.getNgramProperties()) {
- if (!dictionaryStructureWithBufferPolicy->addNgramEntry(&prevWordsInfo,
+ if (!dictionaryStructureWithBufferPolicy->addNgramEntry(&ngramContext,
&ngramProperty)) {
LogUtils::logToJava(env, "Cannot add ngram to the new dict.");
return false;
@@ -718,7 +720,8 @@ static const JNINativeMethod sMethods[] = {
{
const_cast<char *>("getWordPropertyNative"),
const_cast<char *>("(J[IZ[I[Z[ILjava/util/ArrayList;Ljava/util/ArrayList;"
- "Ljava/util/ArrayList;Ljava/util/ArrayList;)V"),
+ "Ljava/util/ArrayList;Ljava/util/ArrayList;Ljava/util/ArrayList;"
+ "Ljava/util/ArrayList;)V"),
reinterpret_cast<void *>(latinime_BinaryDictionary_getWordProperty)
},
{
@@ -747,9 +750,9 @@ static const JNINativeMethod sMethods[] = {
reinterpret_cast<void *>(latinime_BinaryDictionary_removeNgramEntry)
},
{
- const_cast<char *>("updateCounterNative"),
+ const_cast<char *>("updateEntriesForWordWithNgramContextNative"),
const_cast<char *>("(J[[I[Z[IZII)Z"),
- reinterpret_cast<void *>(latinime_BinaryDictionary_updateCounter)
+ reinterpret_cast<void *>(latinime_BinaryDictionary_updateEntriesForWordWithNgramContext)
},
{
const_cast<char *>("addMultipleDictionaryEntriesNative"),
diff --git a/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp b/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp
index 766064153..3c6bff3b6 100644
--- a/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp
+++ b/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp
@@ -22,7 +22,7 @@
#include "jni.h"
#include "jni_common.h"
#include "suggest/core/session/dic_traverse_session.h"
-#include "suggest/core/session/prev_words_info.h"
+#include "suggest/core/session/ngram_context.h"
namespace latinime {
class Dictionary;
@@ -40,14 +40,14 @@ static void latinime_initDicTraverseSession(JNIEnv *env, jclass clazz, jlong tra
}
Dictionary *dict = reinterpret_cast<Dictionary *>(dictionary);
if (!previousWord) {
- PrevWordsInfo prevWordsInfo;
- ts->init(dict, &prevWordsInfo, 0 /* suggestOptions */);
+ NgramContext emptyNgramContext;
+ ts->init(dict, &emptyNgramContext, 0 /* suggestOptions */);
return;
}
int prevWord[previousWordLength];
env->GetIntArrayRegion(previousWord, 0, previousWordLength, prevWord);
- PrevWordsInfo prevWordsInfo(prevWord, previousWordLength, false /* isStartOfSentence */);
- ts->init(dict, &prevWordsInfo, 0 /* suggestOptions */);
+ NgramContext ngramContext(prevWord, previousWordLength, false /* isStartOfSentence */);
+ ts->init(dict, &ngramContext, 0 /* suggestOptions */);
}
static void latinime_releaseDicTraverseSession(JNIEnv *env, jclass clazz, jlong traverseSession) {
diff --git a/native/jni/src/suggest/core/dictionary/dictionary.cpp b/native/jni/src/suggest/core/dictionary/dictionary.cpp
index 7a69d3ceb..697e99ffb 100644
--- a/native/jni/src/suggest/core/dictionary/dictionary.cpp
+++ b/native/jni/src/suggest/core/dictionary/dictionary.cpp
@@ -23,7 +23,7 @@
#include "suggest/core/policy/dictionary_header_structure_policy.h"
#include "suggest/core/result/suggestion_results.h"
#include "suggest/core/session/dic_traverse_session.h"
-#include "suggest/core/session/prev_words_info.h"
+#include "suggest/core/session/ngram_context.h"
#include "suggest/core/suggest.h"
#include "suggest/core/suggest_options.h"
#include "suggest/policyimpl/gesture/gesture_suggest_policy_factory.h"
@@ -46,11 +46,11 @@ Dictionary::Dictionary(JNIEnv *env, DictionaryStructureWithBufferPolicy::Structu
void Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession,
int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
- int inputSize, const PrevWordsInfo *const prevWordsInfo,
+ int inputSize, const NgramContext *const ngramContext,
const SuggestOptions *const suggestOptions, const float weightOfLangModelVsSpatialModel,
SuggestionResults *const outSuggestionResults) const {
TimeKeeper::setCurrentTime();
- traverseSession->init(this, prevWordsInfo, suggestOptions);
+ traverseSession->init(this, ngramContext, suggestOptions);
const auto &suggest = suggestOptions->isGesture() ? mGestureSuggest : mTypingSuggest;
suggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
ycoordinates, times, pointerIds, inputCodePoints, inputSize,
@@ -58,10 +58,10 @@ void Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession
}
Dictionary::NgramListenerForPrediction::NgramListenerForPrediction(
- const PrevWordsInfo *const prevWordsInfo, const WordIdArrayView prevWordIds,
+ const NgramContext *const ngramContext, const WordIdArrayView prevWordIds,
SuggestionResults *const suggestionResults,
const DictionaryStructureWithBufferPolicy *const dictStructurePolicy)
- : mPrevWordsInfo(prevWordsInfo), mPrevWordIds(prevWordIds),
+ : mNgramContext(ngramContext), mPrevWordIds(prevWordIds),
mSuggestionResults(suggestionResults), mDictStructurePolicy(dictStructurePolicy) {}
void Dictionary::NgramListenerForPrediction::onVisitEntry(const int ngramProbability,
@@ -69,7 +69,7 @@ void Dictionary::NgramListenerForPrediction::onVisitEntry(const int ngramProbabi
if (targetWordId == NOT_A_WORD_ID) {
return;
}
- if (mPrevWordsInfo->isNthPrevWordBeginningOfSentence(1 /* n */)
+ if (mNgramContext->isNthPrevWordBeginningOfSentence(1 /* n */)
&& ngramProbability == NOT_A_PROBABILITY) {
return;
}
@@ -85,20 +85,20 @@ void Dictionary::NgramListenerForPrediction::onVisitEntry(const int ngramProbabi
wordAttributes.getProbability());
}
-void Dictionary::getPredictions(const PrevWordsInfo *const prevWordsInfo,
+void Dictionary::getPredictions(const NgramContext *const ngramContext,
SuggestionResults *const outSuggestionResults) const {
TimeKeeper::setCurrentTime();
WordIdArray<MAX_PREV_WORD_COUNT_FOR_N_GRAM> prevWordIdArray;
- const WordIdArrayView prevWordIds = prevWordsInfo->getPrevWordIds(
+ const WordIdArrayView prevWordIds = ngramContext->getPrevWordIds(
mDictionaryStructureWithBufferPolicy.get(), &prevWordIdArray,
true /* tryLowerCaseSearch */);
- NgramListenerForPrediction listener(prevWordsInfo, prevWordIds, outSuggestionResults,
+ NgramListenerForPrediction listener(ngramContext, prevWordIds, outSuggestionResults,
mDictionaryStructureWithBufferPolicy.get());
mDictionaryStructureWithBufferPolicy->iterateNgramEntries(prevWordIds, &listener);
}
int Dictionary::getProbability(const CodePointArrayView codePoints) const {
- return getNgramProbability(nullptr /* prevWordsInfo */, codePoints);
+ return getNgramProbability(nullptr /* ngramContext */, codePoints);
}
int Dictionary::getMaxProbabilityOfExactMatches(const CodePointArrayView codePoints) const {
@@ -107,18 +107,18 @@ int Dictionary::getMaxProbabilityOfExactMatches(const CodePointArrayView codePoi
mDictionaryStructureWithBufferPolicy.get(), codePoints);
}
-int Dictionary::getNgramProbability(const PrevWordsInfo *const prevWordsInfo,
+int Dictionary::getNgramProbability(const NgramContext *const ngramContext,
const CodePointArrayView codePoints) const {
TimeKeeper::setCurrentTime();
const int wordId = mDictionaryStructureWithBufferPolicy->getWordId(codePoints,
false /* forceLowerCaseSearch */);
if (wordId == NOT_A_WORD_ID) return NOT_A_PROBABILITY;
- if (!prevWordsInfo) {
+ if (!ngramContext) {
return getDictionaryStructurePolicy()->getProbabilityOfWord(WordIdArrayView(), wordId);
}
WordIdArray<MAX_PREV_WORD_COUNT_FOR_N_GRAM> prevWordIdArray;
- const WordIdArrayView prevWordIds = prevWordsInfo->getPrevWordIds
- (mDictionaryStructureWithBufferPolicy.get(), &prevWordIdArray,
+ const WordIdArrayView prevWordIds = ngramContext->getPrevWordIds(
+ mDictionaryStructureWithBufferPolicy.get(), &prevWordIdArray,
true /* tryLowerCaseSearch */);
return getDictionaryStructurePolicy()->getProbabilityOfWord(prevWordIds, wordId);
}
@@ -140,24 +140,24 @@ bool Dictionary::removeUnigramEntry(const CodePointArrayView codePoints) {
return mDictionaryStructureWithBufferPolicy->removeUnigramEntry(codePoints);
}
-bool Dictionary::addNgramEntry(const PrevWordsInfo *const prevWordsInfo,
+bool Dictionary::addNgramEntry(const NgramContext *const ngramContext,
const NgramProperty *const ngramProperty) {
TimeKeeper::setCurrentTime();
- return mDictionaryStructureWithBufferPolicy->addNgramEntry(prevWordsInfo, ngramProperty);
+ return mDictionaryStructureWithBufferPolicy->addNgramEntry(ngramContext, ngramProperty);
}
-bool Dictionary::removeNgramEntry(const PrevWordsInfo *const prevWordsInfo,
+bool Dictionary::removeNgramEntry(const NgramContext *const ngramContext,
const CodePointArrayView codePoints) {
TimeKeeper::setCurrentTime();
- return mDictionaryStructureWithBufferPolicy->removeNgramEntry(prevWordsInfo, codePoints);
+ return mDictionaryStructureWithBufferPolicy->removeNgramEntry(ngramContext, codePoints);
}
-bool Dictionary::updateCounter(const PrevWordsInfo *const prevWordsInfo,
+bool Dictionary::updateEntriesForWordWithNgramContext(const NgramContext *const ngramContext,
const CodePointArrayView codePoints, const bool isValidWord,
const HistoricalInfo historicalInfo) {
TimeKeeper::setCurrentTime();
- return mDictionaryStructureWithBufferPolicy->updateCounter(prevWordsInfo, codePoints,
- isValidWord, historicalInfo);
+ return mDictionaryStructureWithBufferPolicy->updateEntriesForWordWithNgramContext(ngramContext,
+ codePoints, isValidWord, historicalInfo);
}
bool Dictionary::flush(const char *const filePath) {
diff --git a/native/jni/src/suggest/core/dictionary/dictionary.h b/native/jni/src/suggest/core/dictionary/dictionary.h
index a58dbfbd7..843aec473 100644
--- a/native/jni/src/suggest/core/dictionary/dictionary.h
+++ b/native/jni/src/suggest/core/dictionary/dictionary.h
@@ -33,7 +33,7 @@ namespace latinime {
class DictionaryStructureWithBufferPolicy;
class DicTraverseSession;
-class PrevWordsInfo;
+class NgramContext;
class ProximityInfo;
class SuggestionResults;
class SuggestOptions;
@@ -66,18 +66,18 @@ class Dictionary {
void getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession,
int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
- int inputSize, const PrevWordsInfo *const prevWordsInfo,
+ int inputSize, const NgramContext *const ngramContext,
const SuggestOptions *const suggestOptions, const float weightOfLangModelVsSpatialModel,
SuggestionResults *const outSuggestionResults) const;
- void getPredictions(const PrevWordsInfo *const prevWordsInfo,
+ void getPredictions(const NgramContext *const ngramContext,
SuggestionResults *const outSuggestionResults) const;
int getProbability(const CodePointArrayView codePoints) const;
int getMaxProbabilityOfExactMatches(const CodePointArrayView codePoints) const;
- int getNgramProbability(const PrevWordsInfo *const prevWordsInfo,
+ int getNgramProbability(const NgramContext *const ngramContext,
const CodePointArrayView codePoints) const;
bool addUnigramEntry(const CodePointArrayView codePoints,
@@ -85,13 +85,13 @@ class Dictionary {
bool removeUnigramEntry(const CodePointArrayView codePoints);
- bool addNgramEntry(const PrevWordsInfo *const prevWordsInfo,
+ bool addNgramEntry(const NgramContext *const ngramContext,
const NgramProperty *const ngramProperty);
- bool removeNgramEntry(const PrevWordsInfo *const prevWordsInfo,
+ bool removeNgramEntry(const NgramContext *const ngramContext,
const CodePointArrayView codePoints);
- bool updateCounter(const PrevWordsInfo *const prevWordsInfo,
+ bool updateEntriesForWordWithNgramContext(const NgramContext *const ngramContext,
const CodePointArrayView codePoints, const bool isValidWord,
const HistoricalInfo historicalInfo);
@@ -123,7 +123,7 @@ class Dictionary {
class NgramListenerForPrediction : public NgramListener {
public:
- NgramListenerForPrediction(const PrevWordsInfo *const prevWordsInfo,
+ NgramListenerForPrediction(const NgramContext *const ngramContext,
const WordIdArrayView prevWordIds, SuggestionResults *const suggestionResults,
const DictionaryStructureWithBufferPolicy *const dictStructurePolicy);
virtual void onVisitEntry(const int ngramProbability, const int targetWordId);
@@ -131,7 +131,7 @@ class Dictionary {
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(NgramListenerForPrediction);
- const PrevWordsInfo *const mPrevWordsInfo;
+ const NgramContext *const mNgramContext;
const WordIdArrayView mPrevWordIds;
SuggestionResults *const mSuggestionResults;
const DictionaryStructureWithBufferPolicy *const mDictStructurePolicy;
diff --git a/native/jni/src/suggest/core/dictionary/dictionary_utils.cpp b/native/jni/src/suggest/core/dictionary/dictionary_utils.cpp
index b85f3622a..9573c37bc 100644
--- a/native/jni/src/suggest/core/dictionary/dictionary_utils.cpp
+++ b/native/jni/src/suggest/core/dictionary/dictionary_utils.cpp
@@ -21,7 +21,7 @@
#include "suggest/core/dicnode/dic_node_vector.h"
#include "suggest/core/dictionary/dictionary.h"
#include "suggest/core/dictionary/digraph_utils.h"
-#include "suggest/core/session/prev_words_info.h"
+#include "suggest/core/session/ngram_context.h"
#include "suggest/core/policy/dictionary_structure_with_buffer_policy.h"
#include "utils/int_array_view.h"
@@ -33,10 +33,10 @@ namespace latinime {
std::vector<DicNode> current;
std::vector<DicNode> next;
- // No prev words information.
- PrevWordsInfo emptyPrevWordsInfo;
+ // No ngram context.
+ NgramContext emptyNgramContext;
WordIdArray<MAX_PREV_WORD_COUNT_FOR_N_GRAM> prevWordIdArray;
- const WordIdArrayView prevWordIds = emptyPrevWordsInfo.getPrevWordIds(
+ const WordIdArrayView prevWordIds = emptyNgramContext.getPrevWordIds(
dictionaryStructurePolicy, &prevWordIdArray, false /* tryLowerCaseSearch */);
current.emplace_back();
DicNodeUtils::initAsRoot(dictionaryStructurePolicy, prevWordIds, &current.front());
diff --git a/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h b/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h
index 6624b7921..ceda5c03f 100644
--- a/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h
+++ b/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h
@@ -33,7 +33,7 @@ class DicNodeVector;
class DictionaryHeaderStructurePolicy;
class MultiBigramMap;
class NgramListener;
-class PrevWordsInfo;
+class NgramContext;
class UnigramProperty;
/*
@@ -81,15 +81,15 @@ class DictionaryStructureWithBufferPolicy {
virtual bool removeUnigramEntry(const CodePointArrayView wordCodePoints) = 0;
// Returns whether the update was success or not.
- virtual bool addNgramEntry(const PrevWordsInfo *const prevWordsInfo,
+ virtual bool addNgramEntry(const NgramContext *const ngramContext,
const NgramProperty *const ngramProperty) = 0;
// Returns whether the update was success or not.
- virtual bool removeNgramEntry(const PrevWordsInfo *const prevWordsInfo,
+ virtual bool removeNgramEntry(const NgramContext *const ngramContext,
const CodePointArrayView wordCodePoints) = 0;
// Returns whether the update was success or not.
- virtual bool updateCounter(const PrevWordsInfo *const prevWordsInfo,
+ virtual bool updateEntriesForWordWithNgramContext(const NgramContext *const ngramContext,
const CodePointArrayView wordCodePoints, const bool isValidWord,
const HistoricalInfo historicalInfo) = 0;
diff --git a/native/jni/src/suggest/core/session/dic_traverse_session.cpp b/native/jni/src/suggest/core/session/dic_traverse_session.cpp
index b4d01d0f0..52dc2f86c 100644
--- a/native/jni/src/suggest/core/session/dic_traverse_session.cpp
+++ b/native/jni/src/suggest/core/session/dic_traverse_session.cpp
@@ -20,7 +20,7 @@
#include "suggest/core/dictionary/dictionary.h"
#include "suggest/core/policy/dictionary_header_structure_policy.h"
#include "suggest/core/policy/dictionary_structure_with_buffer_policy.h"
-#include "suggest/core/session/prev_words_info.h"
+#include "suggest/core/session/ngram_context.h"
namespace latinime {
@@ -30,12 +30,12 @@ const int DicTraverseSession::DICTIONARY_SIZE_THRESHOLD_TO_USE_LARGE_CACHE_FOR_S
256 * 1024;
void DicTraverseSession::init(const Dictionary *const dictionary,
- const PrevWordsInfo *const prevWordsInfo, const SuggestOptions *const suggestOptions) {
+ const NgramContext *const ngramContext, const SuggestOptions *const suggestOptions) {
mDictionary = dictionary;
mMultiWordCostMultiplier = getDictionaryStructurePolicy()->getHeaderStructurePolicy()
->getMultiWordCostMultiplier();
mSuggestOptions = suggestOptions;
- mPrevWordIdCount = prevWordsInfo->getPrevWordIds(getDictionaryStructurePolicy(),
+ mPrevWordIdCount = ngramContext->getPrevWordIds(getDictionaryStructurePolicy(),
&mPrevWordIdArray, true /* tryLowerCaseSearch */).size();
}
diff --git a/native/jni/src/suggest/core/session/dic_traverse_session.h b/native/jni/src/suggest/core/session/dic_traverse_session.h
index 9f841aa3c..bc53167f0 100644
--- a/native/jni/src/suggest/core/session/dic_traverse_session.h
+++ b/native/jni/src/suggest/core/session/dic_traverse_session.h
@@ -30,7 +30,7 @@ namespace latinime {
class Dictionary;
class DictionaryStructureWithBufferPolicy;
-class PrevWordsInfo;
+class NgramContext;
class ProximityInfo;
class SuggestOptions;
@@ -61,7 +61,7 @@ class DicTraverseSession {
// Non virtual inline destructor -- never inherit this class
AK_FORCE_INLINE ~DicTraverseSession() {}
- void init(const Dictionary *dictionary, const PrevWordsInfo *const prevWordsInfo,
+ void init(const Dictionary *dictionary, const NgramContext *const ngramContext,
const SuggestOptions *const suggestOptions);
// TODO: Remove and merge into init
void setupForGetSuggestions(const ProximityInfo *pInfo, const int *inputCodePoints,
diff --git a/native/jni/src/suggest/core/session/prev_words_info.h b/native/jni/src/suggest/core/session/ngram_context.h
index 553d5ad07..64c71410f 100644
--- a/native/jni/src/suggest/core/session/prev_words_info.h
+++ b/native/jni/src/suggest/core/session/ngram_context.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef LATINIME_PREV_WORDS_INFO_H
-#define LATINIME_PREV_WORDS_INFO_H
+#ifndef LATINIME_NGRAM_CONTEXT_H
+#define LATINIME_NGRAM_CONTEXT_H
#include <array>
@@ -26,25 +26,26 @@
namespace latinime {
-class PrevWordsInfo {
+// Rename to NgramContext.
+class NgramContext {
public:
// No prev word information.
- PrevWordsInfo() : mPrevWordCount(0) {
+ NgramContext() : mPrevWordCount(0) {
clear();
}
- PrevWordsInfo(const PrevWordsInfo &prevWordsInfo)
- : mPrevWordCount(prevWordsInfo.mPrevWordCount) {
+ NgramContext(const NgramContext &ngramContext)
+ : mPrevWordCount(ngramContext.mPrevWordCount) {
for (size_t i = 0; i < mPrevWordCount; ++i) {
- mPrevWordCodePointCount[i] = prevWordsInfo.mPrevWordCodePointCount[i];
- memmove(mPrevWordCodePoints[i], prevWordsInfo.mPrevWordCodePoints[i],
+ mPrevWordCodePointCount[i] = ngramContext.mPrevWordCodePointCount[i];
+ memmove(mPrevWordCodePoints[i], ngramContext.mPrevWordCodePoints[i],
sizeof(mPrevWordCodePoints[i][0]) * mPrevWordCodePointCount[i]);
- mIsBeginningOfSentence[i] = prevWordsInfo.mIsBeginningOfSentence[i];
+ mIsBeginningOfSentence[i] = ngramContext.mIsBeginningOfSentence[i];
}
}
// Construct from previous words.
- PrevWordsInfo(const int prevWordCodePoints[][MAX_WORD_LENGTH],
+ NgramContext(const int prevWordCodePoints[][MAX_WORD_LENGTH],
const int *const prevWordCodePointCount, const bool *const isBeginningOfSentence,
const size_t prevWordCount)
: mPrevWordCount(std::min(NELEMS(mPrevWordCodePoints), prevWordCount)) {
@@ -61,7 +62,7 @@ class PrevWordsInfo {
}
// Construct from a previous word.
- PrevWordsInfo(const int *const prevWordCodePoints, const int prevWordCodePointCount,
+ NgramContext(const int *const prevWordCodePoints, const int prevWordCodePointCount,
const bool isBeginningOfSentence) : mPrevWordCount(1) {
clear();
if (prevWordCodePointCount > MAX_WORD_LENGTH || !prevWordCodePoints) {
@@ -78,8 +79,8 @@ class PrevWordsInfo {
}
// TODO: Remove.
- const PrevWordsInfo getTrimmedPrevWordsInfo(const size_t maxPrevWordCount) const {
- return PrevWordsInfo(mPrevWordCodePoints, mPrevWordCodePointCount, mIsBeginningOfSentence,
+ const NgramContext getTrimmedNgramContext(const size_t maxPrevWordCount) const {
+ return NgramContext(mPrevWordCodePoints, mPrevWordCodePointCount, mIsBeginningOfSentence,
std::min(mPrevWordCount, maxPrevWordCount));
}
@@ -122,7 +123,7 @@ class PrevWordsInfo {
}
private:
- DISALLOW_ASSIGNMENT_OPERATOR(PrevWordsInfo);
+ DISALLOW_ASSIGNMENT_OPERATOR(NgramContext);
static int getWordId(const DictionaryStructureWithBufferPolicy *const dictStructurePolicy,
const int *const wordCodePoints, const int wordCodePointCount,
@@ -165,4 +166,4 @@ class PrevWordsInfo {
bool mIsBeginningOfSentence[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
};
} // namespace latinime
-#endif // LATINIME_PREV_WORDS_INFO_H
+#endif // LATINIME_NGRAM_CONTEXT_H
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.cpp
index 8d169743c..6243f14cc 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.cpp
@@ -310,7 +310,7 @@ bool Ver4PatriciaTrieNodeWriter::addShortcutTarget(const PtNodeParams *const ptN
const int shortcutProbability) {
if (!mShortcutPolicy->addNewShortcut(ptNodeParams->getTerminalId(),
targetCodePoints, targetCodePointCount, shortcutProbability)) {
- AKLOGE("Cannot add new shortuct entry. terminalId: %d", ptNodeParams->getTerminalId());
+ AKLOGE("Cannot add new shortcut entry. terminalId: %d", ptNodeParams->getTerminalId());
return false;
}
if (!ptNodeParams->hasShortcutTargets()) {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp
index 36eafa1e9..1c61bd4b9 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp
@@ -33,7 +33,7 @@
#include "suggest/core/dictionary/property/ngram_property.h"
#include "suggest/core/dictionary/property/unigram_property.h"
#include "suggest/core/dictionary/property/word_property.h"
-#include "suggest/core/session/prev_words_info.h"
+#include "suggest/core/session/ngram_context.h"
#include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_reading_helper.h"
#include "suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_reader.h"
#include "suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h"
@@ -338,7 +338,7 @@ bool Ver4PatriciaTriePolicy::removeUnigramEntry(const CodePointArrayView wordCod
return mNodeWriter.suppressUnigramEntry(&ptNodeParams);
}
-bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsInfo,
+bool Ver4PatriciaTriePolicy::addNgramEntry(const NgramContext *const ngramContext,
const NgramProperty *const ngramProperty) {
if (!mBuffers->isUpdatable()) {
AKLOGI("Warning: addNgramEntry() is called for non-updatable dictionary.");
@@ -349,8 +349,8 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI
mDictBuffer->getTailPosition());
return false;
}
- if (!prevWordsInfo->isValid()) {
- AKLOGE("prev words info is not valid for adding n-gram entry to the dictionary.");
+ if (!ngramContext->isValid()) {
+ AKLOGE("Ngram context is not valid for adding n-gram entry to the dictionary.");
return false;
}
if (ngramProperty->getTargetCodePoints()->size() > MAX_WORD_LENGTH) {
@@ -359,23 +359,23 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI
return false;
}
WordIdArray<MAX_PREV_WORD_COUNT_FOR_N_GRAM> prevWordIdArray;
- const WordIdArrayView prevWordIds = prevWordsInfo->getPrevWordIds(this, &prevWordIdArray,
+ const WordIdArrayView prevWordIds = ngramContext->getPrevWordIds(this, &prevWordIdArray,
false /* tryLowerCaseSearch */);
if (prevWordIds.empty()) {
return false;
}
if (prevWordIds[0] == NOT_A_WORD_ID) {
- if (prevWordsInfo->isNthPrevWordBeginningOfSentence(1 /* n */)) {
+ if (ngramContext->isNthPrevWordBeginningOfSentence(1 /* n */)) {
const UnigramProperty beginningOfSentenceUnigramProperty(
true /* representsBeginningOfSentence */, true /* isNotAWord */,
false /* isBlacklisted */, MAX_PROBABILITY /* probability */, HistoricalInfo());
- if (!addUnigramEntry(prevWordsInfo->getNthPrevWordCodePoints(1 /* n */),
+ if (!addUnigramEntry(ngramContext->getNthPrevWordCodePoints(1 /* n */),
&beginningOfSentenceUnigramProperty)) {
AKLOGE("Cannot add unigram entry for the beginning-of-sentence.");
return false;
}
// Refresh word ids.
- prevWordsInfo->getPrevWordIds(this, &prevWordIdArray, false /* tryLowerCaseSearch */);
+ ngramContext->getPrevWordIds(this, &prevWordIdArray, false /* tryLowerCaseSearch */);
} else {
return false;
}
@@ -399,7 +399,7 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI
}
}
-bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWordsInfo,
+bool Ver4PatriciaTriePolicy::removeNgramEntry(const NgramContext *const ngramContext,
const CodePointArrayView wordCodePoints) {
if (!mBuffers->isUpdatable()) {
AKLOGI("Warning: removeNgramEntry() is called for non-updatable dictionary.");
@@ -410,8 +410,8 @@ bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWor
mDictBuffer->getTailPosition());
return false;
}
- if (!prevWordsInfo->isValid()) {
- AKLOGE("prev words info is not valid for removing n-gram entry form the dictionary.");
+ if (!ngramContext->isValid()) {
+ AKLOGE("Ngram context is not valid for removing n-gram entry form the dictionary.");
return false;
}
if (wordCodePoints.size() > MAX_WORD_LENGTH) {
@@ -419,7 +419,7 @@ bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWor
wordCodePoints.size());
}
WordIdArray<MAX_PREV_WORD_COUNT_FOR_N_GRAM> prevWordIdArray;
- const WordIdArrayView prevWordIds = prevWordsInfo->getPrevWordIds(this, &prevWordIdArray,
+ const WordIdArrayView prevWordIds = ngramContext->getPrevWordIds(this, &prevWordIdArray,
false /* tryLowerCaseSerch */);
if (prevWordIds.firstOrDefault(NOT_A_WORD_ID) == NOT_A_WORD_ID) {
return false;
@@ -440,26 +440,27 @@ bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWor
}
-bool Ver4PatriciaTriePolicy::updateCounter(const PrevWordsInfo *const prevWordsInfo,
- const CodePointArrayView wordCodePoints, const bool isValidWord,
- const HistoricalInfo historicalInfo) {
+bool Ver4PatriciaTriePolicy::updateEntriesForWordWithNgramContext(
+ const NgramContext *const ngramContext, const CodePointArrayView wordCodePoints,
+ const bool isValidWord, const HistoricalInfo historicalInfo) {
if (!mBuffers->isUpdatable()) {
- AKLOGI("Warning: updateCounter() is called for non-updatable dictionary.");
+ AKLOGI("Warning: updateEntriesForWordWithNgramContext() is called for non-updatable "
+ "dictionary.");
return false;
}
const int probability = isValidWord ? DUMMY_PROBABILITY_FOR_VALID_WORDS : NOT_A_PROBABILITY;
const UnigramProperty unigramProperty(false /* representsBeginningOfSentence */,
false /* isNotAWord */, false /*isBlacklisted*/, probability, historicalInfo);
if (!addUnigramEntry(wordCodePoints, &unigramProperty)) {
- AKLOGE("Cannot update unigarm entry in updateCounter().");
+ AKLOGE("Cannot update unigarm entry in updateEntriesForWordWithNgramContext().");
return false;
}
- const int probabilityForNgram = prevWordsInfo->isNthPrevWordBeginningOfSentence(1 /* n */)
+ const int probabilityForNgram = ngramContext->isNthPrevWordBeginningOfSentence(1 /* n */)
? NOT_A_PROBABILITY : probability;
const NgramProperty ngramProperty(wordCodePoints.toVector(), probabilityForNgram,
historicalInfo);
- if (!addNgramEntry(prevWordsInfo, &ngramProperty)) {
- AKLOGE("Cannot update unigarm entry in updateCounter().");
+ if (!addNgramEntry(ngramContext, &ngramProperty)) {
+ AKLOGE("Cannot update unigarm entry in updateEntriesForWordWithNgramContext().");
return false;
}
return true;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h
index b82563e61..4aa399c3e 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h
@@ -112,13 +112,13 @@ class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
bool removeUnigramEntry(const CodePointArrayView wordCodePoints);
- bool addNgramEntry(const PrevWordsInfo *const prevWordsInfo,
+ bool addNgramEntry(const NgramContext *const ngramContext,
const NgramProperty *const ngramProperty);
- bool removeNgramEntry(const PrevWordsInfo *const prevWordsInfo,
+ bool removeNgramEntry(const NgramContext *const ngramContext,
const CodePointArrayView wordCodePoints);
- bool updateCounter(const PrevWordsInfo *const prevWordsInfo,
+ bool updateEntriesForWordWithNgramContext(const NgramContext *const ngramContext,
const CodePointArrayView wordCodePoints, const bool isValidWord,
const HistoricalInfo historicalInfo);
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp
index d3d684bfa..b7f1199c5 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp
@@ -23,7 +23,7 @@
#include "suggest/core/dictionary/binary_dictionary_bigrams_iterator.h"
#include "suggest/core/dictionary/multi_bigram_map.h"
#include "suggest/core/dictionary/ngram_listener.h"
-#include "suggest/core/session/prev_words_info.h"
+#include "suggest/core/session/ngram_context.h"
#include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_reading_helper.h"
#include "suggest/policyimpl/dictionary/structure/pt_common/patricia_trie_reading_utils.h"
#include "suggest/policyimpl/dictionary/utils/probability_utils.h"
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h
index 32a95bb6c..b17681388 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h
@@ -93,25 +93,26 @@ class PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
return false;
}
- bool addNgramEntry(const PrevWordsInfo *const prevWordsInfo,
+ bool addNgramEntry(const NgramContext *const ngramContext,
const NgramProperty *const ngramProperty) {
// This method should not be called for non-updatable dictionary.
AKLOGI("Warning: addNgramEntry() is called for non-updatable dictionary.");
return false;
}
- bool removeNgramEntry(const PrevWordsInfo *const prevWordsInfo,
+ bool removeNgramEntry(const NgramContext *const ngramContext,
const CodePointArrayView wordCodePoints) {
// This method should not be called for non-updatable dictionary.
AKLOGI("Warning: removeNgramEntry() is called for non-updatable dictionary.");
return false;
}
- bool updateCounter(const PrevWordsInfo *const prevWordsInfo,
+ bool updateEntriesForWordWithNgramContext(const NgramContext *const ngramContext,
const CodePointArrayView wordCodePoints, const bool isValidWord,
const HistoricalInfo historicalInfo) {
// This method should not be called for non-updatable dictionary.
- AKLOGI("Warning: updateCounter() is called for non-updatable dictionary.");
+ AKLOGI("Warning: updateEntriesForWordWithNgramContext() is called for non-updatable "
+ "dictionary.");
return false;
}
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_patricia_trie_node_reader.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_patricia_trie_node_reader.cpp
index dc0ed96d0..90d4687dd 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_patricia_trie_node_reader.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_patricia_trie_node_reader.cpp
@@ -37,7 +37,7 @@ const PtNodeParams Ver2ParticiaTrieNodeReader::fetchPtNodeParamsInBufferFromPtNo
int shortcutPos = NOT_A_DICT_POS;
int bigramPos = NOT_A_DICT_POS;
int siblingPos = NOT_A_DICT_POS;
- PatriciaTrieReadingUtils::readPtNodeInfo(mBuffer.data(), ptNodePos, mShortuctPolicy,
+ PatriciaTrieReadingUtils::readPtNodeInfo(mBuffer.data(), ptNodePos, mShortcutPolicy,
mBigramPolicy, mCodePointTable, &flags, &mergedNodeCodePointCount, mergedNodeCodePoints,
&probability, &childrenPos, &shortcutPos, &bigramPos, &siblingPos);
if (mergedNodeCodePointCount <= 0) {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_patricia_trie_node_reader.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_patricia_trie_node_reader.h
index 24ec5bcca..838d37314 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_patricia_trie_node_reader.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/ver2_patricia_trie_node_reader.h
@@ -35,7 +35,7 @@ class Ver2ParticiaTrieNodeReader : public PtNodeReader {
const DictionaryBigramsStructurePolicy *const bigramPolicy,
const DictionaryShortcutsStructurePolicy *const shortcutPolicy,
const int *const codePointTable)
- : mBuffer(buffer), mBigramPolicy(bigramPolicy), mShortuctPolicy(shortcutPolicy),
+ : mBuffer(buffer), mBigramPolicy(bigramPolicy), mShortcutPolicy(shortcutPolicy),
mCodePointTable(codePointTable) {}
virtual const PtNodeParams fetchPtNodeParamsInBufferFromPtNodePos(const int ptNodePos) const;
@@ -45,7 +45,7 @@ class Ver2ParticiaTrieNodeReader : public PtNodeReader {
const ReadOnlyByteArrayView mBuffer;
const DictionaryBigramsStructurePolicy *const mBigramPolicy;
- const DictionaryShortcutsStructurePolicy *const mShortuctPolicy;
+ const DictionaryShortcutsStructurePolicy *const mShortcutPolicy;
const int *const mCodePointTable;
};
} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp
index f13512d5a..d28006ae9 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp
@@ -285,7 +285,7 @@ bool Ver4PatriciaTrieNodeWriter::addShortcutTarget(const PtNodeParams *const ptN
const int shortcutProbability) {
if (!mShortcutPolicy->addNewShortcut(ptNodeParams->getTerminalId(),
targetCodePoints, targetCodePointCount, shortcutProbability)) {
- AKLOGE("Cannot add new shortuct entry. terminalId: %d", ptNodeParams->getTerminalId());
+ AKLOGE("Cannot add new shortcut entry. terminalId: %d", ptNodeParams->getTerminalId());
return false;
}
return true;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp
index 036197c41..445bbe07e 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp
@@ -26,7 +26,7 @@
#include "suggest/core/dictionary/property/ngram_property.h"
#include "suggest/core/dictionary/property/unigram_property.h"
#include "suggest/core/dictionary/property/word_property.h"
-#include "suggest/core/session/prev_words_info.h"
+#include "suggest/core/session/ngram_context.h"
#include "suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_reading_helper.h"
#include "suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.h"
#include "suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h"
@@ -266,7 +266,7 @@ bool Ver4PatriciaTriePolicy::removeUnigramEntry(const CodePointArrayView wordCod
return true;
}
-bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsInfo,
+bool Ver4PatriciaTriePolicy::addNgramEntry(const NgramContext *const ngramContext,
const NgramProperty *const ngramProperty) {
if (!mBuffers->isUpdatable()) {
AKLOGI("Warning: addNgramEntry() is called for non-updatable dictionary.");
@@ -277,8 +277,8 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI
mDictBuffer->getTailPosition());
return false;
}
- if (!prevWordsInfo->isValid()) {
- AKLOGE("prev words info is not valid for adding n-gram entry to the dictionary.");
+ if (!ngramContext->isValid()) {
+ AKLOGE("Ngram context is not valid for adding n-gram entry to the dictionary.");
return false;
}
if (ngramProperty->getTargetCodePoints()->size() > MAX_WORD_LENGTH) {
@@ -287,7 +287,7 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI
return false;
}
WordIdArray<MAX_PREV_WORD_COUNT_FOR_N_GRAM> prevWordIdArray;
- const WordIdArrayView prevWordIds = prevWordsInfo->getPrevWordIds(this, &prevWordIdArray,
+ const WordIdArrayView prevWordIds = ngramContext->getPrevWordIds(this, &prevWordIdArray,
false /* tryLowerCaseSearch */);
if (prevWordIds.empty()) {
return false;
@@ -296,19 +296,19 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI
if (prevWordIds[i] != NOT_A_WORD_ID) {
continue;
}
- if (!prevWordsInfo->isNthPrevWordBeginningOfSentence(i + 1 /* n */)) {
+ if (!ngramContext->isNthPrevWordBeginningOfSentence(i + 1 /* n */)) {
return false;
}
const UnigramProperty beginningOfSentenceUnigramProperty(
true /* representsBeginningOfSentence */, true /* isNotAWord */,
false /* isBlacklisted */, MAX_PROBABILITY /* probability */, HistoricalInfo());
- if (!addUnigramEntry(prevWordsInfo->getNthPrevWordCodePoints(1 /* n */),
+ if (!addUnigramEntry(ngramContext->getNthPrevWordCodePoints(1 /* n */),
&beginningOfSentenceUnigramProperty)) {
AKLOGE("Cannot add unigram entry for the beginning-of-sentence.");
return false;
}
// Refresh word ids.
- prevWordsInfo->getPrevWordIds(this, &prevWordIdArray, false /* tryLowerCaseSearch */);
+ ngramContext->getPrevWordIds(this, &prevWordIdArray, false /* tryLowerCaseSearch */);
}
const int wordId = getWordId(CodePointArrayView(*ngramProperty->getTargetCodePoints()),
false /* forceLowerCaseSearch */);
@@ -326,7 +326,7 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI
}
}
-bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWordsInfo,
+bool Ver4PatriciaTriePolicy::removeNgramEntry(const NgramContext *const ngramContext,
const CodePointArrayView wordCodePoints) {
if (!mBuffers->isUpdatable()) {
AKLOGI("Warning: removeNgramEntry() is called for non-updatable dictionary.");
@@ -337,8 +337,8 @@ bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWor
mDictBuffer->getTailPosition());
return false;
}
- if (!prevWordsInfo->isValid()) {
- AKLOGE("prev words info is not valid for removing n-gram entry form the dictionary.");
+ if (!ngramContext->isValid()) {
+ AKLOGE("Ngram context is not valid for removing n-gram entry form the dictionary.");
return false;
}
if (wordCodePoints.size() > MAX_WORD_LENGTH) {
@@ -346,7 +346,7 @@ bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWor
wordCodePoints.size());
}
WordIdArray<MAX_PREV_WORD_COUNT_FOR_N_GRAM> prevWordIdArray;
- const WordIdArrayView prevWordIds = prevWordsInfo->getPrevWordIds(this, &prevWordIdArray,
+ const WordIdArrayView prevWordIds = ngramContext->getPrevWordIds(this, &prevWordIdArray,
false /* tryLowerCaseSerch */);
if (prevWordIds.empty() || prevWordIds.contains(NOT_A_WORD_ID)) {
return false;
@@ -363,29 +363,30 @@ bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWor
}
}
-bool Ver4PatriciaTriePolicy::updateCounter(const PrevWordsInfo *const prevWordsInfo,
- const CodePointArrayView wordCodePoints, const bool isValidWord,
- const HistoricalInfo historicalInfo) {
+bool Ver4PatriciaTriePolicy::updateEntriesForWordWithNgramContext(
+ const NgramContext *const ngramContext, const CodePointArrayView wordCodePoints,
+ const bool isValidWord, const HistoricalInfo historicalInfo) {
if (!mBuffers->isUpdatable()) {
- AKLOGI("Warning: updateCounter() is called for non-updatable dictionary.");
+ AKLOGI("Warning: updateEntriesForWordWithNgramContext() is called for non-updatable "
+ "dictionary.");
return false;
}
// TODO: Have count up method in language model dict content.
const int probability = isValidWord ? DUMMY_PROBABILITY_FOR_VALID_WORDS : NOT_A_PROBABILITY;
const UnigramProperty unigramProperty(false /* representsBeginningOfSentence */,
- false /* isNotAWord */, false /*isBlacklisted*/, probability, historicalInfo);
+ false /* isNotAWord */, false /* isBlacklisted */, probability, historicalInfo);
if (!addUnigramEntry(wordCodePoints, &unigramProperty)) {
- AKLOGE("Cannot update unigarm entry in updateCounter().");
+ AKLOGE("Cannot update unigarm entry in updateEntriesForWordWithNgramContext().");
return false;
}
- const int probabilityForNgram = prevWordsInfo->isNthPrevWordBeginningOfSentence(1 /* n */)
+ const int probabilityForNgram = ngramContext->isNthPrevWordBeginningOfSentence(1 /* n */)
? NOT_A_PROBABILITY : probability;
const NgramProperty ngramProperty(wordCodePoints.toVector(), probabilityForNgram,
historicalInfo);
- for (size_t i = 1; i <= prevWordsInfo->getPrevWordCount(); ++i) {
- const PrevWordsInfo trimmedPrevWordsInfo(prevWordsInfo->getTrimmedPrevWordsInfo(i));
- if (!addNgramEntry(&trimmedPrevWordsInfo, &ngramProperty)) {
- AKLOGE("Cannot update ngram entry in updateCounter().");
+ for (size_t i = 1; i <= ngramContext->getPrevWordCount(); ++i) {
+ const NgramContext trimmedNgramContext(ngramContext->getTrimmedNgramContext(i));
+ if (!addNgramEntry(&trimmedNgramContext, &ngramProperty)) {
+ AKLOGE("Cannot update ngram entry in updateEntriesForWordWithNgramContext().");
return false;
}
}
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h
index 662bb8d4b..60e30f209 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h
@@ -92,13 +92,13 @@ class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
bool removeUnigramEntry(const CodePointArrayView wordCodePoints);
- bool addNgramEntry(const PrevWordsInfo *const prevWordsInfo,
+ bool addNgramEntry(const NgramContext *const ngramContext,
const NgramProperty *const ngramProperty);
- bool removeNgramEntry(const PrevWordsInfo *const prevWordsInfo,
+ bool removeNgramEntry(const NgramContext *const ngramContext,
const CodePointArrayView wordCodePoints);
- bool updateCounter(const PrevWordsInfo *const prevWordsInfo,
+ bool updateEntriesForWordWithNgramContext(const NgramContext *const ngramContext,
const CodePointArrayView wordCodePoints, const bool isValidWord,
const HistoricalInfo historicalInfo);
diff --git a/native/jni/src/utils/jni_data_utils.h b/native/jni/src/utils/jni_data_utils.h
index 235a03bba..25cc41742 100644
--- a/native/jni/src/utils/jni_data_utils.h
+++ b/native/jni/src/utils/jni_data_utils.h
@@ -21,7 +21,7 @@
#include "defines.h"
#include "jni.h"
-#include "suggest/core/session/prev_words_info.h"
+#include "suggest/core/session/ngram_context.h"
#include "suggest/core/policy/dictionary_header_structure_policy.h"
#include "suggest/policyimpl/dictionary/header/header_read_write_utils.h"
#include "utils/char_utils.h"
@@ -96,7 +96,7 @@ class JniDataUtils {
}
}
- static PrevWordsInfo constructPrevWordsInfo(JNIEnv *env, jobjectArray prevWordCodePointArrays,
+ static NgramContext constructNgramContext(JNIEnv *env, jobjectArray prevWordCodePointArrays,
jbooleanArray isBeginningOfSentenceArray, const size_t prevWordCount) {
int prevWordCodePoints[MAX_PREV_WORD_COUNT_FOR_N_GRAM][MAX_WORD_LENGTH];
int prevWordCodePointCount[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
@@ -119,7 +119,7 @@ class JniDataUtils {
&isBeginningOfSentenceBoolean);
isBeginningOfSentence[i] = isBeginningOfSentenceBoolean == JNI_TRUE;
}
- return PrevWordsInfo(prevWordCodePoints, prevWordCodePointCount, isBeginningOfSentence,
+ return NgramContext(prevWordCodePoints, prevWordCodePointCount, isBeginningOfSentence,
prevWordCount);
}
diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
index 6860bea45..ee7942450 100644
--- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
@@ -39,6 +39,8 @@ import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils;
import com.android.inputmethod.event.Event;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.latin.Dictionary;
+import com.android.inputmethod.latin.Dictionary.PhonyDictionary;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.settings.DebugSettings;
import com.android.inputmethod.latin.settings.Settings;
@@ -61,6 +63,10 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
protected static final int DELAY_TO_WAIT_FOR_PREDICTIONS = 200;
private final int TIMEOUT_TO_WAIT_FOR_LOADING_MAIN_DICTIONARY_IN_SECONDS = 60;
+ // Type for a test phony dictionary
+ private static final String TYPE_TEST = "test";
+ private static final PhonyDictionary DICTIONARY_TEST = new PhonyDictionary(TYPE_TEST);
+
protected LatinIME mLatinIME;
protected Keyboard mKeyboard;
protected MyEditText mEditText;
@@ -353,7 +359,7 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
protected void pickSuggestionManually(final String suggestion) {
mLatinIME.pickSuggestionManually(new SuggestedWordInfo(suggestion, 1,
- SuggestedWordInfo.KIND_CORRECTION, null /* sourceDict */,
+ SuggestedWordInfo.KIND_CORRECTION, DICTIONARY_TEST,
SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */));
}
diff --git a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
index 563261f8f..221541e4a 100644
--- a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
+++ b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
@@ -59,40 +59,6 @@ public class SuggestedWordsTests extends AndroidTestCase {
SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */);
}
- public void testGetSuggestedWordsExcludingTypedWord() {
- final String TYPED_WORD = "typed";
- final int NUMBER_OF_ADDED_SUGGESTIONS = 5;
- final int KIND_OF_SECOND_CORRECTION = SuggestedWordInfo.KIND_CORRECTION;
- final ArrayList<SuggestedWordInfo> list = new ArrayList<>();
- list.add(createTypedWordInfo(TYPED_WORD));
- for (int i = 0; i < NUMBER_OF_ADDED_SUGGESTIONS; ++i) {
- list.add(createCorrectionWordInfo(Integer.toString(i)));
- }
-
- final SuggestedWords words = new SuggestedWords(
- list, null /* rawSuggestions */,
- false /* typedWordValid */,
- false /* willAutoCorrect */,
- false /* isObsoleteSuggestions */,
- SuggestedWords.INPUT_STYLE_NONE);
- assertEquals(NUMBER_OF_ADDED_SUGGESTIONS + 1, words.size());
- assertEquals("typed", words.getWord(0));
- assertTrue(words.getInfo(0).isKindOf(SuggestedWordInfo.KIND_TYPED));
- assertEquals("0", words.getWord(1));
- assertTrue(words.getInfo(1).isKindOf(KIND_OF_SECOND_CORRECTION));
- assertEquals("4", words.getWord(5));
- assertTrue(words.getInfo(5).isKindOf(KIND_OF_SECOND_CORRECTION));
-
- final SuggestedWords wordsWithoutTyped =
- words.getSuggestedWordsExcludingTypedWordForRecorrection();
- // Make sure that the typed word has indeed been excluded, by testing the size of the
- // suggested words, the string and the kind of the top suggestion, which should match
- // the string and kind of what we inserted after the typed word.
- assertEquals(words.size() - 1, wordsWithoutTyped.size());
- assertEquals("0", wordsWithoutTyped.getWord(0));
- assertTrue(wordsWithoutTyped.getInfo(0).isKindOf(KIND_OF_SECOND_CORRECTION));
- }
-
// Helper for testGetTransformedWordInfo
private SuggestedWordInfo transformWordInfo(final String info,
final int trailingSingleQuotesCount) {
@@ -141,9 +107,14 @@ public class SuggestedWordsTests extends AndroidTestCase {
assertNotNull(typedWord);
assertEquals(TYPED_WORD, typedWord.mWord);
- // Make sure getTypedWordInfoOrNull() returns null.
- final SuggestedWords wordsWithoutTypedWord =
- wordsWithTypedWord.getSuggestedWordsExcludingTypedWordForRecorrection();
+ // Make sure getTypedWordInfoOrNull() returns null when no typed word.
+ list.remove(0);
+ final SuggestedWords wordsWithoutTypedWord = new SuggestedWords(
+ list, null /* rawSuggestions */,
+ false /* typedWordValid */,
+ false /* willAutoCorrect */,
+ false /* isObsoleteSuggestions */,
+ SuggestedWords.INPUT_STYLE_NONE);
assertNull(wordsWithoutTypedWord.getTypedWordInfoOrNull());
// Make sure getTypedWordInfoOrNull() returns null.