aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/src/com/android/inputmethod/latin/common/CodePointUtils.java20
-rw-r--r--common/src/com/android/inputmethod/latin/common/ComposedData.java66
-rw-r--r--common/src/com/android/inputmethod/latin/common/Constants.java6
-rw-r--r--common/src/com/android/inputmethod/latin/common/InputPointers.java22
-rw-r--r--common/src/com/android/inputmethod/latin/common/ResizableIntArray.java10
-rw-r--r--dictionaries/de_wordlist.combined.gzbin1292666 -> 1293426 bytes
-rw-r--r--dictionaries/en_GB_wordlist.combined.gzbin860708 -> 865437 bytes
-rw-r--r--dictionaries/en_US_wordlist.combined.gzbin877710 -> 883015 bytes
-rw-r--r--dictionaries/en_wordlist.combined.gzbin909096 -> 914050 bytes
-rw-r--r--dictionaries/es_wordlist.combined.gzbin1164983 -> 1165885 bytes
-rw-r--r--dictionaries/fr_wordlist.combined.gzbin1106371 -> 1108423 bytes
-rw-r--r--dictionaries/it_wordlist.combined.gzbin933697 -> 935024 bytes
-rw-r--r--dictionaries/nl_wordlist.combined.gzbin1053242 -> 1054497 bytes
-rw-r--r--dictionaries/pl_wordlist.combined.gzbin1089296 -> 1090690 bytes
-rw-r--r--dictionaries/pt_BR_wordlist.combined.gzbin878505 -> 879877 bytes
-rw-r--r--dictionaries/pt_PT_wordlist.combined.gzbin1105959 -> 1106730 bytes
-rw-r--r--dictionaries/ru_wordlist.combined.gzbin1394944 -> 1397626 bytes
-rw-r--r--dictionaries/sv_wordlist.combined.gzbin1139281 -> 1140879 bytes
-rw-r--r--dictionaries/tr_wordlist.combined.gzbin925948 -> 926338 bytes
-rw-r--r--java/res/raw/main_de.dictbin1606096 -> 1606096 bytes
-rw-r--r--java/res/raw/main_en.dictbin1070485 -> 1070485 bytes
-rw-r--r--java/res/raw/main_es.dictbin1377071 -> 1377071 bytes
-rw-r--r--java/res/raw/main_fr.dictbin1328940 -> 1328933 bytes
-rw-r--r--java/res/raw/main_it.dictbin1143338 -> 1143338 bytes
-rw-r--r--java/res/raw/main_pt_br.dictbin1092054 -> 1092054 bytes
-rw-r--r--java/res/raw/main_ru.dictbin1292026 -> 1292026 bytes
-rw-r--r--java/res/values-af/strings.xml3
-rw-r--r--java/res/values-ar/strings.xml3
-rw-r--r--java/res/values-az-rAZ/strings.xml3
-rw-r--r--java/res/values-bg/strings.xml3
-rw-r--r--java/res/values-bn-rBD/strings-emoji-descriptions.xml2
-rw-r--r--java/res/values-bn-rBD/strings.xml3
-rw-r--r--java/res/values-ca/strings.xml3
-rw-r--r--java/res/values-da/strings.xml3
-rw-r--r--java/res/values-en-rGB/strings.xml3
-rw-r--r--java/res/values-en-rIN/strings.xml3
-rw-r--r--java/res/values-es-rUS/strings.xml3
-rw-r--r--java/res/values-eu-rES/strings.xml3
-rw-r--r--java/res/values-fa/strings.xml3
-rw-r--r--java/res/values-fi/strings-emoji-descriptions.xml2
-rw-r--r--java/res/values-fi/strings.xml3
-rw-r--r--java/res/values-fr-rCA/strings.xml3
-rw-r--r--java/res/values-fr/strings-emoji-descriptions.xml2
-rw-r--r--java/res/values-fr/strings.xml3
-rw-r--r--java/res/values-gl-rES/strings-emoji-descriptions.xml2
-rw-r--r--java/res/values-gl-rES/strings.xml3
-rw-r--r--java/res/values-hi/strings-emoji-descriptions.xml2
-rw-r--r--java/res/values-hi/strings.xml3
-rw-r--r--java/res/values-hr/strings.xml3
-rw-r--r--java/res/values-hy-rAM/strings.xml3
-rw-r--r--java/res/values-is-rIS/strings.xml3
-rw-r--r--java/res/values-ja/strings.xml3
-rw-r--r--java/res/values-ka-rGE/strings.xml3
-rw-r--r--java/res/values-kk-rKZ/strings.xml3
-rw-r--r--java/res/values-ko/strings.xml3
-rw-r--r--java/res/values-ky-rKG/strings.xml3
-rw-r--r--java/res/values-lo-rLA/strings-emoji-descriptions.xml2
-rw-r--r--java/res/values-lo-rLA/strings.xml3
-rw-r--r--java/res/values-lt/strings-emoji-descriptions.xml2
-rw-r--r--java/res/values-lv/strings-emoji-descriptions.xml2
-rw-r--r--java/res/values-lv/strings.xml3
-rw-r--r--java/res/values-ml-rIN/strings-emoji-descriptions.xml2
-rw-r--r--java/res/values-ml-rIN/strings.xml3
-rw-r--r--java/res/values-mr-rIN/strings.xml3
-rw-r--r--java/res/values-ms-rMY/strings.xml3
-rw-r--r--java/res/values-my-rMM/strings.xml3
-rw-r--r--java/res/values-ne-rNP/strings-emoji-descriptions.xml2
-rw-r--r--java/res/values-ne-rNP/strings.xml3
-rw-r--r--java/res/values-nl/strings-emoji-descriptions.xml2
-rw-r--r--java/res/values-ro/strings.xml3
-rw-r--r--java/res/values-ru/strings.xml3
-rw-r--r--java/res/values-si-rLK/strings.xml3
-rw-r--r--java/res/values-sk/strings.xml3
-rw-r--r--java/res/values-sl/strings.xml3
-rw-r--r--java/res/values-sr/strings.xml3
-rw-r--r--java/res/values-sv/strings-emoji-descriptions.xml2
-rw-r--r--java/res/values-sw/strings.xml3
-rw-r--r--java/res/values-ta-rIN/strings.xml3
-rw-r--r--java/res/values-te-rIN/strings.xml3
-rw-r--r--java/res/values-th/strings-emoji-descriptions.xml2
-rw-r--r--java/res/values-th/strings.xml3
-rw-r--r--java/res/values-tl/strings.xml3
-rw-r--r--java/res/values-tr/strings.xml3
-rw-r--r--java/res/values-uk/strings.xml3
-rw-r--r--java/res/values-ur-rPK/strings-emoji-descriptions.xml2
-rw-r--r--java/res/values-ur-rPK/strings.xml3
-rw-r--r--java/res/values-uz-rUZ/strings.xml3
-rw-r--r--java/res/values-vi/strings.xml3
-rw-r--r--java/res/values-zh-rCN/strings.xml3
-rw-r--r--java/res/values-zh-rHK/strings.xml3
-rw-r--r--java/res/values-zh-rTW/strings-emoji-descriptions.xml2
-rw-r--r--java/res/values-zh-rTW/strings.xml3
-rw-r--r--java/res/values/donottranslate-debug-settings.xml4
-rw-r--r--java/res/xml/prefs_screen_debug.xml11
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java47
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java152
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java17
-rw-r--r--java/src/com/android/inputmethod/latin/Dictionary.java14
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryCollection.java16
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitator.java7
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java15
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java6
-rw-r--r--java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java12
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java8
-rw-r--r--java/src/com/android/inputmethod/latin/WordComposer.java37
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FormatSpec.java14
-rw-r--r--java/src/com/android/inputmethod/latin/settings/DebugSettings.java2
-rw-r--r--java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java49
-rw-r--r--java/src/com/android/inputmethod/latin/settings/LocalSettingsConstants.java2
-rw-r--r--java/src/com/android/inputmethod/latin/settings/Settings.java6
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsValues.java6
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java3
-rw-r--r--java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java28
-rw-r--r--java/src/com/android/inputmethod/latin/utils/CollectionUtils.java13
-rw-r--r--java/src/com/android/inputmethod/latin/utils/CombinedFormatUtils.java13
-rw-r--r--java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java5
-rw-r--r--java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java11
-rw-r--r--java/src/com/android/inputmethod/latin/utils/ResourceUtils.java10
-rw-r--r--native/dicttoolkit/Android.mk67
-rw-r--r--native/dicttoolkit/CleanupNativeFileList.mk17
-rw-r--r--native/dicttoolkit/NativeFileList.mk21
-rw-r--r--native/dicttoolkit/UnitTests.mk68
-rw-r--r--native/dicttoolkit/dict_toolkit_main.cpp23
-rwxr-xr-xnative/dicttoolkit/run_tests.sh34
-rw-r--r--native/dicttoolkit/src/dict_toolkit_defines.h22
-rw-r--r--native/dicttoolkit/tests/dict_toolkit_defines_test.cpp32
-rw-r--r--native/jni/NativeFileList.mk3
-rw-r--r--native/jni/src/suggest/core/dictionary/dictionary.cpp3
-rw-r--r--native/jni/src/suggest/core/dictionary/error_type_utils.cpp1
-rw-r--r--native/jni/src/suggest/core/dictionary/error_type_utils.h5
-rw-r--r--native/jni/src/suggest/core/dictionary/ngram_listener.h2
-rw-r--r--native/jni/src/suggest/core/dictionary/property/historical_info.h1
-rw-r--r--native/jni/src/suggest/core/policy/scoring.h2
-rw-r--r--native/jni/src/suggest/core/result/suggestions_output_utils.cpp66
-rw-r--r--native/jni/src/suggest/core/result/suggestions_output_utils.h9
-rw-r--r--native/jni/src/suggest/core/suggest.cpp5
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h16
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.cpp7
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/content/bigram_dict_content.cpp2
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/content/probability_dict_content.cpp3
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp4
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.cpp18
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h11
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.cpp12
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/dynamic_language_model_probability_utils.cpp37
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/dynamic_language_model_probability_utils.h114
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp127
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h26
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_global_counters.h4
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/probability_entry.h2
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.cpp4
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h1
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp65
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.cpp4
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.cpp14
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.h8
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/probability_utils.cpp23
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/probability_utils.h15
-rw-r--r--native/jni/src/suggest/policyimpl/typing/scoring_params.cpp1
-rw-r--r--native/jni/src/suggest/policyimpl/typing/scoring_params.h1
-rw-r--r--native/jni/src/suggest/policyimpl/typing/typing_scoring.h47
-rw-r--r--native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_test.cpp8
-rw-r--r--native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/probability_entry_test.cpp8
-rw-r--r--native/jni/tests/suggest/policyimpl/dictionary/utils/format_utils_test.cpp8
-rw-r--r--native/jni/tests/suggest/policyimpl/dictionary/utils/probability_utils_test.cpp33
-rw-r--r--tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java83
-rw-r--r--tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java119
-rw-r--r--tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java28
-rw-r--r--tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java16
-rw-r--r--tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java15
-rw-r--r--tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java3
-rw-r--r--tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java3
-rw-r--r--tests/src/com/android/inputmethod/latin/utils/CollectionUtilsTests.java33
-rw-r--r--tools/dicttool/Android.mk4
-rw-r--r--tools/dicttool/compat/com/android/inputmethod/event/CombinerChain.java54
-rw-r--r--tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java51
-rw-r--r--tools/dicttool/src/com/android/inputmethod/latin/dicttool/CommandList.java1
-rw-r--r--tools/dicttool/src/com/android/inputmethod/latin/dicttool/DictionaryMaker.java2
179 files changed, 1520 insertions, 713 deletions
diff --git a/common/src/com/android/inputmethod/latin/common/CodePointUtils.java b/common/src/com/android/inputmethod/latin/common/CodePointUtils.java
index 592da5c1f..ec59de850 100644
--- a/common/src/com/android/inputmethod/latin/common/CodePointUtils.java
+++ b/common/src/com/android/inputmethod/latin/common/CodePointUtils.java
@@ -20,6 +20,8 @@ import com.android.inputmethod.annotations.UsedForTesting;
import java.util.Random;
+import javax.annotation.Nonnull;
+
// Utility methods related with code points used for tests.
// TODO: Figure out where this class should be.
@UsedForTesting
@@ -65,17 +67,23 @@ public class CodePointUtils {
};
@UsedForTesting
- public static int[] generateCodePointSet(final int codePointSetSize, final Random random) {
+ @Nonnull
+ public static int[] generateCodePointSet(final int codePointSetSize,
+ @Nonnull final Random random) {
final int[] codePointSet = new int[codePointSetSize];
for (int i = codePointSet.length - 1; i >= 0; ) {
final int r = Math.abs(random.nextInt());
- if (r < 0) continue;
+ if (r < 0) {
+ continue;
+ }
// Don't insert 0~0x20, but insert any other code point.
// Code points are in the range 0~0x10FFFF.
final int candidateCodePoint = 0x20 + r % (Character.MAX_CODE_POINT - 0x20);
// Code points between MIN_ and MAX_SURROGATE are not valid on their own.
if (candidateCodePoint >= Character.MIN_SURROGATE
- && candidateCodePoint <= Character.MAX_SURROGATE) continue;
+ && candidateCodePoint <= Character.MAX_SURROGATE) {
+ continue;
+ }
codePointSet[i] = candidateCodePoint;
--i;
}
@@ -86,8 +94,10 @@ public class CodePointUtils {
* Generates a random word.
*/
@UsedForTesting
- public static String generateWord(final Random random, final int[] codePointSet) {
- StringBuilder builder = new StringBuilder();
+ @Nonnull
+ public static String generateWord(@Nonnull final Random random,
+ @Nonnull final int[] codePointSet) {
+ final StringBuilder builder = new StringBuilder();
// 8 * 4 = 32 chars max, but we do it the following way so as to bias the random toward
// longer words. This should be closer to natural language, and more importantly, it will
// exercise the algorithms in dicttool much more.
diff --git a/common/src/com/android/inputmethod/latin/common/ComposedData.java b/common/src/com/android/inputmethod/latin/common/ComposedData.java
new file mode 100644
index 000000000..7f0966050
--- /dev/null
+++ b/common/src/com/android/inputmethod/latin/common/ComposedData.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.common;
+
+import javax.annotation.Nonnull;
+
+/**
+ * An immutable class that encapsulates a snapshot of word composition data.
+ */
+public class ComposedData {
+ @Nonnull
+ public final InputPointers mInputPointers;
+ public final boolean mIsBatchMode;
+ @Nonnull
+ public final String mTypedWord;
+
+ public ComposedData(@Nonnull final InputPointers inputPointers, final boolean isBatchMode,
+ @Nonnull final String typedWord) {
+ mInputPointers = inputPointers;
+ mIsBatchMode = isBatchMode;
+ mTypedWord = typedWord;
+ }
+
+ /**
+ * Copy the code points in the typed word to a destination array of ints.
+ *
+ * If the array is too small to hold the code points in the typed word, nothing is copied and
+ * -1 is returned.
+ *
+ * @param destination the array of ints.
+ * @return the number of copied code points.
+ */
+ public int copyCodePointsExceptTrailingSingleQuotesAndReturnCodePointCount(
+ @Nonnull final int[] destination) {
+ // lastIndex is exclusive
+ final int lastIndex = mTypedWord.length()
+ - StringUtils.getTrailingSingleQuotesCount(mTypedWord);
+ if (lastIndex <= 0) {
+ // The string is empty or contains only single quotes.
+ return 0;
+ }
+
+ // The following function counts the number of code points in the text range which begins
+ // at index 0 and extends to the character at lastIndex.
+ final int codePointSize = Character.codePointCount(mTypedWord, 0, lastIndex);
+ if (codePointSize > destination.length) {
+ return -1;
+ }
+ return StringUtils.copyCodePointsAndReturnCodePointCount(destination, mTypedWord, 0,
+ lastIndex, true /* downCase */);
+ }
+}
diff --git a/common/src/com/android/inputmethod/latin/common/Constants.java b/common/src/com/android/inputmethod/latin/common/Constants.java
index 8f4a1e50d..abc377a84 100644
--- a/common/src/com/android/inputmethod/latin/common/Constants.java
+++ b/common/src/com/android/inputmethod/latin/common/Constants.java
@@ -18,6 +18,8 @@ package com.android.inputmethod.latin.common;
import com.android.inputmethod.annotations.UsedForTesting;
+import javax.annotation.Nonnull;
+
public final class Constants {
public static final class Color {
/**
@@ -259,6 +261,7 @@ public final class Constants {
return code >= CODE_SPACE;
}
+ @Nonnull
public static String printableCode(final int code) {
switch (code) {
case CODE_SHIFT: return "shift";
@@ -286,7 +289,8 @@ public final class Constants {
}
}
- public static String printableCodes(final int[] codes) {
+ @Nonnull
+ public static String printableCodes(@Nonnull final int[] codes) {
final StringBuilder sb = new StringBuilder();
boolean addDelimiter = false;
for (final int code : codes) {
diff --git a/common/src/com/android/inputmethod/latin/common/InputPointers.java b/common/src/com/android/inputmethod/latin/common/InputPointers.java
index 40131aca4..7beee1536 100644
--- a/common/src/com/android/inputmethod/latin/common/InputPointers.java
+++ b/common/src/com/android/inputmethod/latin/common/InputPointers.java
@@ -18,6 +18,8 @@ package com.android.inputmethod.latin.common;
import com.android.inputmethod.annotations.UsedForTesting;
+import javax.annotation.Nonnull;
+
// TODO: This class is not thread-safe.
public final class InputPointers {
private static final boolean DEBUG_TIME = false;
@@ -28,7 +30,7 @@ public final class InputPointers {
private final ResizableIntArray mPointerIds;
private final ResizableIntArray mTimes;
- public InputPointers(int defaultCapacity) {
+ public InputPointers(final int defaultCapacity) {
mDefaultCapacity = defaultCapacity;
mXCoordinates = new ResizableIntArray(defaultCapacity);
mYCoordinates = new ResizableIntArray(defaultCapacity);
@@ -51,7 +53,8 @@ public final class InputPointers {
mTimes.fill(lastTime, fromIndex, fillLength);
}
- public void addPointerAt(int index, int x, int y, int pointerId, int time) {
+ public void addPointerAt(final int index, final int x, final int y, final int pointerId,
+ final int time) {
mXCoordinates.addAt(index, x);
mYCoordinates.addAt(index, y);
mPointerIds.addAt(index, pointerId);
@@ -62,21 +65,21 @@ public final class InputPointers {
}
@UsedForTesting
- public void addPointer(int x, int y, int pointerId, int time) {
+ public void addPointer(final int x, final int y, final int pointerId, final int time) {
mXCoordinates.add(x);
mYCoordinates.add(y);
mPointerIds.add(pointerId);
mTimes.add(time);
}
- public void set(InputPointers ip) {
+ public void set(@Nonnull final InputPointers ip) {
mXCoordinates.set(ip.mXCoordinates);
mYCoordinates.set(ip.mYCoordinates);
mPointerIds.set(ip.mPointerIds);
mTimes.set(ip.mTimes);
}
- public void copy(InputPointers ip) {
+ public void copy(@Nonnull final InputPointers ip) {
mXCoordinates.copy(ip.mXCoordinates);
mYCoordinates.copy(ip.mYCoordinates);
mPointerIds.copy(ip.mPointerIds);
@@ -93,8 +96,9 @@ public final class InputPointers {
* @param startPos the starting index of the data in {@code times} and etc.
* @param length the number of data to be appended.
*/
- public void append(int pointerId, ResizableIntArray times, ResizableIntArray xCoordinates,
- ResizableIntArray yCoordinates, int startPos, int length) {
+ public void append(final int pointerId, @Nonnull final ResizableIntArray times,
+ @Nonnull final ResizableIntArray xCoordinates,
+ @Nonnull final ResizableIntArray yCoordinates, final int startPos, final int length) {
if (length == 0) {
return;
}
@@ -127,14 +131,17 @@ public final class InputPointers {
return mXCoordinates.getLength();
}
+ @Nonnull
public int[] getXCoordinates() {
return mXCoordinates.getPrimitiveArray();
}
+ @Nonnull
public int[] getYCoordinates() {
return mYCoordinates.getPrimitiveArray();
}
+ @Nonnull
public int[] getPointerIds() {
return mPointerIds.getPrimitiveArray();
}
@@ -145,6 +152,7 @@ public final class InputPointers {
* @return The time each point was registered, in milliseconds, relative to the first event in
* the sequence.
*/
+ @Nonnull
public int[] getTimes() {
return mTimes.getPrimitiveArray();
}
diff --git a/common/src/com/android/inputmethod/latin/common/ResizableIntArray.java b/common/src/com/android/inputmethod/latin/common/ResizableIntArray.java
index ea23d8a33..340abb23e 100644
--- a/common/src/com/android/inputmethod/latin/common/ResizableIntArray.java
+++ b/common/src/com/android/inputmethod/latin/common/ResizableIntArray.java
@@ -18,8 +18,11 @@ package com.android.inputmethod.latin.common;
import java.util.Arrays;
+import javax.annotation.Nonnull;
+
// TODO: This class is not thread-safe.
public final class ResizableIntArray {
+ @Nonnull
private int[] mArray;
private int mLength;
@@ -89,17 +92,18 @@ public final class ResizableIntArray {
mLength = 0;
}
+ @Nonnull
public int[] getPrimitiveArray() {
return mArray;
}
- public void set(final ResizableIntArray ip) {
+ public void set(@Nonnull final ResizableIntArray ip) {
// TODO: Implement primitive array pool.
mArray = ip.mArray;
mLength = ip.mLength;
}
- public void copy(final ResizableIntArray ip) {
+ public void copy(@Nonnull final ResizableIntArray ip) {
final int newCapacity = calculateCapacity(ip.mLength);
if (newCapacity > 0) {
// TODO: Implement primitive array pool.
@@ -109,7 +113,7 @@ public final class ResizableIntArray {
mLength = ip.mLength;
}
- public void append(final ResizableIntArray src, final int startPos, final int length) {
+ public void append(@Nonnull final ResizableIntArray src, final int startPos, final int length) {
if (length == 0) {
return;
}
diff --git a/dictionaries/de_wordlist.combined.gz b/dictionaries/de_wordlist.combined.gz
index 803211c01..92c95540c 100644
--- a/dictionaries/de_wordlist.combined.gz
+++ b/dictionaries/de_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/en_GB_wordlist.combined.gz b/dictionaries/en_GB_wordlist.combined.gz
index 1fa9b85ea..217660fc4 100644
--- a/dictionaries/en_GB_wordlist.combined.gz
+++ b/dictionaries/en_GB_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/en_US_wordlist.combined.gz b/dictionaries/en_US_wordlist.combined.gz
index 2e039ff05..8aed9c5e0 100644
--- a/dictionaries/en_US_wordlist.combined.gz
+++ b/dictionaries/en_US_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/en_wordlist.combined.gz b/dictionaries/en_wordlist.combined.gz
index e845346d6..7fe6618cf 100644
--- a/dictionaries/en_wordlist.combined.gz
+++ b/dictionaries/en_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/es_wordlist.combined.gz b/dictionaries/es_wordlist.combined.gz
index 3391e64b4..71e7309fc 100644
--- a/dictionaries/es_wordlist.combined.gz
+++ b/dictionaries/es_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/fr_wordlist.combined.gz b/dictionaries/fr_wordlist.combined.gz
index 1b9fd73f9..afe44a6d9 100644
--- a/dictionaries/fr_wordlist.combined.gz
+++ b/dictionaries/fr_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/it_wordlist.combined.gz b/dictionaries/it_wordlist.combined.gz
index 5a5cbdc7a..ed58a12c5 100644
--- a/dictionaries/it_wordlist.combined.gz
+++ b/dictionaries/it_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/nl_wordlist.combined.gz b/dictionaries/nl_wordlist.combined.gz
index 37ba8ab42..19c3a7ea8 100644
--- a/dictionaries/nl_wordlist.combined.gz
+++ b/dictionaries/nl_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/pl_wordlist.combined.gz b/dictionaries/pl_wordlist.combined.gz
index ba71a5581..2b84eecfd 100644
--- a/dictionaries/pl_wordlist.combined.gz
+++ b/dictionaries/pl_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/pt_BR_wordlist.combined.gz b/dictionaries/pt_BR_wordlist.combined.gz
index 02df1c1ee..7aac61e50 100644
--- a/dictionaries/pt_BR_wordlist.combined.gz
+++ b/dictionaries/pt_BR_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/pt_PT_wordlist.combined.gz b/dictionaries/pt_PT_wordlist.combined.gz
index bcd50ab03..5bf9a60e8 100644
--- a/dictionaries/pt_PT_wordlist.combined.gz
+++ b/dictionaries/pt_PT_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/ru_wordlist.combined.gz b/dictionaries/ru_wordlist.combined.gz
index 401ad08b0..5e9266221 100644
--- a/dictionaries/ru_wordlist.combined.gz
+++ b/dictionaries/ru_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/sv_wordlist.combined.gz b/dictionaries/sv_wordlist.combined.gz
index b6ebab320..db44ae4c4 100644
--- a/dictionaries/sv_wordlist.combined.gz
+++ b/dictionaries/sv_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/tr_wordlist.combined.gz b/dictionaries/tr_wordlist.combined.gz
index 306cea184..d3c8825b9 100644
--- a/dictionaries/tr_wordlist.combined.gz
+++ b/dictionaries/tr_wordlist.combined.gz
Binary files differ
diff --git a/java/res/raw/main_de.dict b/java/res/raw/main_de.dict
index 45b288375..c3c2cbe46 100644
--- a/java/res/raw/main_de.dict
+++ b/java/res/raw/main_de.dict
Binary files differ
diff --git a/java/res/raw/main_en.dict b/java/res/raw/main_en.dict
index 5bbb85761..b9e5bc77b 100644
--- a/java/res/raw/main_en.dict
+++ b/java/res/raw/main_en.dict
Binary files differ
diff --git a/java/res/raw/main_es.dict b/java/res/raw/main_es.dict
index fae131850..076d5aa8f 100644
--- a/java/res/raw/main_es.dict
+++ b/java/res/raw/main_es.dict
Binary files differ
diff --git a/java/res/raw/main_fr.dict b/java/res/raw/main_fr.dict
index 19532d9bf..0e8686092 100644
--- a/java/res/raw/main_fr.dict
+++ b/java/res/raw/main_fr.dict
Binary files differ
diff --git a/java/res/raw/main_it.dict b/java/res/raw/main_it.dict
index ff11b9798..609ef13b7 100644
--- a/java/res/raw/main_it.dict
+++ b/java/res/raw/main_it.dict
Binary files differ
diff --git a/java/res/raw/main_pt_br.dict b/java/res/raw/main_pt_br.dict
index 9fa50442a..c33865187 100644
--- a/java/res/raw/main_pt_br.dict
+++ b/java/res/raw/main_pt_br.dict
Binary files differ
diff --git a/java/res/raw/main_ru.dict b/java/res/raw/main_ru.dict
index 76b5f805a..d0af70730 100644
--- a/java/res/raw/main_ru.dict
+++ b/java/res/raw/main_ru.dict
Binary files differ
diff --git a/java/res/values-af/strings.xml b/java/res/values-af/strings.xml
index ca8b816f4..f8be8f1d3 100644
--- a/java/res/values-af/strings.xml
+++ b/java/res/values-af/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Serwies (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Tradisioneel)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Kompak)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Geen taal nie (alfabet)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml
index 62d5f3dbd..da414a66d 100644
--- a/java/res/values-ar/strings.xml
+++ b/java/res/values-ar/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"هنجليزية (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"الصربية (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (التقليدية)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (مكثفة)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"بدون لغة (أبجدية)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"‏الأبجدية (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"‏الأبجدية (QWERTZ)"</string>
diff --git a/java/res/values-az-rAZ/strings.xml b/java/res/values-az-rAZ/strings.xml
index b13c90536..b1a192ce5 100644
--- a/java/res/values-az-rAZ/strings.xml
+++ b/java/res/values-az-rAZ/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hingilis (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Serb (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Ənənəvi)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Kompakt)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Dil yoxdur (Əlifba)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Əlifba (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Əlifba (QWERTZ)"</string>
diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml
index 805014b05..5d7e6b4b1 100644
--- a/java/res/values-bg/strings.xml
+++ b/java/res/values-bg/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Хинглиш (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Сръбска (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (традиционна клавиатура)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (компактна)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Без език (латиница)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Латиница (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Латиница (QWERTZ)"</string>
diff --git a/java/res/values-bn-rBD/strings-emoji-descriptions.xml b/java/res/values-bn-rBD/strings-emoji-descriptions.xml
index 3c58621f4..4c661661d 100644
--- a/java/res/values-bn-rBD/strings-emoji-descriptions.xml
+++ b/java/res/values-bn-rBD/strings-emoji-descriptions.xml
@@ -267,7 +267,7 @@
<string name="spoken_emoji_1F36A" msgid="2726271795913042295">"কুকি"</string>
<string name="spoken_emoji_1F36B" msgid="6342163604299875931">"চকোলেট বার"</string>
<string name="spoken_emoji_1F36C" msgid="2168934753998218790">"ক্যান্ডি"</string>
- <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"ললিপপ"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lollipop"</string>
<string name="spoken_emoji_1F36E" msgid="4630541402785165902">"কাস্টার্ড"</string>
<string name="spoken_emoji_1F36F" msgid="5577915387425169439">"মধুর পাত্র"</string>
<string name="spoken_emoji_1F370" msgid="7243244547866114951">"শর্টকেক"</string>
diff --git a/java/res/values-bn-rBD/strings.xml b/java/res/values-bn-rBD/strings.xml
index 5487bb5f2..8d77be4ea 100644
--- a/java/res/values-bn-rBD/strings.xml
+++ b/java/res/values-bn-rBD/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"হিংলিশ (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"সার্বিয়ান (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ঐতিহ্যবাহি)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (কম্প্যাক্ট)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"কোনো ভাষা নয় (বর্ণমালা)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"বর্ণমালা (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"বর্ণমালা (QWERTZ)"</string>
diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml
index ef792b8d0..3f0e447f9 100644
--- a/java/res/values-ca/strings.xml
+++ b/java/res/values-ca/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Serbi (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (compacte)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Cap idioma (alfabet)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml
index 0e92e4711..39c51e9ea 100644
--- a/java/res/values-da/strings.xml
+++ b/java/res/values-da/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Serbisk (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionelt)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (kompakt)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Intet sprog (Alfabet)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
diff --git a/java/res/values-en-rGB/strings.xml b/java/res/values-en-rGB/strings.xml
index 3ed282651..1778cded3 100644
--- a/java/res/values-en-rGB/strings.xml
+++ b/java/res/values-en-rGB/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Serbian (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Traditional)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Compact)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"No language (Alphabet)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alphabet (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alphabet (QWERTZ)"</string>
diff --git a/java/res/values-en-rIN/strings.xml b/java/res/values-en-rIN/strings.xml
index 3ed282651..1778cded3 100644
--- a/java/res/values-en-rIN/strings.xml
+++ b/java/res/values-en-rIN/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Serbian (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Traditional)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Compact)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"No language (Alphabet)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alphabet (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alphabet (QWERTZ)"</string>
diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml
index 8142b1d0b..7b9e3ba66 100644
--- a/java/res/values-es-rUS/strings.xml
+++ b/java/res/values-es-rUS/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Serbio (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (compacto)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Ningún idioma (alfabeto)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabeto (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabeto (QWERTZ)"</string>
diff --git a/java/res/values-eu-rES/strings.xml b/java/res/values-eu-rES/strings.xml
index 9496d95e9..23d15930c 100644
--- a/java/res/values-eu-rES/strings.xml
+++ b/java/res/values-eu-rES/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglisha (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Serbiarra (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradizionala)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (trinkoa)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Ez dago hizkuntzarik (alfabetoa)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabetoa (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabetoa (QWERTZ)"</string>
diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml
index a0390dfdb..2461da5af 100644
--- a/java/res/values-fa/strings.xml
+++ b/java/res/values-fa/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"هندی انگلیسی (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"صربی (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (سنتی)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (فشرده)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"بدون زبان (حروف الفبا)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"‏حروف الفبا (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"‏حروف الفبا (QWERTZ)"</string>
diff --git a/java/res/values-fi/strings-emoji-descriptions.xml b/java/res/values-fi/strings-emoji-descriptions.xml
index ad08bbda2..72af3c229 100644
--- a/java/res/values-fi/strings-emoji-descriptions.xml
+++ b/java/res/values-fi/strings-emoji-descriptions.xml
@@ -267,7 +267,7 @@
<string name="spoken_emoji_1F36A" msgid="2726271795913042295">"Pikkuleipä"</string>
<string name="spoken_emoji_1F36B" msgid="6342163604299875931">"Suklaapatukka"</string>
<string name="spoken_emoji_1F36C" msgid="2168934753998218790">"Karamelli"</string>
- <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Tikkukaramelli"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lollipop"</string>
<string name="spoken_emoji_1F36E" msgid="4630541402785165902">"Vanukas"</string>
<string name="spoken_emoji_1F36F" msgid="5577915387425169439">"Hunajapurkki"</string>
<string name="spoken_emoji_1F370" msgid="7243244547866114951">"Kakkuviipale"</string>
diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml
index b133cc9d9..0308d18d7 100644
--- a/java/res/values-fi/strings.xml
+++ b/java/res/values-fi/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hindienglanti (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"serbialainen (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (perinteinen)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tiivis)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Ei kieltä (aakkoset)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Aakkoset (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Aakkoset (QWERTZ)"</string>
diff --git a/java/res/values-fr-rCA/strings.xml b/java/res/values-fr-rCA/strings.xml
index ee522059c..6730a7982 100644
--- a/java/res/values-fr-rCA/strings.xml
+++ b/java/res/values-fr-rCA/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Serbe (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionnel)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (compact)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Aucune langue (alphabet)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alphabet latin (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alphabet latin (QWERTZ)"</string>
diff --git a/java/res/values-fr/strings-emoji-descriptions.xml b/java/res/values-fr/strings-emoji-descriptions.xml
index 1f99ee3bc..b7ad706fc 100644
--- a/java/res/values-fr/strings-emoji-descriptions.xml
+++ b/java/res/values-fr/strings-emoji-descriptions.xml
@@ -267,7 +267,7 @@
<string name="spoken_emoji_1F36A" msgid="2726271795913042295">"Biscuit"</string>
<string name="spoken_emoji_1F36B" msgid="6342163604299875931">"Barre de chocolat"</string>
<string name="spoken_emoji_1F36C" msgid="2168934753998218790">"Bonbon"</string>
- <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Sucette"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lollipop"</string>
<string name="spoken_emoji_1F36E" msgid="4630541402785165902">"Crème anglaise"</string>
<string name="spoken_emoji_1F36F" msgid="5577915387425169439">"Pot de miel"</string>
<string name="spoken_emoji_1F370" msgid="7243244547866114951">"Sablé"</string>
diff --git a/java/res/values-fr/strings.xml b/java/res/values-fr/strings.xml
index 2a93c992d..3349f4a6a 100644
--- a/java/res/values-fr/strings.xml
+++ b/java/res/values-fr/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hindi/Anglais (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Serbe (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (traditionnel)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Compact)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Aucune langue (latin)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alphabet latin (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alphabet latin (QWERTZ)"</string>
diff --git a/java/res/values-gl-rES/strings-emoji-descriptions.xml b/java/res/values-gl-rES/strings-emoji-descriptions.xml
index cdb67fa45..31eb89bb2 100644
--- a/java/res/values-gl-rES/strings-emoji-descriptions.xml
+++ b/java/res/values-gl-rES/strings-emoji-descriptions.xml
@@ -267,7 +267,7 @@
<string name="spoken_emoji_1F36A" msgid="2726271795913042295">"Galleta"</string>
<string name="spoken_emoji_1F36B" msgid="6342163604299875931">"Barra de chocolate"</string>
<string name="spoken_emoji_1F36C" msgid="2168934753998218790">"Caramelo"</string>
- <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Chupa-chupa"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lollipop"</string>
<string name="spoken_emoji_1F36E" msgid="4630541402785165902">"Crema"</string>
<string name="spoken_emoji_1F36F" msgid="5577915387425169439">"Tarro de mel"</string>
<string name="spoken_emoji_1F370" msgid="7243244547866114951">"Pastel"</string>
diff --git a/java/res/values-gl-rES/strings.xml b/java/res/values-gl-rES/strings.xml
index d266ad5a6..d72bcb8b1 100644
--- a/java/res/values-gl-rES/strings.xml
+++ b/java/res/values-gl-rES/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Serbio (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicional)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (compacto)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Ningún idioma (alfabeto)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabeto (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabeto (QWERTZ)"</string>
diff --git a/java/res/values-hi/strings-emoji-descriptions.xml b/java/res/values-hi/strings-emoji-descriptions.xml
index 1f18e6add..df5fa1e13 100644
--- a/java/res/values-hi/strings-emoji-descriptions.xml
+++ b/java/res/values-hi/strings-emoji-descriptions.xml
@@ -267,7 +267,7 @@
<string name="spoken_emoji_1F36A" msgid="2726271795913042295">"कुकी"</string>
<string name="spoken_emoji_1F36B" msgid="6342163604299875931">"चॉकलेट बार"</string>
<string name="spoken_emoji_1F36C" msgid="2168934753998218790">"कैंडी"</string>
- <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"लॉलीपॉप"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lollipop"</string>
<string name="spoken_emoji_1F36E" msgid="4630541402785165902">"दही"</string>
<string name="spoken_emoji_1F36F" msgid="5577915387425169439">"शहद का बर्तन"</string>
<string name="spoken_emoji_1F370" msgid="7243244547866114951">"शॉर्टकेक"</string>
diff --git a/java/res/values-hi/strings.xml b/java/res/values-hi/strings.xml
index 9fc08ac8e..a4f2dd39d 100644
--- a/java/res/values-hi/strings.xml
+++ b/java/res/values-hi/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"हिंग्लिश (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"सर्बियाई (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (पारंपरिक)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (संक्षिप्त)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"भाषा उपलब्ध नहीं है (लैटिन वर्णाक्षर)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"वर्णाक्षर (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"वर्णाक्षर (QWERTZ)"</string>
diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml
index 7a5a665b3..e1893714e 100644
--- a/java/res/values-hr/strings.xml
+++ b/java/res/values-hr/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Srpski (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicionalni)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (kompaktna)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Nema jezika (abeceda)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Abeceda (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Abeceda (QWERTZ)"</string>
diff --git a/java/res/values-hy-rAM/strings.xml b/java/res/values-hy-rAM/strings.xml
index 7d301195a..8d7c5c8c1 100644
--- a/java/res/values-hy-rAM/strings.xml
+++ b/java/res/values-hy-rAM/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Հինգլիշ (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Սերբերեն (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ավանդական)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (սեղմ)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Ոչ մի լեզվով (Այբուբեն)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Այբուբեն (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Այբուբեն (QWERTZ)"</string>
diff --git a/java/res/values-is-rIS/strings.xml b/java/res/values-is-rIS/strings.xml
index 2bc3bfbeb..8a6927af1 100644
--- a/java/res/values-is-rIS/strings.xml
+++ b/java/res/values-is-rIS/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Serbneskt (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (hefðbundið)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (lítið)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Ekkert tungumál (stafróf)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Stafróf (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Stafróf (QWERTZ)"</string>
diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml
index 4caaae394..53ef5779f 100644
--- a/java/res/values-ja/strings.xml
+++ b/java/res/values-ja/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ヒングリッシュ(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"セルビア語(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(伝統言語)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(コンパクト)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"言語なし(アルファベット)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"アルファベット(QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"アルファベット(QWERTZ)"</string>
diff --git a/java/res/values-ka-rGE/strings.xml b/java/res/values-ka-rGE/strings.xml
index dc2308c2e..d4457a508 100644
--- a/java/res/values-ka-rGE/strings.xml
+++ b/java/res/values-ka-rGE/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ჰინგლისური (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"სერბული (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ტრადიციული)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (კომპაქტური)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"ენის გარეშე (ანბანი)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"ანბანი (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"ანბანი (QWERTZ)"</string>
diff --git a/java/res/values-kk-rKZ/strings.xml b/java/res/values-kk-rKZ/strings.xml
index 838a07a77..58f8f306e 100644
--- a/java/res/values-kk-rKZ/strings.xml
+++ b/java/res/values-kk-rKZ/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Хинглиш (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Серб (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (дәстүрлі)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (шағын)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Тіл жоқ (әліпби)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Әліпби (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Әліпби (QWERTZ)"</string>
diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml
index e3935174e..68195f0d1 100644
--- a/java/res/values-ko/strings.xml
+++ b/java/res/values-ko/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"인도 영어(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"세르비아어(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(번체)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(컴팩트)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"언어 없음(알파벳)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"알파벳(QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"알파벳(QWERTZ)"</string>
diff --git a/java/res/values-ky-rKG/strings.xml b/java/res/values-ky-rKG/strings.xml
index 90c2db3b1..6b46785e3 100644
--- a/java/res/values-ky-rKG/strings.xml
+++ b/java/res/values-ky-rKG/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Хинглиш (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Сербче (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Салттык)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Чакан)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Тил жок (Алфавит)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Алфавит (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Алфавит (QWERTZ)"</string>
diff --git a/java/res/values-lo-rLA/strings-emoji-descriptions.xml b/java/res/values-lo-rLA/strings-emoji-descriptions.xml
index 0747fa629..84b9d0502 100644
--- a/java/res/values-lo-rLA/strings-emoji-descriptions.xml
+++ b/java/res/values-lo-rLA/strings-emoji-descriptions.xml
@@ -267,7 +267,7 @@
<string name="spoken_emoji_1F36A" msgid="2726271795913042295">"​ຄຸ​ກ​ກີ້"</string>
<string name="spoken_emoji_1F36B" msgid="6342163604299875931">"​ຊັອກ​ໂກ​ແລັດບາ"</string>
<string name="spoken_emoji_1F36C" msgid="2168934753998218790">"ແຄນດີ້"</string>
- <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"​ໂລ​ລິ​ປັອບ"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lollipop"</string>
<string name="spoken_emoji_1F36E" msgid="4630541402785165902">"​ຄັ​ສ​ຕາດ"</string>
<string name="spoken_emoji_1F36F" msgid="5577915387425169439">"ໝໍ້​ນ້ຳ​ເຜິ້ງ"</string>
<string name="spoken_emoji_1F370" msgid="7243244547866114951">"ຊັອດ​ເຄັກ"</string>
diff --git a/java/res/values-lo-rLA/strings.xml b/java/res/values-lo-rLA/strings.xml
index b23eb31b7..efc09bebc 100644
--- a/java/res/values-lo-rLA/strings.xml
+++ b/java/res/values-lo-rLA/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ຮິງ​ລິສ (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"ເຊີ​ບຽນ (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ດັ້ງ​ເດີມ)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ກະ​ທັດ​ຮັດ)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"ບໍ່ມີພາສາ (ໂຕອັກສອນ)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"ໂຕອັກສອນ (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"ໂຕອັກສອນ (QWERTZ)"</string>
diff --git a/java/res/values-lt/strings-emoji-descriptions.xml b/java/res/values-lt/strings-emoji-descriptions.xml
index fa81dbbd8..afe9ac0e6 100644
--- a/java/res/values-lt/strings-emoji-descriptions.xml
+++ b/java/res/values-lt/strings-emoji-descriptions.xml
@@ -267,7 +267,7 @@
<string name="spoken_emoji_1F36A" msgid="2726271795913042295">"Sausainis"</string>
<string name="spoken_emoji_1F36B" msgid="6342163604299875931">"Šokolado plytelė"</string>
<string name="spoken_emoji_1F36C" msgid="2168934753998218790">"Saldainis"</string>
- <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Ledinukas ant pagaliuko"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lollipop"</string>
<string name="spoken_emoji_1F36E" msgid="4630541402785165902">"Saldus kremas"</string>
<string name="spoken_emoji_1F36F" msgid="5577915387425169439">"Medaus puodynė"</string>
<string name="spoken_emoji_1F370" msgid="7243244547866114951">"Trapus pyragas"</string>
diff --git a/java/res/values-lv/strings-emoji-descriptions.xml b/java/res/values-lv/strings-emoji-descriptions.xml
index a51991b81..525a1a0e8 100644
--- a/java/res/values-lv/strings-emoji-descriptions.xml
+++ b/java/res/values-lv/strings-emoji-descriptions.xml
@@ -267,7 +267,7 @@
<string name="spoken_emoji_1F36A" msgid="2726271795913042295">"Cepums"</string>
<string name="spoken_emoji_1F36B" msgid="6342163604299875931">"Šokolādes tāfelīte"</string>
<string name="spoken_emoji_1F36C" msgid="2168934753998218790">"Konfekte"</string>
- <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Cukurgailītis"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lollipop"</string>
<string name="spoken_emoji_1F36E" msgid="4630541402785165902">"Olu krēms"</string>
<string name="spoken_emoji_1F36F" msgid="5577915387425169439">"Medus pods"</string>
<string name="spoken_emoji_1F370" msgid="7243244547866114951">"Smilšu torte ar augļu pildījumu"</string>
diff --git a/java/res/values-lv/strings.xml b/java/res/values-lv/strings.xml
index ed7e9d457..833839b8a 100644
--- a/java/res/values-lv/strings.xml
+++ b/java/res/values-lv/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hindi–angļu valoda (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Serbu (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicionālā)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (kompaktā)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Nav valodas (alfabēts)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabēts (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabēts (QWERTZ)"</string>
diff --git a/java/res/values-ml-rIN/strings-emoji-descriptions.xml b/java/res/values-ml-rIN/strings-emoji-descriptions.xml
index a846f31a5..ab6509756 100644
--- a/java/res/values-ml-rIN/strings-emoji-descriptions.xml
+++ b/java/res/values-ml-rIN/strings-emoji-descriptions.xml
@@ -267,7 +267,7 @@
<string name="spoken_emoji_1F36A" msgid="2726271795913042295">"കുക്കി"</string>
<string name="spoken_emoji_1F36B" msgid="6342163604299875931">"ചോക്കലേറ്റ് ബാർ"</string>
<string name="spoken_emoji_1F36C" msgid="2168934753998218790">"മിഠായി"</string>
- <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"ലോലിപോപ്പ്"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lollipop"</string>
<string name="spoken_emoji_1F36E" msgid="4630541402785165902">"കസ്‌റ്റാർഡ്"</string>
<string name="spoken_emoji_1F36F" msgid="5577915387425169439">"തേൻ കുടം"</string>
<string name="spoken_emoji_1F370" msgid="7243244547866114951">"ഷോർട്ട്‌കേക്ക്"</string>
diff --git a/java/res/values-ml-rIN/strings.xml b/java/res/values-ml-rIN/strings.xml
index acf00c2b6..a34de64ac 100644
--- a/java/res/values-ml-rIN/strings.xml
+++ b/java/res/values-ml-rIN/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ഹിംഗ്ലീഷ് (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"സെർബിയൻ (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (പരമ്പരാഗതം)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (കോം‌പാക്‌ട്)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"ഭാഷയില്ല (അക്ഷരമാല)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"അക്ഷരമാല (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"അക്ഷരമാല (QWERTZ)"</string>
diff --git a/java/res/values-mr-rIN/strings.xml b/java/res/values-mr-rIN/strings.xml
index 492226a8c..2c6746e35 100644
--- a/java/res/values-mr-rIN/strings.xml
+++ b/java/res/values-mr-rIN/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"हिंग्लिश (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"सर्बियन (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (पारंपारिक)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (संक्षिप्त)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"भाषा नाही (वर्णमाला)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"वर्णमाला (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"वर्णमाला (QWERTZ)"</string>
diff --git a/java/res/values-ms-rMY/strings.xml b/java/res/values-ms-rMY/strings.xml
index f33bdb4b3..3136c3bbd 100644
--- a/java/res/values-ms-rMY/strings.xml
+++ b/java/res/values-ms-rMY/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Bahasa Serbia (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Tradisional)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Sarat)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Tiada bahasa (Abjad)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Abjad (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Abjad (QWERTZ)"</string>
diff --git a/java/res/values-my-rMM/strings.xml b/java/res/values-my-rMM/strings.xml
index 3e5a491ea..ab4037861 100644
--- a/java/res/values-my-rMM/strings.xml
+++ b/java/res/values-my-rMM/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ဟင်ဂလိပ် (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"ဆားဘီယား (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ရိုးရာ)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ကျစ်လစ်သော)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"ဘာသာစကားမရှိ (ဗျည်းအက္ခရာ)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"ဗျည်းအက္ခရာ (ကွာတီ)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"ဗျည်းအက္ခရာ (ကွာတီ)"</string>
diff --git a/java/res/values-ne-rNP/strings-emoji-descriptions.xml b/java/res/values-ne-rNP/strings-emoji-descriptions.xml
index 43f4d892b..39e5bc075 100644
--- a/java/res/values-ne-rNP/strings-emoji-descriptions.xml
+++ b/java/res/values-ne-rNP/strings-emoji-descriptions.xml
@@ -267,7 +267,7 @@
<string name="spoken_emoji_1F36A" msgid="2726271795913042295">"कुकीज"</string>
<string name="spoken_emoji_1F36B" msgid="6342163604299875931">"चकलेट बार"</string>
<string name="spoken_emoji_1F36C" msgid="2168934753998218790">"क्यान्डी"</string>
- <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"लालीपप"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lollipop"</string>
<string name="spoken_emoji_1F36E" msgid="4630541402785165902">"कस्तार्ड"</string>
<string name="spoken_emoji_1F36F" msgid="5577915387425169439">"महदानी"</string>
<string name="spoken_emoji_1F370" msgid="7243244547866114951">"सर्टकेक"</string>
diff --git a/java/res/values-ne-rNP/strings.xml b/java/res/values-ne-rNP/strings.xml
index ec17c4e6f..40c2d4f96 100644
--- a/java/res/values-ne-rNP/strings.xml
+++ b/java/res/values-ne-rNP/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"हिङ्लिस (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"सर्बियाई (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (परम्परागत)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (संकुचित)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"कुनै भाषा होइन (वर्णमाला)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"वर्णमाला (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"वर्णमाला (QWERTZ)"</string>
diff --git a/java/res/values-nl/strings-emoji-descriptions.xml b/java/res/values-nl/strings-emoji-descriptions.xml
index 3b298900b..a02c21fa0 100644
--- a/java/res/values-nl/strings-emoji-descriptions.xml
+++ b/java/res/values-nl/strings-emoji-descriptions.xml
@@ -267,7 +267,7 @@
<string name="spoken_emoji_1F36A" msgid="2726271795913042295">"Cookie"</string>
<string name="spoken_emoji_1F36B" msgid="6342163604299875931">"Chocoladereep"</string>
<string name="spoken_emoji_1F36C" msgid="2168934753998218790">"Snoep"</string>
- <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lolly"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lollipop"</string>
<string name="spoken_emoji_1F36E" msgid="4630541402785165902">"Vla"</string>
<string name="spoken_emoji_1F36F" msgid="5577915387425169439">"Honingpot"</string>
<string name="spoken_emoji_1F370" msgid="7243244547866114951">"Cake"</string>
diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml
index 8e3ebf2bf..03398733c 100644
--- a/java/res/values-ro/strings.xml
+++ b/java/res/values-ro/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Sârbă (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradițională)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Compact)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Nicio limbă (alfabet)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabet (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabet (QWERTZ)"</string>
diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml
index bd45c68a7..e5aaf8ba7 100644
--- a/java/res/values-ru/strings.xml
+++ b/java/res/values-ru/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Хинглиш (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Сербский (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (классическая)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (компактная раскладка)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Язык не определен (латиница)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Латиница (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Латиница (QWERTZ)"</string>
diff --git a/java/res/values-si-rLK/strings.xml b/java/res/values-si-rLK/strings.xml
index 2e5f3d9f4..f8fa5e7c3 100644
--- a/java/res/values-si-rLK/strings.xml
+++ b/java/res/values-si-rLK/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"හින්ග්ලිෂ් (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"සර්බියානු (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (සාම්ප්‍රදායික)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (සංයුක්ත)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"භාෂාවක් නැත (අකාරාදිය)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"අකාරාදිය (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"අකාරාදිය (QWERTZ)"</string>
diff --git a/java/res/values-sk/strings.xml b/java/res/values-sk/strings.xml
index 80c91c89f..0d0e69fee 100644
--- a/java/res/values-sk/strings.xml
+++ b/java/res/values-sk/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"srbčina (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradičná)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (kompaktná)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Žiadny jazyk (latinka)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Latinka (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Latinka (QWERTZ)"</string>
diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml
index 396334cdb..e1f86c36c 100644
--- a/java/res/values-sl/strings.xml
+++ b/java/res/values-sl/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hindujska angleščina (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Srbščina (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (tradicionalna)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (kompaktna)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Brez jezika (latinice)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Latinica (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Latinica (QWERTZ)"</string>
diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml
index 28f6cae4e..f8c4ff601 100644
--- a/java/res/values-sr/strings.xml
+++ b/java/res/values-sr/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"хенглески (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"српски (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (традиционални)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (компактна)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Нема језика (абецеда)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Абецеда (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Абецеда (QWERTZ)"</string>
diff --git a/java/res/values-sv/strings-emoji-descriptions.xml b/java/res/values-sv/strings-emoji-descriptions.xml
index 879de0b90..e49c73ce4 100644
--- a/java/res/values-sv/strings-emoji-descriptions.xml
+++ b/java/res/values-sv/strings-emoji-descriptions.xml
@@ -267,7 +267,7 @@
<string name="spoken_emoji_1F36A" msgid="2726271795913042295">"Småkaka"</string>
<string name="spoken_emoji_1F36B" msgid="6342163604299875931">"Chokladkaka"</string>
<string name="spoken_emoji_1F36C" msgid="2168934753998218790">"Godis"</string>
- <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Klubba"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lollipop"</string>
<string name="spoken_emoji_1F36E" msgid="4630541402785165902">"Vaniljkräm"</string>
<string name="spoken_emoji_1F36F" msgid="5577915387425169439">"Honungsburk"</string>
<string name="spoken_emoji_1F370" msgid="7243244547866114951">"Sockerkaka"</string>
diff --git a/java/res/values-sw/strings.xml b/java/res/values-sw/strings.xml
index ae1a3a8f7..04c4f2bb7 100644
--- a/java/res/values-sw/strings.xml
+++ b/java/res/values-sw/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Kiserbia (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (cha Jadi)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Thabiti)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Hakuna lugha (Alfabeti)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabeti (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabeti (QWERTZ)"</string>
diff --git a/java/res/values-ta-rIN/strings.xml b/java/res/values-ta-rIN/strings.xml
index 0a2d13890..64c573ba8 100644
--- a/java/res/values-ta-rIN/strings.xml
+++ b/java/res/values-ta-rIN/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ஹிங்கிலிஷ் (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"செர்பியன் (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (பாரம்பரியமானது)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (வசதியான)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"மொழியில்லை (அகரவரிசை)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"அகரவரிசை (க்வெர்டி)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"அகரவரிசை (க்வெர்ட்ச்)"</string>
diff --git a/java/res/values-te-rIN/strings.xml b/java/res/values-te-rIN/strings.xml
index 15e9aaf38..0fb55b4b2 100644
--- a/java/res/values-te-rIN/strings.xml
+++ b/java/res/values-te-rIN/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"హింగ్లీష్ (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"సెర్బియన్ (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (సాంప్రదాయకం)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (కాంపాక్ట్)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"భాష లేదు (ఆల్ఫాబెట్)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"ఆల్ఫాబెట్ (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"ఆల్ఫాబెట్ (QWERTZ)"</string>
diff --git a/java/res/values-th/strings-emoji-descriptions.xml b/java/res/values-th/strings-emoji-descriptions.xml
index 86ab2c08e..e5ef9b89d 100644
--- a/java/res/values-th/strings-emoji-descriptions.xml
+++ b/java/res/values-th/strings-emoji-descriptions.xml
@@ -267,7 +267,7 @@
<string name="spoken_emoji_1F36A" msgid="2726271795913042295">"คุกกี้"</string>
<string name="spoken_emoji_1F36B" msgid="6342163604299875931">"ช็อกโกแลตแท่ง"</string>
<string name="spoken_emoji_1F36C" msgid="2168934753998218790">"ลูกกวาด"</string>
- <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"อมยิ้ม"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lollipop"</string>
<string name="spoken_emoji_1F36E" msgid="4630541402785165902">"คัสตาร์ด"</string>
<string name="spoken_emoji_1F36F" msgid="5577915387425169439">"โถน้ำผึ้ง"</string>
<string name="spoken_emoji_1F370" msgid="7243244547866114951">"ชอร์ตเค้ก"</string>
diff --git a/java/res/values-th/strings.xml b/java/res/values-th/strings.xml
index 5c239dbd4..fcc76d9b9 100644
--- a/java/res/values-th/strings.xml
+++ b/java/res/values-th/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ภาษาอังกฤษผสมกับฮินดู (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"เซอร์เบีย (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ดั้งเดิม)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (แบบกะทัดรัด)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"ไม่มีภาษา (ตัวอักษรละติน)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"ตัวอักษร (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"ตัวอักษร (QWERTZ)"</string>
diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml
index 8d755e42f..82617b889 100644
--- a/java/res/values-tl/strings.xml
+++ b/java/res/values-tl/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Serbian (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Traditional)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Compact)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Walang wika (Alpabeto)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alpabeto (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alpabeto (QWERTZ)"</string>
diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml
index 86426fa1a..359e0d16f 100644
--- a/java/res/values-tr/strings.xml
+++ b/java/res/values-tr/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hingilizce (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Sırpça (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Geleneksel)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Kompakt)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Dil yok (Alfabe)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alfabe (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alfabe (QWERTZ)"</string>
diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml
index 33ab58497..dd625cb70 100644
--- a/java/res/values-uk/strings.xml
+++ b/java/res/values-uk/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Хінґліш (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"сербська (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (традиційна)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (компактна)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Стандартна (латиниця)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Латиниця (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Латиниця (QWERTZ)"</string>
diff --git a/java/res/values-ur-rPK/strings-emoji-descriptions.xml b/java/res/values-ur-rPK/strings-emoji-descriptions.xml
index e6bbdcf49..d5bcf2f94 100644
--- a/java/res/values-ur-rPK/strings-emoji-descriptions.xml
+++ b/java/res/values-ur-rPK/strings-emoji-descriptions.xml
@@ -267,7 +267,7 @@
<string name="spoken_emoji_1F36A" msgid="2726271795913042295">"کوکی"</string>
<string name="spoken_emoji_1F36B" msgid="6342163604299875931">"چاکلیٹ بار"</string>
<string name="spoken_emoji_1F36C" msgid="2168934753998218790">"قندی"</string>
- <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"لالی پاپ"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lollipop"</string>
<string name="spoken_emoji_1F36E" msgid="4630541402785165902">"کسٹرڈ"</string>
<string name="spoken_emoji_1F36F" msgid="5577915387425169439">"شہد کا برتن"</string>
<string name="spoken_emoji_1F370" msgid="7243244547866114951">"کیک کا ٹکڑا"</string>
diff --git a/java/res/values-ur-rPK/strings.xml b/java/res/values-ur-rPK/strings.xml
index f00e503e0..4b1f03b03 100644
--- a/java/res/values-ur-rPK/strings.xml
+++ b/java/res/values-ur-rPK/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"ہنگلش (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"سربیائی (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (روایتی)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (کمپیکٹ)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"کوئی زبان نہیں (الفابیٹ)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"‏حروف تہجی (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"‏حروف تہجی (QWERTZ)"</string>
diff --git a/java/res/values-uz-rUZ/strings.xml b/java/res/values-uz-rUZ/strings.xml
index 62143d7af..59aba60f0 100644
--- a/java/res/values-uz-rUZ/strings.xml
+++ b/java/res/values-uz-rUZ/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Serb (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (an’anaviy)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (ixcham)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Til aniqlanmadi (lotin)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Lotin (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Lotin (QWERTZ)"</string>
diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml
index fa0e11b51..ec0deb117 100644
--- a/java/res/values-vi/strings.xml
+++ b/java/res/values-vi/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Tiếng Anh-Hindi (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Tiếng Serbia (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Truyền thống)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Viết tắt)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"Không ngôn ngữ nào (Bảng chữ cái)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"Bảng chữ cái (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"Bảng chữ cái (QWERTZ)"</string>
diff --git a/java/res/values-zh-rCN/strings.xml b/java/res/values-zh-rCN/strings.xml
index 4562c4bd1..52b0dac74 100644
--- a/java/res/values-zh-rCN/strings.xml
+++ b/java/res/values-zh-rCN/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"印地英语(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"塞尔维亚语(<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>布局)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(传统)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>(紧凑型)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"无语言(字母)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"字母 (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"字母 (QWERTZ)"</string>
diff --git a/java/res/values-zh-rHK/strings.xml b/java/res/values-zh-rHK/strings.xml
index e584a88fe..840f33387 100644
--- a/java/res/values-zh-rHK/strings.xml
+++ b/java/res/values-zh-rHK/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"印度英文 (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"塞爾維亞文 (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (傳統)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (精簡版)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"無語言 (字母)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"字母 (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"字母 (QWERTZ)"</string>
diff --git a/java/res/values-zh-rTW/strings-emoji-descriptions.xml b/java/res/values-zh-rTW/strings-emoji-descriptions.xml
index 06e260a69..b5c723066 100644
--- a/java/res/values-zh-rTW/strings-emoji-descriptions.xml
+++ b/java/res/values-zh-rTW/strings-emoji-descriptions.xml
@@ -267,7 +267,7 @@
<string name="spoken_emoji_1F36A" msgid="2726271795913042295">"餅乾"</string>
<string name="spoken_emoji_1F36B" msgid="6342163604299875931">"巧克力棒"</string>
<string name="spoken_emoji_1F36C" msgid="2168934753998218790">"糖果"</string>
- <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"棒棒糖"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lollipop"</string>
<string name="spoken_emoji_1F36E" msgid="4630541402785165902">"卡士達"</string>
<string name="spoken_emoji_1F36F" msgid="5577915387425169439">"蜂蜜罐"</string>
<string name="spoken_emoji_1F370" msgid="7243244547866114951">"水果蛋糕"</string>
diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml
index aa534c869..8fac3105e 100644
--- a/java/res/values-zh-rTW/strings.xml
+++ b/java/res/values-zh-rTW/strings.xml
@@ -102,8 +102,7 @@
<string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"印度英文 (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"塞爾維亞文 (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string>
<string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (傳統)"</string>
- <!-- no translation found for subtype_generic_compact (3353673321203202922) -->
- <skip />
+ <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (精簡)"</string>
<string name="subtype_no_language" msgid="7137390094240139495">"無語言 (字母)"</string>
<string name="subtype_no_language_qwerty" msgid="244337630616742604">"字母 (QWERTY)"</string>
<string name="subtype_no_language_qwertz" msgid="443066912507547976">"字母 (QWERTZ)"</string>
diff --git a/java/res/values/donottranslate-debug-settings.xml b/java/res/values/donottranslate-debug-settings.xml
index c612010f6..491043f1a 100644
--- a/java/res/values/donottranslate-debug-settings.xml
+++ b/java/res/values/donottranslate-debug-settings.xml
@@ -43,6 +43,10 @@
<string name="prefs_key_popup_dismiss_end_y_scale_settings">Key popup dismiss end Y scale</string>
<!-- Title of the settings for reading an external dictionary file -->
<string name="prefs_read_external_dictionary">Read external dictionary file</string>
+ <!-- Title of the settings to enable keyboard resizing -->
+ <string name="prefs_resize_keyboard">Enable keyboard resizing</string>
+ <!-- Title of the settings for setting keyboard height -->
+ <string name="prefs_keyboard_height_scale">Keyboard height scale</string>
<!-- Message to show when there are no files to install as an external dictionary [CHAR LIMIT=100] -->
<string name="read_external_dictionary_no_files_message">No dictionary files in the Downloads folder</string>
<!-- Title of the dialog that selects a file to install as an external dictionary [CHAR LIMIT=50] -->
diff --git a/java/res/xml/prefs_screen_debug.xml b/java/res/xml/prefs_screen_debug.xml
index 13edf3ec6..905bc045c 100644
--- a/java/res/xml/prefs_screen_debug.xml
+++ b/java/res/xml/prefs_screen_debug.xml
@@ -76,6 +76,17 @@
android:key="pref_key_preview_dismiss_duration"
android:title="@string/prefs_key_popup_dismiss_duration_settings"
latin:maxValue="100" /> <!-- milliseconds -->
+ <CheckBoxPreference
+ android:key="pref_resize_keyboard"
+ android:title="@string/prefs_resize_keyboard"
+ android:defaultValue="false"
+ android:persistent="true" />
+ <com.android.inputmethod.latin.settings.SeekBarDialogPreference
+ android:dependency="pref_resize_keyboard"
+ android:key="pref_keyboard_height_scale"
+ android:title="@string/prefs_keyboard_height_scale"
+ latin:minValue="50"
+ latin:maxValue="120" /> <!-- percentage -->
<PreferenceScreen
android:key="read_external_dictionary"
android:title="@string/prefs_read_external_dictionary" />
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
index b674359e6..7eb91b588 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
@@ -359,7 +359,7 @@ public final class KeyboardLayoutSet {
try {
final int scriptId =
featureAttr.getInt(R.styleable.KeyboardLayoutSet_Feature_supportedScript,
- ScriptUtils.SCRIPT_UNKNOWN);
+ ScriptUtils.SCRIPT_UNKNOWN);
XmlParseUtils.checkEndTag(TAG_FEATURE, parser);
return scriptId;
} finally {
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 3bcce4f69..af24ac48c 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -39,6 +39,8 @@ import com.android.inputmethod.latin.WordComposer;
import com.android.inputmethod.latin.define.ProductionFlags;
import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.settings.SettingsValues;
+import com.android.inputmethod.latin.utils.CapsModeUtils;
+import com.android.inputmethod.latin.utils.RecapitalizeStatus;
import com.android.inputmethod.latin.utils.ResourceUtils;
import com.android.inputmethod.latin.utils.ScriptUtils;
@@ -110,7 +112,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
mThemeContext, editorInfo);
final Resources res = mThemeContext.getResources();
final int keyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res);
- final int keyboardHeight = ResourceUtils.getDefaultKeyboardHeight(res);
+ final int keyboardHeight = ResourceUtils.getKeyboardHeight(res, settingsValues);
builder.setKeyboardGeometry(keyboardWidth, keyboardHeight);
builder.setSubtype(mSubtypeSwitcher.getCurrentSubtype());
builder.setVoiceInputKeyEnabled(settingsValues.mShowsVoiceInputKey);
@@ -204,36 +206,54 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void setAlphabetKeyboard() {
+ if (DEBUG_ACTION) {
+ Log.d(TAG, "setAlphabetKeyboard");
+ }
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET));
}
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void setAlphabetManualShiftedKeyboard() {
+ if (DEBUG_ACTION) {
+ Log.d(TAG, "setAlphabetManualShiftedKeyboard");
+ }
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED));
}
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void setAlphabetAutomaticShiftedKeyboard() {
+ if (DEBUG_ACTION) {
+ Log.d(TAG, "setAlphabetAutomaticShiftedKeyboard");
+ }
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED));
}
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void setAlphabetShiftLockedKeyboard() {
+ if (DEBUG_ACTION) {
+ Log.d(TAG, "setAlphabetShiftLockedKeyboard");
+ }
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED));
}
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void setAlphabetShiftLockShiftedKeyboard() {
+ if (DEBUG_ACTION) {
+ Log.d(TAG, "setAlphabetShiftLockShiftedKeyboard");
+ }
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED));
}
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void setSymbolsKeyboard() {
+ if (DEBUG_ACTION) {
+ Log.d(TAG, "setSymbolsKeyboard");
+ }
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_SYMBOLS));
}
@@ -247,6 +267,9 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void setEmojiKeyboard() {
+ if (DEBUG_ACTION) {
+ Log.d(TAG, "setEmojiKeyboard");
+ }
final Keyboard keyboard = mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET);
mMainKeyboardFrame.setVisibility(View.GONE);
mEmojiPalettesView.startEmojiPalettes(
@@ -269,19 +292,29 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void setSymbolsShiftedKeyboard() {
+ if (DEBUG_ACTION) {
+ Log.d(TAG, "setSymbolsShiftedKeyboard");
+ }
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_SYMBOLS_SHIFTED));
}
// Future method for requesting an updating to the shift state.
@Override
- public void requestUpdatingShiftState(final int currentAutoCapsState,
- final int currentRecapitalizeState) {
- mState.onUpdateShiftState(currentAutoCapsState, currentRecapitalizeState);
+ public void requestUpdatingShiftState(final int autoCapsFlags, final int recapitalizeMode) {
+ if (DEBUG_ACTION) {
+ Log.d(TAG, "requestUpdatingShiftState: "
+ + " autoCapsFlags=" + CapsModeUtils.flagsToString(autoCapsFlags)
+ + " recapitalizeMode=" + RecapitalizeStatus.modeToString(recapitalizeMode));
+ }
+ mState.onUpdateShiftState(autoCapsFlags, recapitalizeMode);
}
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void startDoubleTapShiftKeyTimer() {
+ if (DEBUG_TIMER_ACTION) {
+ Log.d(TAG, "startDoubleTapShiftKeyTimer");
+ }
final MainKeyboardView keyboardView = getMainKeyboardView();
if (keyboardView != null) {
keyboardView.startDoubleTapShiftKeyTimer();
@@ -291,6 +324,9 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void cancelDoubleTapShiftKeyTimer() {
+ if (DEBUG_TIMER_ACTION) {
+ Log.d(TAG, "setAlphabetKeyboard");
+ }
final MainKeyboardView keyboardView = getMainKeyboardView();
if (keyboardView != null) {
keyboardView.cancelDoubleTapShiftKeyTimer();
@@ -300,6 +336,9 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
// Implements {@link KeyboardState.SwitchActions}.
@Override
public boolean isInDoubleTapShiftKeyTimeout() {
+ if (DEBUG_TIMER_ACTION) {
+ Log.d(TAG, "isInDoubleTapShiftKeyTimeout");
+ }
final MainKeyboardView keyboardView = getMainKeyboardView();
return keyboardView != null && keyboardView.isInDoubleTapShiftKeyTimeout();
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index cc28e7ac8..70e116709 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -21,6 +21,7 @@ import android.util.Log;
import com.android.inputmethod.event.Event;
import com.android.inputmethod.latin.common.Constants;
+import com.android.inputmethod.latin.utils.CapsModeUtils;
import com.android.inputmethod.latin.utils.RecapitalizeStatus;
/**
@@ -38,9 +39,11 @@ import com.android.inputmethod.latin.utils.RecapitalizeStatus;
public final class KeyboardState {
private static final String TAG = KeyboardState.class.getSimpleName();
private static final boolean DEBUG_EVENT = false;
- private static final boolean DEBUG_ACTION = false;
+ private static final boolean DEBUG_INTERNAL_ACTION = false;
public interface SwitchActions {
+ public static final boolean DEBUG_ACTION = false;
+
public void setAlphabetKeyboard();
public void setAlphabetManualShiftedKeyboard();
public void setAlphabetAutomaticShiftedKeyboard();
@@ -53,8 +56,9 @@ public final class KeyboardState {
/**
* Request to call back {@link KeyboardState#onUpdateShiftState(int, int)}.
*/
- public void requestUpdatingShiftState(final int currentAutoCapsState,
- final int currentRecapitalizeState);
+ public void requestUpdatingShiftState(final int autoCapsFlags, final int recapitalizeMode);
+
+ public static final boolean DEBUG_TIMER_ACTION = false;
public void startDoubleTapShiftKeyTimer();
public boolean isInDoubleTapShiftKeyTimeout();
@@ -119,10 +123,9 @@ public final class KeyboardState {
mRecapitalizeMode = RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE;
}
- public void onLoadKeyboard(final int currentAutoCapsState,
- final int currentRecapitalizeState) {
+ public void onLoadKeyboard(final int autoCapsFlags, final int recapitalizeMode) {
if (DEBUG_EVENT) {
- Log.d(TAG, "onLoadKeyboard: " + this);
+ Log.d(TAG, "onLoadKeyboard: " + stateToString(autoCapsFlags, recapitalizeMode));
}
// Reset alphabet shift state.
mAlphabetShiftState.setShiftLocked(false);
@@ -130,7 +133,7 @@ public final class KeyboardState {
mPrevSymbolsKeyboardWasShifted = false;
mShiftKeyState.onRelease();
mSymbolKeyState.onRelease();
- onRestoreKeyboardState(currentAutoCapsState, currentRecapitalizeState);
+ onRestoreKeyboardState(autoCapsFlags, recapitalizeMode);
}
private static final int UNSHIFT = 0;
@@ -156,14 +159,14 @@ public final class KeyboardState {
}
}
- private void onRestoreKeyboardState(final int currentAutoCapsState,
- final int currentRecapitalizeState) {
+ private void onRestoreKeyboardState(final int autoCapsFlags, final int recapitalizeMode) {
final SavedKeyboardState state = mSavedKeyboardState;
if (DEBUG_EVENT) {
- Log.d(TAG, "onRestoreKeyboardState: saved=" + state + " " + this);
+ Log.d(TAG, "onRestoreKeyboardState: saved=" + state
+ + " " + stateToString(autoCapsFlags, recapitalizeMode));
}
if (!state.mIsValid || state.mIsAlphabetMode) {
- setAlphabetKeyboard(currentAutoCapsState, currentRecapitalizeState);
+ setAlphabetKeyboard(autoCapsFlags, recapitalizeMode);
} else if (state.mIsEmojiMode) {
setEmojiKeyboard();
} else {
@@ -188,7 +191,7 @@ public final class KeyboardState {
}
private void setShifted(final int shiftMode) {
- if (DEBUG_ACTION) {
+ if (DEBUG_INTERNAL_ACTION) {
Log.d(TAG, "setShifted: shiftMode=" + shiftModeToString(shiftMode) + " " + this);
}
if (!mIsAlphabetMode) return;
@@ -227,7 +230,7 @@ public final class KeyboardState {
}
private void setShiftLocked(final boolean shiftLocked) {
- if (DEBUG_ACTION) {
+ if (DEBUG_INTERNAL_ACTION) {
Log.d(TAG, "setShiftLocked: shiftLocked=" + shiftLocked + " " + this);
}
if (!mIsAlphabetMode) return;
@@ -241,10 +244,10 @@ public final class KeyboardState {
mAlphabetShiftState.setShiftLocked(shiftLocked);
}
- private void toggleAlphabetAndSymbols(final int currentAutoCapsState,
- final int currentRecapitalizeState) {
- if (DEBUG_ACTION) {
- Log.d(TAG, "toggleAlphabetAndSymbols: " + this);
+ private void toggleAlphabetAndSymbols(final int autoCapsFlags, final int recapitalizeMode) {
+ if (DEBUG_INTERNAL_ACTION) {
+ Log.d(TAG, "toggleAlphabetAndSymbols: "
+ + stateToString(autoCapsFlags, recapitalizeMode));
}
if (mIsAlphabetMode) {
mPrevMainKeyboardWasShiftLocked = mAlphabetShiftState.isShiftLocked();
@@ -256,7 +259,7 @@ public final class KeyboardState {
mPrevSymbolsKeyboardWasShifted = false;
} else {
mPrevSymbolsKeyboardWasShifted = mIsSymbolShifted;
- setAlphabetKeyboard(currentAutoCapsState, currentRecapitalizeState);
+ setAlphabetKeyboard(autoCapsFlags, recapitalizeMode);
if (mPrevMainKeyboardWasShiftLocked) {
setShiftLocked(true);
}
@@ -266,15 +269,15 @@ public final class KeyboardState {
// TODO: Remove this method. Come up with a more comprehensive way to reset the keyboard layout
// when a keyboard layout set doesn't get reloaded in LatinIME.onStartInputViewInternal().
- private void resetKeyboardStateToAlphabet(final int currentAutoCapsState,
- final int currentRecapitalizeState) {
- if (DEBUG_ACTION) {
- Log.d(TAG, "resetKeyboardStateToAlphabet: " + this);
+ private void resetKeyboardStateToAlphabet(final int autoCapsFlags, final int recapitalizeMode) {
+ if (DEBUG_INTERNAL_ACTION) {
+ Log.d(TAG, "resetKeyboardStateToAlphabet: "
+ + stateToString(autoCapsFlags, recapitalizeMode));
}
if (mIsAlphabetMode) return;
mPrevSymbolsKeyboardWasShifted = mIsSymbolShifted;
- setAlphabetKeyboard(currentAutoCapsState, currentRecapitalizeState);
+ setAlphabetKeyboard(autoCapsFlags, recapitalizeMode);
if (mPrevMainKeyboardWasShiftLocked) {
setShiftLocked(true);
}
@@ -289,10 +292,9 @@ public final class KeyboardState {
}
}
- private void setAlphabetKeyboard(final int currentAutoCapsState,
- final int currentRecapitalizeState) {
- if (DEBUG_ACTION) {
- Log.d(TAG, "setAlphabetKeyboard");
+ private void setAlphabetKeyboard(final int autoCapsFlags, final int recapitalizeMode) {
+ if (DEBUG_INTERNAL_ACTION) {
+ Log.d(TAG, "setAlphabetKeyboard: " + stateToString(autoCapsFlags, recapitalizeMode));
}
mSwitchActions.setAlphabetKeyboard();
@@ -301,11 +303,11 @@ public final class KeyboardState {
mIsSymbolShifted = false;
mRecapitalizeMode = RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE;
mSwitchState = SWITCH_STATE_ALPHA;
- mSwitchActions.requestUpdatingShiftState(currentAutoCapsState, currentRecapitalizeState);
+ mSwitchActions.requestUpdatingShiftState(autoCapsFlags, recapitalizeMode);
}
private void setSymbolsKeyboard() {
- if (DEBUG_ACTION) {
+ if (DEBUG_INTERNAL_ACTION) {
Log.d(TAG, "setSymbolsKeyboard");
}
mSwitchActions.setSymbolsKeyboard();
@@ -318,7 +320,7 @@ public final class KeyboardState {
}
private void setSymbolsShiftedKeyboard() {
- if (DEBUG_ACTION) {
+ if (DEBUG_INTERNAL_ACTION) {
Log.d(TAG, "setSymbolsShiftedKeyboard");
}
mSwitchActions.setSymbolsShiftedKeyboard();
@@ -331,7 +333,7 @@ public final class KeyboardState {
}
private void setEmojiKeyboard() {
- if (DEBUG_ACTION) {
+ if (DEBUG_INTERNAL_ACTION) {
Log.d(TAG, "setEmojiKeyboard");
}
mIsAlphabetMode = false;
@@ -343,11 +345,12 @@ public final class KeyboardState {
mSwitchActions.setEmojiKeyboard();
}
- public void onPressKey(final int code, final boolean isSinglePointer,
- final int currentAutoCapsState, final int currentRecapitalizeState) {
+ public void onPressKey(final int code, final boolean isSinglePointer, final int autoCapsFlags,
+ final int recapitalizeMode) {
if (DEBUG_EVENT) {
- Log.d(TAG, "onPressKey: code=" + Constants.printableCode(code) + " single="
- + isSinglePointer + " autoCaps=" + currentAutoCapsState + " " + this);
+ Log.d(TAG, "onPressKey: code=" + Constants.printableCode(code)
+ + " single=" + isSinglePointer
+ + " " + stateToString(autoCapsFlags, recapitalizeMode));
}
if (code != Constants.CODE_SHIFT) {
// Because the double tap shift key timer is to detect two consecutive shift key press,
@@ -359,7 +362,7 @@ public final class KeyboardState {
} else if (code == Constants.CODE_CAPSLOCK) {
// Nothing to do here. See {@link #onReleaseKey(int,boolean)}.
} else if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) {
- onPressSymbol(currentAutoCapsState, currentRecapitalizeState);
+ onPressSymbol(autoCapsFlags, recapitalizeMode);
} else {
mShiftKeyState.onOtherKeyPressed();
mSymbolKeyState.onOtherKeyPressed();
@@ -372,7 +375,7 @@ public final class KeyboardState {
// off because, for example, we may be in the #1 state within the manual temporary
// shifted mode.
if (!isSinglePointer && mIsAlphabetMode
- && currentAutoCapsState != TextUtils.CAP_MODE_CHARACTERS) {
+ && autoCapsFlags != TextUtils.CAP_MODE_CHARACTERS) {
final boolean needsToResetAutoCaps = mAlphabetShiftState.isAutomaticShifted()
|| (mAlphabetShiftState.isManualShifted() && mShiftKeyState.isReleasing());
if (needsToResetAutoCaps) {
@@ -382,34 +385,35 @@ public final class KeyboardState {
}
}
- public void onReleaseKey(final int code, final boolean withSliding,
- final int currentAutoCapsState, final int currentRecapitalizeState) {
+ public void onReleaseKey(final int code, final boolean withSliding, final int autoCapsFlags,
+ final int recapitalizeMode) {
if (DEBUG_EVENT) {
Log.d(TAG, "onReleaseKey: code=" + Constants.printableCode(code)
- + " sliding=" + withSliding + " " + this);
+ + " sliding=" + withSliding
+ + " " + stateToString(autoCapsFlags, recapitalizeMode));
}
if (code == Constants.CODE_SHIFT) {
- onReleaseShift(withSliding, currentAutoCapsState, currentRecapitalizeState);
+ onReleaseShift(withSliding, autoCapsFlags, recapitalizeMode);
} else if (code == Constants.CODE_CAPSLOCK) {
setShiftLocked(!mAlphabetShiftState.isShiftLocked());
} else if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) {
- onReleaseSymbol(withSliding, currentAutoCapsState, currentRecapitalizeState);
+ onReleaseSymbol(withSliding, autoCapsFlags, recapitalizeMode);
}
}
- private void onPressSymbol(final int currentAutoCapsState,
- final int currentRecapitalizeState) {
- toggleAlphabetAndSymbols(currentAutoCapsState, currentRecapitalizeState);
+ private void onPressSymbol(final int autoCapsFlags,
+ final int recapitalizeMode) {
+ toggleAlphabetAndSymbols(autoCapsFlags, recapitalizeMode);
mSymbolKeyState.onPress();
mSwitchState = SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL;
}
- private void onReleaseSymbol(final boolean withSliding, final int currentAutoCapsState,
- final int currentRecapitalizeState) {
+ private void onReleaseSymbol(final boolean withSliding, final int autoCapsFlags,
+ final int recapitalizeMode) {
if (mSymbolKeyState.isChording()) {
// Switch back to the previous keyboard mode if the user chords the mode change key and
// another key, then releases the mode change key.
- toggleAlphabetAndSymbols(currentAutoCapsState, currentRecapitalizeState);
+ toggleAlphabetAndSymbols(autoCapsFlags, recapitalizeMode);
} else if (!withSliding) {
// If the mode change key is being released without sliding, we should forget the
// previous symbols keyboard shift state and simply switch back to symbols layout
@@ -419,23 +423,23 @@ public final class KeyboardState {
mSymbolKeyState.onRelease();
}
- public void onUpdateShiftState(final int autoCaps, final int recapitalizeMode) {
+ public void onUpdateShiftState(final int autoCapsFlags, final int recapitalizeMode) {
if (DEBUG_EVENT) {
- Log.d(TAG, "onUpdateShiftState: autoCaps=" + autoCaps + ", recapitalizeMode="
- + recapitalizeMode + " " + this);
+ Log.d(TAG, "onUpdateShiftState: " + stateToString(autoCapsFlags, recapitalizeMode));
}
mRecapitalizeMode = recapitalizeMode;
- updateAlphabetShiftState(autoCaps, recapitalizeMode);
+ updateAlphabetShiftState(autoCapsFlags, recapitalizeMode);
}
// TODO: Remove this method. Come up with a more comprehensive way to reset the keyboard layout
// when a keyboard layout set doesn't get reloaded in LatinIME.onStartInputViewInternal().
- public void onResetKeyboardStateToAlphabet(final int currentAutoCapsState,
- final int currentRecapitalizeState) {
+ public void onResetKeyboardStateToAlphabet(final int autoCapsFlags,
+ final int recapitalizeMode) {
if (DEBUG_EVENT) {
- Log.d(TAG, "onResetKeyboardStateToAlphabet: " + this);
+ Log.d(TAG, "onResetKeyboardStateToAlphabet: "
+ + stateToString(autoCapsFlags, recapitalizeMode));
}
- resetKeyboardStateToAlphabet(currentAutoCapsState, currentRecapitalizeState);
+ resetKeyboardStateToAlphabet(autoCapsFlags, recapitalizeMode);
}
private void updateShiftStateForRecapitalize(final int recapitalizeMode) {
@@ -453,7 +457,7 @@ public final class KeyboardState {
}
}
- private void updateAlphabetShiftState(final int autoCaps, final int recapitalizeMode) {
+ private void updateAlphabetShiftState(final int autoCapsFlags, final int recapitalizeMode) {
if (!mIsAlphabetMode) return;
if (RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE != recapitalizeMode) {
// We are recapitalizing. Match the keyboard to the current recapitalize state.
@@ -466,7 +470,7 @@ public final class KeyboardState {
return;
}
if (!mAlphabetShiftState.isShiftLocked() && !mShiftKeyState.isIgnoring()) {
- if (mShiftKeyState.isReleasing() && autoCaps != Constants.TextUtils.CAP_MODE_OFF) {
+ if (mShiftKeyState.isReleasing() && autoCapsFlags != Constants.TextUtils.CAP_MODE_OFF) {
// Only when shift key is releasing, automatic temporary upper case will be set.
setShifted(AUTOMATIC_SHIFT);
} else {
@@ -526,8 +530,8 @@ public final class KeyboardState {
}
}
- private void onReleaseShift(final boolean withSliding, final int currentAutoCapsState,
- final int currentRecapitalizeState) {
+ private void onReleaseShift(final boolean withSliding, final int autoCapsFlags,
+ final int recapitalizeMode) {
if (RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE != mRecapitalizeMode) {
// We are recapitalizing. We should match the keyboard state to the recapitalize
// state in priority.
@@ -550,8 +554,7 @@ public final class KeyboardState {
// After chording input, automatic shift state may have been changed depending on
// what characters were input.
mShiftKeyState.onRelease();
- mSwitchActions.requestUpdatingShiftState(currentAutoCapsState,
- currentRecapitalizeState);
+ mSwitchActions.requestUpdatingShiftState(autoCapsFlags, recapitalizeMode);
return;
} else if (mAlphabetShiftState.isShiftLockShifted() && withSliding) {
// In shift locked state, shift has been pressed and slid out to other key.
@@ -588,21 +591,20 @@ public final class KeyboardState {
mShiftKeyState.onRelease();
}
- public void onFinishSlidingInput(final int currentAutoCapsState,
- final int currentRecapitalizeState) {
+ public void onFinishSlidingInput(final int autoCapsFlags, final int recapitalizeMode) {
if (DEBUG_EVENT) {
- Log.d(TAG, "onFinishSlidingInput: " + this);
+ Log.d(TAG, "onFinishSlidingInput: " + stateToString(autoCapsFlags, recapitalizeMode));
}
// Switch back to the previous keyboard mode if the user cancels sliding input.
switch (mSwitchState) {
case SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL:
- toggleAlphabetAndSymbols(currentAutoCapsState, currentRecapitalizeState);
+ toggleAlphabetAndSymbols(autoCapsFlags, recapitalizeMode);
break;
case SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE:
toggleShiftInSymbols();
break;
case SWITCH_STATE_MOMENTARY_ALPHA_SHIFT:
- setAlphabetKeyboard(currentAutoCapsState, currentRecapitalizeState);
+ setAlphabetKeyboard(autoCapsFlags, recapitalizeMode);
break;
}
}
@@ -611,12 +613,11 @@ public final class KeyboardState {
return c == Constants.CODE_SPACE || c == Constants.CODE_ENTER;
}
- public void onEvent(final Event event, final int currentAutoCapsState,
- final int currentRecapitalizeState) {
+ public void onEvent(final Event event, final int autoCapsFlags, final int recapitalizeMode) {
final int code = event.isFunctionalKeyEvent() ? event.mKeyCode : event.mCodePoint;
if (DEBUG_EVENT) {
Log.d(TAG, "onEvent: code=" + Constants.printableCode(code)
- + " autoCaps=" + currentAutoCapsState + " " + this);
+ + " " + stateToString(autoCapsFlags, recapitalizeMode));
}
switch (mSwitchState) {
@@ -652,7 +653,7 @@ public final class KeyboardState {
// Switch back to alpha keyboard mode if user types one or more non-space/enter
// characters followed by a space/enter.
if (isSpaceOrEnter(code)) {
- toggleAlphabetAndSymbols(currentAutoCapsState, currentRecapitalizeState);
+ toggleAlphabetAndSymbols(autoCapsFlags, recapitalizeMode);
mPrevSymbolsKeyboardWasShifted = false;
}
break;
@@ -660,11 +661,11 @@ public final class KeyboardState {
// If the code is a letter, update keyboard shift state.
if (Constants.isLetterCode(code)) {
- updateAlphabetShiftState(currentAutoCapsState, currentRecapitalizeState);
+ updateAlphabetShiftState(autoCapsFlags, recapitalizeMode);
} else if (code == Constants.CODE_EMOJI) {
setEmojiKeyboard();
} else if (code == Constants.CODE_ALPHA_FROM_EMOJI) {
- setAlphabetKeyboard(currentAutoCapsState, currentRecapitalizeState);
+ setAlphabetKeyboard(autoCapsFlags, recapitalizeMode);
}
}
@@ -697,4 +698,9 @@ public final class KeyboardState {
+ " symbol=" + mSymbolKeyState
+ " switch=" + switchStateToString(mSwitchState) + "]";
}
+
+ private String stateToString(final int autoCapsFlags, final int recapitalizeMode) {
+ return this + " autoCapsFlags=" + CapsModeUtils.flagsToString(autoCapsFlags)
+ + " recapitalizeMode=" + RecapitalizeStatus.modeToString(recapitalizeMode);
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 8e9b5c6f6..b5d0b446f 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -21,8 +21,8 @@ import android.util.Log;
import android.util.SparseArray;
import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.common.ComposedData;
import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.common.InputPointers;
import com.android.inputmethod.latin.common.StringUtils;
@@ -262,8 +262,8 @@ public final class BinaryDictionary extends Dictionary {
}
@Override
- public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
- final NgramContext ngramContext, final ProximityInfo proximityInfo,
+ public ArrayList<SuggestedWordInfo> getSuggestions(final ComposedData composedData,
+ final NgramContext ngramContext, final long proximityInfoHandle,
final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int sessionId, final float weightForLocale,
final float[] inOutWeightOfLangModelVsSpatialModel) {
@@ -274,12 +274,13 @@ public final class BinaryDictionary extends Dictionary {
Arrays.fill(session.mInputCodePoints, Constants.NOT_A_CODE);
ngramContext.outputToArray(session.mPrevWordCodePointArrays,
session.mIsBeginningOfSentenceArray);
- final InputPointers inputPointers = composer.getInputPointers();
- final boolean isGesture = composer.isBatchMode();
+ final InputPointers inputPointers = composedData.mInputPointers;
+ final boolean isGesture = composedData.mIsBatchMode;
final int inputSize;
if (!isGesture) {
- inputSize = composer.copyCodePointsExceptTrailingSingleQuotesAndReturnCodePointCount(
- session.mInputCodePoints);
+ inputSize =
+ composedData.copyCodePointsExceptTrailingSingleQuotesAndReturnCodePointCount(
+ session.mInputCodePoints);
if (inputSize < 0) {
return null;
}
@@ -303,7 +304,7 @@ public final class BinaryDictionary extends Dictionary {
Dictionary.NOT_A_WEIGHT_OF_LANG_MODEL_VS_SPATIAL_MODEL;
}
// TOOD: Pass multiple previous words information for n-gram.
- getSuggestionsNative(mNativeDict, proximityInfo.getNativeProximityInfo(),
+ getSuggestionsNative(mNativeDict, proximityInfoHandle,
getTraverseSession(sessionId).getSession(), inputPointers.getXCoordinates(),
inputPointers.getYCoordinates(), inputPointers.getTimes(),
inputPointers.getPointerIds(), session.mInputCodePoints, inputSize,
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index 28a62b283..7d7ed77e7 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -17,8 +17,8 @@
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.common.ComposedData;
import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
import java.util.ArrayList;
@@ -87,9 +87,9 @@ public abstract class Dictionary {
/**
* Searches for suggestions for a given context.
- * @param composer the key sequence to match with coordinate info, as a WordComposer
+ * @param composedData the key sequence to match with coordinate info
* @param ngramContext the context for n-gram.
- * @param proximityInfo the object for key proximity. May be ignored by some implementations.
+ * @param proximityInfoHandle the handle for key proximity. Is ignored by some implementations.
* @param settingsValuesForSuggestion the settings values used for the suggestion.
* @param sessionId the session id.
* @param weightForLocale the weight given to this locale, to multiply the output scores for
@@ -99,8 +99,8 @@ public abstract class Dictionary {
* a float array that has only one element. This can be updated when a different value is used.
* @return the list of suggestions (possibly null if none)
*/
- abstract public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
- final NgramContext ngramContext, final ProximityInfo proximityInfo,
+ abstract public ArrayList<SuggestedWordInfo> getSuggestions(final ComposedData composedData,
+ final NgramContext ngramContext, final long proximityInfoHandle,
final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int sessionId, final float weightForLocale,
final float[] inOutWeightOfLangModelVsSpatialModel);
@@ -203,8 +203,8 @@ public abstract class Dictionary {
}
@Override
- public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
- final NgramContext ngramContext, final ProximityInfo proximityInfo,
+ public ArrayList<SuggestedWordInfo> getSuggestions(final ComposedData composedData,
+ final NgramContext ngramContext, final long proximityInfoHandle,
final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int sessionId, final float weightForLocale,
final float[] inOutWeightOfLangModelVsSpatialModel) {
diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
index a6d7205e2..96575f629 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
@@ -18,8 +18,8 @@ package com.android.inputmethod.latin;
import android.util.Log;
-import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.common.ComposedData;
import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
import java.util.ArrayList;
@@ -59,8 +59,8 @@ public final class DictionaryCollection extends Dictionary {
}
@Override
- public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
- final NgramContext ngramContext, final ProximityInfo proximityInfo,
+ public ArrayList<SuggestedWordInfo> getSuggestions(final ComposedData composedData,
+ final NgramContext ngramContext, final long proximityInfoHandle,
final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int sessionId, final float weightForLocale,
final float[] inOutWeightOfLangModelVsSpatialModel) {
@@ -68,15 +68,15 @@ public final class DictionaryCollection extends Dictionary {
if (dictionaries.isEmpty()) return null;
// To avoid creating unnecessary objects, we get the list out of the first
// dictionary and add the rest to it if not null, hence the get(0)
- ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getSuggestions(composer,
- ngramContext, proximityInfo, settingsValuesForSuggestion, sessionId,
+ ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getSuggestions(composedData,
+ ngramContext, proximityInfoHandle, settingsValuesForSuggestion, sessionId,
weightForLocale, inOutWeightOfLangModelVsSpatialModel);
if (null == suggestions) suggestions = new ArrayList<>();
final int length = dictionaries.size();
for (int i = 1; i < length; ++ i) {
- final ArrayList<SuggestedWordInfo> sugg = dictionaries.get(i).getSuggestions(composer,
- ngramContext, proximityInfo, settingsValuesForSuggestion, sessionId,
- weightForLocale, inOutWeightOfLangModelVsSpatialModel);
+ final ArrayList<SuggestedWordInfo> sugg = dictionaries.get(i).getSuggestions(
+ composedData, ngramContext, proximityInfoHandle, settingsValuesForSuggestion,
+ sessionId, weightForLocale, inOutWeightOfLangModelVsSpatialModel);
if (null != sugg) suggestions.addAll(sugg);
}
return suggestions;
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index 4a22cde7b..d23639a0d 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -23,7 +23,6 @@ import android.util.Pair;
import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.ExpandableBinaryDictionary.UpdateEntriesForInputEventsCallback;
import com.android.inputmethod.latin.NgramContext.WordInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
@@ -683,7 +682,7 @@ public class DictionaryFacilitator {
// TODO: Revise the way to fusion suggestion results.
public SuggestionResults getSuggestionResults(final WordComposer composer,
- final NgramContext ngramContext, final ProximityInfo proximityInfo,
+ final NgramContext ngramContext, final long proximityInfoHandle,
final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId) {
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
final SuggestionResults suggestionResults = new SuggestionResults(
@@ -698,8 +697,8 @@ public class DictionaryFacilitator {
? dictionaryGroup.mWeightForGesturingInLocale
: dictionaryGroup.mWeightForTypingInLocale;
final ArrayList<SuggestedWordInfo> dictionarySuggestions =
- dictionary.getSuggestions(composer, ngramContext, proximityInfo,
- settingsValuesForSuggestion, sessionId,
+ dictionary.getSuggestions(composer.getComposedDataSnapshot(), ngramContext,
+ proximityInfoHandle, settingsValuesForSuggestion, sessionId,
weightForLocale, weightOfLangModelVsSpatialModel);
if (null == dictionarySuggestions) continue;
suggestionResults.addAll(dictionarySuggestions);
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 702d1536a..b47eaa9bb 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -20,8 +20,8 @@ import android.content.Context;
import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.common.ComposedData;
import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.makedict.DictionaryHeader;
import com.android.inputmethod.latin.makedict.FormatSpec;
@@ -120,7 +120,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
private static boolean needsToMigrateDictionary(final int formatVersion) {
// When we bump up the dictionary format version, the old version should be added to here
// for supporting migration. Note that native code has to support reading such formats.
- return formatVersion == FormatSpec.VERSION4_ONLY_FOR_TESTING;
+ return formatVersion == FormatSpec.VERSION4_ONLY_FOR_TESTING
+ || formatVersion == FormatSpec.VERSION402;
}
public boolean isValidDictionaryLocked() {
@@ -480,8 +481,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
@Override
- public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
- final NgramContext ngramContext, final ProximityInfo proximityInfo,
+ public ArrayList<SuggestedWordInfo> getSuggestions(final ComposedData composedData,
+ final NgramContext ngramContext, final long proximityInfoHandle,
final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId,
final float weightForLocale, final float[] inOutWeightOfLangModelVsSpatialModel) {
reloadDictionaryIfRequired();
@@ -494,9 +495,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
return null;
}
final ArrayList<SuggestedWordInfo> suggestions =
- mBinaryDictionary.getSuggestions(composer, ngramContext, proximityInfo,
- settingsValuesForSuggestion, sessionId, weightForLocale,
- inOutWeightOfLangModelVsSpatialModel);
+ mBinaryDictionary.getSuggestions(composedData, ngramContext,
+ proximityInfoHandle, settingsValuesForSuggestion, sessionId,
+ weightForLocale, inOutWeightOfLangModelVsSpatialModel);
if (mBinaryDictionary.isCorrupted()) {
Log.i(TAG, "Dictionary (" + mDictName +") is corrupted. "
+ "Remove and regenerate it.");
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 3fa127005..cd09bf6c7 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1489,11 +1489,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
/**
- * To be called after the InputLogic has gotten a chance to act on the on-device decoding
- * for the full gesture, possibly updating the TextView to reflect the first decoding.
+ * To be called after the InputLogic has gotten a chance to act on the suggested words by the
+ * IME for the full gesture, possibly updating the TextView to reflect the first suggestion.
* <p>
* This method must be run on the UI Thread.
- * @param suggestedWords On-device decoding for the full gesture.
+ * @param suggestedWords suggested words by the IME for the full gesture.
*/
public void onTailBatchInputResultShown(final SuggestedWords suggestedWords) {
mGestureConsumer.onImeSuggestionsProcessed(suggestedWords,
diff --git a/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java
index bc8bd831c..7b1a53a6e 100644
--- a/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java
@@ -16,8 +16,8 @@
package com.android.inputmethod.latin;
-import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.common.ComposedData;
import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
import java.util.ArrayList;
@@ -50,16 +50,16 @@ public final class ReadOnlyBinaryDictionary extends Dictionary {
}
@Override
- public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
- final NgramContext ngramContext, final ProximityInfo proximityInfo,
+ public ArrayList<SuggestedWordInfo> getSuggestions(final ComposedData composedData,
+ final NgramContext ngramContext, final long proximityInfoHandle,
final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int sessionId, final float weightForLocale,
final float[] inOutWeightOfLangModelVsSpatialModel) {
if (mLock.readLock().tryLock()) {
try {
- return mBinaryDictionary.getSuggestions(composer, ngramContext, proximityInfo,
- settingsValuesForSuggestion, sessionId, weightForLocale,
- inOutWeightOfLangModelVsSpatialModel);
+ return mBinaryDictionary.getSuggestions(composedData, ngramContext,
+ proximityInfoHandle, settingsValuesForSuggestion, sessionId,
+ weightForLocale, inOutWeightOfLangModelVsSpatialModel);
} finally {
mLock.readLock().unlock();
}
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 430f765ea..9b4619d35 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -140,8 +140,8 @@ public final class Suggest {
: typedWord;
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
- wordComposer, ngramContext, proximityInfo, settingsValuesForSuggestion,
- SESSION_ID_TYPING);
+ wordComposer, ngramContext, proximityInfo.getNativeProximityInfo(),
+ settingsValuesForSuggestion, SESSION_ID_TYPING);
final ArrayList<SuggestedWordInfo> suggestionsContainer =
getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
trailingSingleQuotesCount,
@@ -247,8 +247,8 @@ public final class Suggest {
final int inputStyle, final int sequenceNumber,
final OnGetSuggestedWordsCallback callback) {
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
- wordComposer, ngramContext, proximityInfo, settingsValuesForSuggestion,
- SESSION_ID_GESTURE);
+ wordComposer, ngramContext, proximityInfo.getNativeProximityInfo(),
+ settingsValuesForSuggestion, SESSION_ID_GESTURE);
// For transforming words that don't come from a dictionary, because it's our best bet
final Locale defaultLocale = mDictionaryFacilitator.getMostProbableLocale();
final ArrayList<SuggestedWordInfo> suggestionsContainer =
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index 0b77f2ce3..fa55319d2 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -19,6 +19,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.common.ComposedData;
import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.common.InputPointers;
import com.android.inputmethod.latin.common.StringUtils;
@@ -90,6 +91,10 @@ public final class WordComposer {
refreshTypedWordCache();
}
+ public ComposedData getComposedDataSnapshot() {
+ return new ComposedData(getInputPointers(), isBatchMode(), mTypedWordCache.toString());
+ }
+
/**
* Restart the combiners, possibly with a new spec.
* @param combiningSpec The spec string for combining. This is found in the extra value.
@@ -134,38 +139,6 @@ public final class WordComposer {
return mCodePointSize;
}
- /**
- * Copy the code points in the typed word to a destination array of ints.
- *
- * If the array is too small to hold the code points in the typed word, nothing is copied and
- * -1 is returned.
- *
- * @param destination the array of ints.
- * @return the number of copied code points.
- */
- public int copyCodePointsExceptTrailingSingleQuotesAndReturnCodePointCount(
- final int[] destination) {
- // This method can be called on a separate thread and mTypedWordCache can change while we
- // are executing this method.
- final String typedWord = mTypedWordCache.toString();
- // lastIndex is exclusive
- final int lastIndex = typedWord.length()
- - StringUtils.getTrailingSingleQuotesCount(typedWord);
- if (lastIndex <= 0) {
- // The string is empty or contains only single quotes.
- return 0;
- }
-
- // The following function counts the number of code points in the text range which begins
- // at index 0 and extends to the character at lastIndex.
- final int codePointSize = Character.codePointCount(typedWord, 0, lastIndex);
- if (codePointSize > destination.length) {
- return -1;
- }
- return StringUtils.copyCodePointsAndReturnCodePointCount(destination, typedWord, 0,
- lastIndex, true /* downCase */);
- }
-
public boolean isSingleLetter() {
return size() == 1;
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index 78d79ae50..4ef504856 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -171,14 +171,18 @@ public final class FormatSpec {
// ExpandableDictionary.matchesExpectedBinaryDictFormatVersionForThisType().
public static final int VERSION2 = 2;
public static final int VERSION201 = 201;
+ public static final int VERSION202 = 202;
public static final int MINIMUM_SUPPORTED_VERSION_OF_CODE_POINT_TABLE = VERSION201;
// Dictionary version used for testing.
public static final int VERSION4_ONLY_FOR_TESTING = 399;
- public static final int VERSION401 = 401;
- public static final int VERSION4 = 402;
- public static final int VERSION4_DEV = 403;
- static final int MINIMUM_SUPPORTED_VERSION = VERSION2;
- static final int MAXIMUM_SUPPORTED_VERSION = VERSION4_DEV;
+ public static final int VERSION402 = 402;
+ public static final int VERSION403 = 403;
+ public static final int VERSION4 = VERSION403;
+ public static final int VERSION4_DEV = VERSION403;
+ static final int MINIMUM_SUPPORTED_STATIC_VERSION = VERSION202;
+ static final int MAXIMUM_SUPPORTED_STATIC_VERSION = VERSION202;
+ static final int MINIMUM_SUPPORTED_DYNAMIC_VERSION = VERSION4;
+ static final int MAXIMUM_SUPPORTED_DYNAMIC_VERSION = VERSION4_DEV;
// TODO: Make this value adaptative to content data, store it in the header, and
// use it in the reading code.
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
index 4985c2f08..6fffb8e9d 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
@@ -29,6 +29,8 @@ public final class DebugSettings {
public static final String PREF_FORCE_NON_DISTINCT_MULTITOUCH = "force_non_distinct_multitouch";
public static final String PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS =
"pref_has_custom_key_preview_animation_params";
+ public static final String PREF_RESIZE_KEYBOARD = "pref_resize_keyboard";
+ public static final String PREF_KEYBOARD_HEIGHT_SCALE = "pref_keyboard_height_scale";
public static final String PREF_KEY_PREVIEW_DISMISS_DURATION =
"pref_key_preview_dismiss_duration";
public static final String PREF_KEY_PREVIEW_DISMISS_END_X_SCALE =
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
index 2e5c3c479..068f56df1 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
@@ -89,6 +89,8 @@ public final class DebugSettingsFragment extends SubScreenFragment
defaultKeyPreviewDismissEndScale);
setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_Y_SCALE,
defaultKeyPreviewDismissEndScale);
+ setupKeyboardHeight(
+ DebugSettings.PREF_KEYBOARD_HEIGHT_SCALE, SettingsValues.DEFAULT_SIZE_SCALE);
mServiceNeedsRestart = false;
mDebugMode = (TwoStatePreference) findPreference(DebugSettings.PREF_DEBUG_MODE);
@@ -250,4 +252,51 @@ public final class DebugSettingsFragment extends SubScreenFragment
public void feedbackValue(final int value) {}
});
}
+
+ private void setupKeyboardHeight(final String prefKey, final float defaultValue) {
+ final SharedPreferences prefs = getSharedPreferences();
+ final SeekBarDialogPreference pref = (SeekBarDialogPreference)findPreference(prefKey);
+ if (pref == null) {
+ return;
+ }
+ pref.setInterface(new SeekBarDialogPreference.ValueProxy() {
+ private static final float PERCENTAGE_FLOAT = 100.0f;
+ private float getValueFromPercentage(final int percentage) {
+ return percentage / PERCENTAGE_FLOAT;
+ }
+
+ private int getPercentageFromValue(final float floatValue) {
+ return (int)(floatValue * PERCENTAGE_FLOAT);
+ }
+
+ @Override
+ public void writeValue(final int value, final String key) {
+ prefs.edit().putFloat(key, getValueFromPercentage(value)).apply();
+ }
+
+ @Override
+ public void writeDefaultValue(final String key) {
+ prefs.edit().remove(key).apply();
+ }
+
+ @Override
+ public int readValue(final String key) {
+ return getPercentageFromValue(
+ Settings.readKeyboardHeight(prefs, key, defaultValue));
+ }
+
+ @Override
+ public int readDefaultValue(final String key) {
+ return getPercentageFromValue(defaultValue);
+ }
+
+ @Override
+ public String getValueText(final int value) {
+ return String.format(Locale.ROOT, "%d%%", value);
+ }
+
+ @Override
+ public void feedbackValue(final int value) {}
+ });
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/settings/LocalSettingsConstants.java b/java/src/com/android/inputmethod/latin/settings/LocalSettingsConstants.java
index 0fd94b0f8..5c416ab18 100644
--- a/java/src/com/android/inputmethod/latin/settings/LocalSettingsConstants.java
+++ b/java/src/com/android/inputmethod/latin/settings/LocalSettingsConstants.java
@@ -47,12 +47,14 @@ public class LocalSettingsConstants {
DebugSettings.PREF_DEBUG_MODE,
DebugSettings.PREF_FORCE_NON_DISTINCT_MULTITOUCH,
DebugSettings.PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS,
+ DebugSettings.PREF_KEYBOARD_HEIGHT_SCALE,
DebugSettings.PREF_KEY_PREVIEW_DISMISS_DURATION,
DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_X_SCALE,
DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_Y_SCALE,
DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_DURATION,
DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_X_SCALE,
DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_START_Y_SCALE,
+ DebugSettings.PREF_RESIZE_KEYBOARD,
DebugSettings.PREF_SHOULD_SHOW_LXX_SUGGESTION_UI,
DebugSettings.PREF_SLIDING_KEY_INPUT_PREVIEW
};
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index 19db60655..16c053474 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -363,6 +363,12 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
return (milliseconds != UNDEFINED_PREFERENCE_VALUE_INT) ? milliseconds : defaultValue;
}
+ public static float readKeyboardHeight(final SharedPreferences prefs,
+ final String prefKey, final float defaultValue) {
+ final float percentage = prefs.getFloat(prefKey, UNDEFINED_PREFERENCE_VALUE_FLOAT);
+ return (percentage != UNDEFINED_PREFERENCE_VALUE_FLOAT) ? percentage : defaultValue;
+ }
+
public static boolean readUseFullscreenMode(final Resources res) {
return res.getBoolean(R.bool.config_use_fullscreen_mode);
}
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index bdb4e64e0..509b41fd3 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -50,6 +50,7 @@ public class SettingsValues {
private static final String FLOAT_MAX_VALUE_MARKER_STRING = "floatMaxValue";
private static final String FLOAT_NEGATIVE_INFINITY_MARKER_STRING = "floatNegativeInfinity";
private static final int TIMEOUT_TO_GET_TARGET_PACKAGE = 5; // seconds
+ public static final float DEFAULT_SIZE_SCALE = 1.0f; // 100%
// From resources:
public final SpacingAndPunctuations mSpacingAndPunctuations;
@@ -110,6 +111,8 @@ public class SettingsValues {
// Debug settings
public final boolean mIsInternal;
public final boolean mHasCustomKeyPreviewAnimationParams;
+ public final boolean mHasKeyboardResize;
+ public final float mKeyboardHeightScale;
public final int mKeyPreviewShowUpDuration;
public final int mKeyPreviewDismissDuration;
public final float mKeyPreviewShowUpStartXScale;
@@ -185,6 +188,9 @@ public class SettingsValues {
mIsInternal = Settings.isInternal(prefs);
mHasCustomKeyPreviewAnimationParams = prefs.getBoolean(
DebugSettings.PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS, false);
+ mHasKeyboardResize = prefs.getBoolean(DebugSettings.PREF_RESIZE_KEYBOARD, false);
+ mKeyboardHeightScale = Settings.readKeyboardHeight(
+ prefs, DebugSettings.PREF_KEYBOARD_HEIGHT_SCALE, DEFAULT_SIZE_SCALE);
mKeyPreviewShowUpDuration = Settings.readKeyPreviewAnimationDuration(
prefs, DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_DURATION,
res.getInteger(R.integer.config_key_preview_show_up_duration));
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 315e3696b..bcf7bbfdc 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -168,7 +168,8 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
DictionaryFacilitator dictionaryFacilitatorForLocale =
mDictionaryFacilitatorCache.get(locale);
return dictionaryFacilitatorForLocale.getSuggestionResults(composer, ngramContext,
- proximityInfo, mSettingsValuesForSuggestion, sessionId);
+ proximityInfo.getNativeProximityInfo(), mSettingsValuesForSuggestion,
+ sessionId);
} finally {
if (sessionId != null) {
mSessionIdPool.add(sessionId);
diff --git a/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
index 0db63fd9f..0dbc7c858 100644
--- a/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
@@ -24,6 +24,7 @@ import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.common.StringUtils;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
+import java.util.ArrayList;
import java.util.Locale;
public final class CapsModeUtils {
@@ -326,4 +327,31 @@ public final class CapsModeUtils {
// Here we arrived at the start of the line. This should behave exactly like whitespace.
return (START == state || LETTER == state) ? noCaps : caps;
}
+
+ /**
+ * Convert capitalize mode flags into human readable text.
+ *
+ * @param capsFlags The modes flags to be converted. It may be any combination of
+ * {@link TextUtils#CAP_MODE_CHARACTERS}, {@link TextUtils#CAP_MODE_WORDS}, and
+ * {@link TextUtils#CAP_MODE_SENTENCES}.
+ * @return the text that describe the <code>capsMode</code>.
+ */
+ public static String flagsToString(final int capsFlags) {
+ final int capsFlagsMask = TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS
+ | TextUtils.CAP_MODE_SENTENCES;
+ if ((capsFlags & ~capsFlagsMask) != 0) {
+ return "unknown<0x" + Integer.toHexString(capsFlags) + ">";
+ }
+ final ArrayList<String> builder = new ArrayList<>();
+ if ((capsFlags & android.text.TextUtils.CAP_MODE_CHARACTERS) != 0) {
+ builder.add("characters");
+ }
+ if ((capsFlags & android.text.TextUtils.CAP_MODE_WORDS) != 0) {
+ builder.add("words");
+ }
+ if ((capsFlags & android.text.TextUtils.CAP_MODE_SENTENCES) != 0) {
+ builder.add("sentences");
+ }
+ return builder.isEmpty() ? "none" : TextUtils.join("|", builder);
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java b/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
index f9839eb91..01f5e1079 100644
--- a/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
@@ -22,16 +22,27 @@ import java.util.Collection;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+/**
+ * Utility methods for working with collections.
+ */
public final class CollectionUtils {
private CollectionUtils() {
// This utility class is not publicly instantiable.
}
+ /**
+ * Converts a sub-range of the given array to an ArrayList of the appropriate type.
+ * @param array Array to be converted.
+ * @param start First index inclusive to be converted.
+ * @param end Last index exclusive to be converted.
+ * @throws IllegalArgumentException if start or end are out of range or start &gt; end.
+ */
@Nonnull
public static <E> ArrayList<E> arrayAsList(@Nonnull final E[] array, final int start,
final int end) {
if (start < 0 || start > end || end > array.length) {
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("Invalid start: " + start + " end: " + end
+ + " with array.length: " + array.length);
}
final ArrayList<E> list = new ArrayList<>(end - start);
diff --git a/java/src/com/android/inputmethod/latin/utils/CombinedFormatUtils.java b/java/src/com/android/inputmethod/latin/utils/CombinedFormatUtils.java
index 4e0f5f583..8699f2ce7 100644
--- a/java/src/com/android/inputmethod/latin/utils/CombinedFormatUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CombinedFormatUtils.java
@@ -36,7 +36,8 @@ public class CombinedFormatUtils {
public static final String WORD_TAG = "word";
public static final String BEGINNING_OF_SENTENCE_TAG = "beginning_of_sentence";
public static final String NOT_A_WORD_TAG = "not_a_word";
- public static final String BLACKLISTED_TAG = "blacklisted";
+ public static final String POSSIBLY_OFFENSIVE_TAG = "possibly_offensive";
+ public static final String TRUE_VALUE = "true";
public static String formatAttributeMap(final HashMap<String, String> attributeMap) {
final StringBuilder builder = new StringBuilder();
@@ -61,13 +62,13 @@ public class CombinedFormatUtils {
builder.append(",");
builder.append(formatProbabilityInfo(wordProperty.mProbabilityInfo));
if (wordProperty.mIsBeginningOfSentence) {
- builder.append("," + BEGINNING_OF_SENTENCE_TAG + "=true");
+ builder.append("," + BEGINNING_OF_SENTENCE_TAG + "=" + TRUE_VALUE);
}
if (wordProperty.mIsNotAWord) {
- builder.append("," + NOT_A_WORD_TAG + "=true");
+ builder.append("," + NOT_A_WORD_TAG + "=" + TRUE_VALUE);
}
if (wordProperty.mIsPossiblyOffensive) {
- builder.append("," + BLACKLISTED_TAG + "=true");
+ builder.append("," + POSSIBLY_OFFENSIVE_TAG + "=" + TRUE_VALUE);
}
builder.append("\n");
if (wordProperty.mHasShortcuts) {
@@ -111,4 +112,8 @@ public class CombinedFormatUtils {
}
return builder.toString();
}
+
+ public static boolean isLiteralTrue(final String value) {
+ return TRUE_VALUE.equalsIgnoreCase(value);
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java
index 56c8249bd..9c6a94810 100644
--- a/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java
@@ -250,8 +250,9 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr
composer.setComposingWord(codePoints, coordinates);
final SuggestionResults suggestionResults;
synchronized (mLock) {
- suggestionResults = dictionaryFacilitator.getSuggestionResults(
- composer, NgramContext.EMPTY_PREV_WORDS_INFO, keyboard.getProximityInfo(),
+ suggestionResults = dictionaryFacilitator.getSuggestionResults(composer,
+ NgramContext.EMPTY_PREV_WORDS_INFO,
+ keyboard.getProximityInfo().getNativeProximityInfo(),
settingsValuesForSuggestion, 0 /* sessionId */);
}
if (suggestionResults.isEmpty()) {
diff --git a/java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java b/java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java
index 21daddce7..a381649a4 100644
--- a/java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java
+++ b/java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java
@@ -51,6 +51,17 @@ public class RecapitalizeStatus {
}
}
+ public static String modeToString(final int recapitalizeMode) {
+ switch (recapitalizeMode) {
+ case NOT_A_RECAPITALIZE_MODE: return "undefined";
+ case CAPS_MODE_ORIGINAL_MIXED_CASE: return "mixedCase";
+ case CAPS_MODE_ALL_LOWER: return "allLower";
+ case CAPS_MODE_FIRST_WORD_UPPER: return "firstWordUpper";
+ case CAPS_MODE_ALL_UPPER: return "allUpper";
+ default: return "unknown<" + recapitalizeMode + ">";
+ }
+ }
+
/**
* We store the location of the cursor and the string that was there before the recapitalize
* action was done, and the location of the cursor and the string that was there after.
diff --git a/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java b/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java
index d1fc642f3..cc0d470df 100644
--- a/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java
@@ -26,6 +26,7 @@ import android.util.TypedValue;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.settings.SettingsValues;
import java.util.ArrayList;
import java.util.HashMap;
@@ -186,6 +187,15 @@ public final class ResourceUtils {
return dm.widthPixels;
}
+ public static int getKeyboardHeight(final Resources res, final SettingsValues settingsValues) {
+ final int defaultKeyboardHeight = getDefaultKeyboardHeight(res);
+ if (settingsValues.mHasKeyboardResize) {
+ // mKeyboardHeightScale Ranges from [.5,1.2], from xml/prefs_screen_debug.xml
+ return (int)(defaultKeyboardHeight * settingsValues.mKeyboardHeightScale);
+ }
+ return defaultKeyboardHeight;
+ }
+
public static int getDefaultKeyboardHeight(final Resources res) {
final DisplayMetrics dm = res.getDisplayMetrics();
final String keyboardHeightInDp = getDeviceOverrideValue(
diff --git a/native/dicttoolkit/Android.mk b/native/dicttoolkit/Android.mk
new file mode 100644
index 000000000..118682dfc
--- /dev/null
+++ b/native/dicttoolkit/Android.mk
@@ -0,0 +1,67 @@
+# 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.
+
+ifeq (,$(TARGET_BUILD_APPS))
+
+# Only build if it's explicitly requested, or running mm/mmm.
+ifneq ($(ONE_SHOT_MAKEFILE)$(filter $(MAKECMDGOALS),dicttoolkit),)
+
+# HACK: Temporarily disable host tool build on Mac until the build system is ready for C++11.
+LATINIME_HOST_OSNAME := $(shell uname -s)
+ifneq ($(LATINIME_HOST_OSNAME), Darwin) # TODO: Remove this
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LATIN_IME_CORE_PATH := $(LOCAL_PATH)/../jni
+
+LATIN_IME_DICT_TOOLKIT_SRC_DIR := src
+LATIN_IME_CORE_SRC_DIR := ../jni/src
+
+LOCAL_CFLAGS += -Werror -Wall -Wextra -Weffc++ -Wformat=2 -Wcast-qual -Wcast-align \
+ -Wwrite-strings -Wfloat-equal -Wpointer-arith -Winit-self -Wredundant-decls \
+ -Woverloaded-virtual -Wsign-promo -Wno-system-headers
+
+# To suppress compiler warnings for unused variables/functions used for debug features etc.
+LOCAL_CFLAGS += -Wno-unused-parameter -Wno-unused-function
+LOCAL_CFLAGS += -std=c++11 -Wno-unused-parameter -Wno-unused-function
+
+include $(LOCAL_PATH)/NativeFileList.mk
+include $(LATIN_IME_CORE_PATH)/NativeFileList.mk
+
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(LATIN_IME_DICT_TOOLKIT_SRC_DIR) \
+ $(LATIN_IME_CORE_PATH)/$(LATIN_IME_CORE_SRC_DIR)
+
+LOCAL_SRC_FILES := $(LATIN_IME_DICT_TOOLKIT_MAIN_SRC_FILES) \
+ $(addprefix $(LATIN_IME_DICT_TOOLKIT_SRC_DIR)/, $(LATIN_IME_DICT_TOOLKIT_SRC_FILES)) \
+ $(addprefix $(LATIN_IME_CORE_SRC_DIR)/, $(LATIN_IME_CORE_SRC_FILES))
+
+LOCAL_MODULE := dicttoolkit
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CLANG := true
+LOCAL_CXX_STL := libc++
+
+include $(BUILD_HOST_EXECUTABLE)
+#################### Clean up the tmp vars
+include $(LOCAL_PATH)/CleanupNativeFileList.mk
+#################### Unit test
+include $(LOCAL_PATH)/UnitTests.mk
+
+endif # Darwin - TODO: Remove this
+
+endif
+
+endif # TARGET_BUILD_APPS
diff --git a/native/dicttoolkit/CleanupNativeFileList.mk b/native/dicttoolkit/CleanupNativeFileList.mk
new file mode 100644
index 000000000..b804b41ed
--- /dev/null
+++ b/native/dicttoolkit/CleanupNativeFileList.mk
@@ -0,0 +1,17 @@
+# 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.
+
+LATIN_IME_DICT_TOOLKIT_MAIN_SRC_FILES :=
+LATIN_IME_DICT_TOOLKIT_SRC_FILES :=
+LATIN_IME_DICT_TOOLKIT_TEST_FILES :=
diff --git a/native/dicttoolkit/NativeFileList.mk b/native/dicttoolkit/NativeFileList.mk
new file mode 100644
index 000000000..b6be9c541
--- /dev/null
+++ b/native/dicttoolkit/NativeFileList.mk
@@ -0,0 +1,21 @@
+# 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.
+
+LATIN_IME_DICT_TOOLKIT_MAIN_SRC_FILES := \
+ dict_toolkit_main.cpp
+
+LATIN_IME_DICT_TOOLKIT_SRC_FILES :=
+
+LATIN_IME_DICT_TOOLKIT_TEST_FILES := \
+ dict_toolkit_defines_test.cpp
diff --git a/native/dicttoolkit/UnitTests.mk b/native/dicttoolkit/UnitTests.mk
new file mode 100644
index 000000000..d568db44a
--- /dev/null
+++ b/native/dicttoolkit/UnitTests.mk
@@ -0,0 +1,68 @@
+# 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.
+
+ifeq (,$(TARGET_BUILD_APPS))
+
+LOCAL_PATH := $(call my-dir)
+
+######################################
+include $(CLEAR_VARS)
+
+LATIN_IME_CORE_PATH := $(LOCAL_PATH)/../jni
+
+LATIN_IME_DICT_TOOLKIT_SRC_DIR := src
+LATIN_IME_CORE_SRC_DIR := ../jni/src
+LATIN_DICT_TOOLKIT_TEST_SRC_DIR := tests
+
+include $(LOCAL_PATH)/NativeFileList.mk
+include $(LATIN_IME_CORE_PATH)/NativeFileList.mk
+
+# TODO: Remove -std=c++11 once it is set by default on host build.
+LATIN_IME_SRC_DIR := src
+LOCAL_ADDRESS_SANITIZER := true
+LOCAL_CFLAGS += -std=c++11 -Wno-unused-parameter -Wno-unused-function
+LOCAL_CLANG := true
+LOCAL_CXX_STL := libc++
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(LATIN_IME_DICT_TOOLKIT_SRC_DIR) \
+ $(LATIN_IME_CORE_PATH)/$(LATIN_IME_CORE_SRC_DIR)
+LOCAL_MODULE := liblatinime_dicttoolkit_host_static_for_unittests
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := \
+ $(addprefix $(LATIN_IME_DICT_TOOLKIT_SRC_DIR)/, $(LATIN_IME_DICT_TOOLKIT_SRC_FILES)) \
+ $(addprefix $(LATIN_IME_CORE_SRC_DIR)/, $(LATIN_IME_CORE_SRC_FILES))
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+# TODO: Remove -std=c++11 once it is set by default on host build.
+LOCAL_CFLAGS += -std=c++11 -Wno-unused-parameter -Wno-unused-function
+LOCAL_CLANG := true
+LOCAL_CXX_STL := libc++
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(LATIN_IME_DICT_TOOLKIT_SRC_DIR) \
+ $(LATIN_IME_CORE_PATH)/$(LATIN_IME_CORE_SRC_DIR)
+LOCAL_MODULE := dicttoolkit_unittests
+LOCAL_MODULE_TAGS := tests
+LOCAL_SRC_FILES := \
+ $(addprefix $(LATIN_DICT_TOOLKIT_TEST_SRC_DIR)/, $(LATIN_IME_DICT_TOOLKIT_TEST_FILES))
+LOCAL_STATIC_LIBRARIES += liblatinime_dicttoolkit_host_static_for_unittests
+include $(BUILD_HOST_NATIVE_TEST)
+
+include $(LOCAL_PATH)/CleanupNativeFileList.mk
+
+#################### Clean up the tmp vars
+LATINIME_HOST_OSNAME :=
+LATIN_IME_SRC_DIR :=
+LATIN_IME_TEST_SRC_DIR :=
+
+endif # TARGET_BUILD_APPS
diff --git a/native/dicttoolkit/dict_toolkit_main.cpp b/native/dicttoolkit/dict_toolkit_main.cpp
new file mode 100644
index 000000000..d71b50eb4
--- /dev/null
+++ b/native/dicttoolkit/dict_toolkit_main.cpp
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+#include <cstdio>
+
+int main(int argc, char **argv) {
+ // TODO: Implement.
+ printf("%s\n", argv[0]);
+ return 0;
+}
diff --git a/native/dicttoolkit/run_tests.sh b/native/dicttoolkit/run_tests.sh
new file mode 100755
index 000000000..44c99c144
--- /dev/null
+++ b/native/dicttoolkit/run_tests.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# 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.
+
+# check script arguments
+if [[ $(type -t mmm) != function ]]; then
+if [[ ${BASH_SOURCE[0]} != $0 ]]; then return; else exit 1; fi
+fi
+
+# Host build is never supported in unbundled (NDK/tapas) build
+if [[ -n $TARGET_BUILD_APPS ]]; then
+ echo "Host build is never supported in tapas build." 1>&2
+ echo "Use lunch command instead." 1>&2
+ if [[ ${BASH_SOURCE[0]} != $0 ]]; then return; else exit 1; fi
+fi
+
+test_name=dicttoolkit_unittests
+
+pushd $PWD > /dev/null
+cd $(gettop)
+(mmm -j16 packages/inputmethods/LatinIME/native/dicttoolkit) || (make -j16 $test_name)
+$ANDROID_HOST_OUT/bin/$test_name
+popd > /dev/null
diff --git a/native/dicttoolkit/src/dict_toolkit_defines.h b/native/dicttoolkit/src/dict_toolkit_defines.h
new file mode 100644
index 000000000..2a2104e26
--- /dev/null
+++ b/native/dicttoolkit/src/dict_toolkit_defines.h
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+#ifndef LATINIME_DICT_TOOLKIT_DEFINES_H
+#define LATINIME_DICT_TOOLKIT_DEFINES_H
+
+#include "defines.h"
+
+#endif // LATINIME_DICT_TOOLKIT_DEFINES_H
diff --git a/native/dicttoolkit/tests/dict_toolkit_defines_test.cpp b/native/dicttoolkit/tests/dict_toolkit_defines_test.cpp
new file mode 100644
index 000000000..3445bd0c5
--- /dev/null
+++ b/native/dicttoolkit/tests/dict_toolkit_defines_test.cpp
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#include "dict_toolkit_defines.h"
+
+#include <gtest/gtest.h>
+
+namespace latinime {
+namespace dicttoolkit {
+namespace {
+
+// Initial trivial test case.
+TEST(DictToolkitDefinesTest, TestKeycodeSpace) {
+ EXPECT_EQ(' ', KEYCODE_SPACE);
+}
+
+} // namespace
+} // namespace dicttoolkit
+} // namespace latinime
diff --git a/native/jni/NativeFileList.mk b/native/jni/NativeFileList.mk
index ca40ba8a5..55bb68344 100644
--- a/native/jni/NativeFileList.mk
+++ b/native/jni/NativeFileList.mk
@@ -71,6 +71,7 @@ LATIN_IME_CORE_SRC_FILES := \
ver4_patricia_trie_writing_helper.cpp \
ver4_pt_node_array_reader.cpp) \
$(addprefix suggest/policyimpl/dictionary/structure/v4/content/, \
+ dynamic_language_model_probability_utils.cpp \
language_model_dict_content.cpp \
language_model_dict_content_global_counters.cpp \
shortcut_dict_content.cpp \
@@ -84,6 +85,7 @@ LATIN_IME_CORE_SRC_FILES := \
forgetting_curve_utils.cpp \
format_utils.cpp \
mmapped_buffer.cpp \
+ probability_utils.cpp \
sparse_table.cpp \
trie_map.cpp ) \
suggest/policyimpl/gesture/gesture_suggest_policy_factory.cpp \
@@ -135,6 +137,7 @@ LATIN_IME_CORE_TEST_FILES := \
suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer_test.cpp \
suggest/policyimpl/dictionary/utils/byte_array_utils_test.cpp \
suggest/policyimpl/dictionary/utils/format_utils_test.cpp \
+ suggest/policyimpl/dictionary/utils/probability_utils_test.cpp \
suggest/policyimpl/dictionary/utils/sparse_table_test.cpp \
suggest/policyimpl/dictionary/utils/trie_map_test.cpp \
suggest/policyimpl/utils/damerau_levenshtein_edit_distance_policy_test.cpp \
diff --git a/native/jni/src/suggest/core/dictionary/dictionary.cpp b/native/jni/src/suggest/core/dictionary/dictionary.cpp
index bfe17cc4c..6a5df9d95 100644
--- a/native/jni/src/suggest/core/dictionary/dictionary.cpp
+++ b/native/jni/src/suggest/core/dictionary/dictionary.cpp
@@ -81,6 +81,9 @@ void Dictionary::NgramListenerForPrediction::onVisitEntry(const int ngramProbabi
}
const WordAttributes wordAttributes = mDictStructurePolicy->getWordAttributesInContext(
mPrevWordIds, targetWordId, nullptr /* multiBigramMap */);
+ if (wordAttributes.getProbability() == NOT_A_PROBABILITY) {
+ return;
+ }
mSuggestionResults->addPrediction(targetWordCodePoints, codePointCount,
wordAttributes.getProbability());
}
diff --git a/native/jni/src/suggest/core/dictionary/error_type_utils.cpp b/native/jni/src/suggest/core/dictionary/error_type_utils.cpp
index 1e2494e92..8f07ce275 100644
--- a/native/jni/src/suggest/core/dictionary/error_type_utils.cpp
+++ b/native/jni/src/suggest/core/dictionary/error_type_utils.cpp
@@ -31,6 +31,7 @@ const ErrorTypeUtils::ErrorType ErrorTypeUtils::NEW_WORD = 0x100;
const ErrorTypeUtils::ErrorType ErrorTypeUtils::ERRORS_TREATED_AS_AN_EXACT_MATCH =
NOT_AN_ERROR | MATCH_WITH_WRONG_CASE | MATCH_WITH_MISSING_ACCENT | MATCH_WITH_DIGRAPH;
+const ErrorTypeUtils::ErrorType ErrorTypeUtils::ERRORS_TREATED_AS_A_PERFECT_MATCH = NOT_AN_ERROR;
const ErrorTypeUtils::ErrorType
ErrorTypeUtils::ERRORS_TREATED_AS_AN_EXACT_MATCH_WITH_INTENTIONAL_OMISSION =
diff --git a/native/jni/src/suggest/core/dictionary/error_type_utils.h b/native/jni/src/suggest/core/dictionary/error_type_utils.h
index fd1d5fcff..e92c509fa 100644
--- a/native/jni/src/suggest/core/dictionary/error_type_utils.h
+++ b/native/jni/src/suggest/core/dictionary/error_type_utils.h
@@ -52,6 +52,10 @@ class ErrorTypeUtils {
return (containedErrorTypes & ~ERRORS_TREATED_AS_AN_EXACT_MATCH) == 0;
}
+ static bool isPerfectMatch(const ErrorType containedErrorTypes) {
+ return (containedErrorTypes & ~ERRORS_TREATED_AS_A_PERFECT_MATCH) == 0;
+ }
+
static bool isExactMatchWithIntentionalOmission(const ErrorType containedErrorTypes) {
return (containedErrorTypes
& ~ERRORS_TREATED_AS_AN_EXACT_MATCH_WITH_INTENTIONAL_OMISSION) == 0;
@@ -73,6 +77,7 @@ class ErrorTypeUtils {
DISALLOW_IMPLICIT_CONSTRUCTORS(ErrorTypeUtils);
static const ErrorType ERRORS_TREATED_AS_AN_EXACT_MATCH;
+ static const ErrorType ERRORS_TREATED_AS_A_PERFECT_MATCH;
static const ErrorType ERRORS_TREATED_AS_AN_EXACT_MATCH_WITH_INTENTIONAL_OMISSION;
};
} // namespace latinime
diff --git a/native/jni/src/suggest/core/dictionary/ngram_listener.h b/native/jni/src/suggest/core/dictionary/ngram_listener.h
index e9b3c1aaf..2eb5e9fd1 100644
--- a/native/jni/src/suggest/core/dictionary/ngram_listener.h
+++ b/native/jni/src/suggest/core/dictionary/ngram_listener.h
@@ -26,6 +26,8 @@ namespace latinime {
*/
class NgramListener {
public:
+ // ngramProbability is always 0 for v403 decaying dictionary.
+ // TODO: Remove ngramProbability.
virtual void onVisitEntry(const int ngramProbability, const int targetWordId) = 0;
virtual ~NgramListener() {};
diff --git a/native/jni/src/suggest/core/dictionary/property/historical_info.h b/native/jni/src/suggest/core/dictionary/property/historical_info.h
index f9bd6fd8c..e5ce1ea25 100644
--- a/native/jni/src/suggest/core/dictionary/property/historical_info.h
+++ b/native/jni/src/suggest/core/dictionary/property/historical_info.h
@@ -38,6 +38,7 @@ class HistoricalInfo {
return mTimestamp;
}
+ // TODO: Remove
int getLevel() const {
return mLevel;
}
diff --git a/native/jni/src/suggest/core/policy/scoring.h b/native/jni/src/suggest/core/policy/scoring.h
index ce3684a1c..b9dda83ad 100644
--- a/native/jni/src/suggest/core/policy/scoring.h
+++ b/native/jni/src/suggest/core/policy/scoring.h
@@ -30,7 +30,7 @@ class Scoring {
public:
virtual int calculateFinalScore(const float compoundDistance, const int inputSize,
const ErrorTypeUtils::ErrorType containedErrorTypes, const bool forceCommit,
- const bool boostExactMatches) const = 0;
+ const bool boostExactMatches, const bool hasProbabilityZero) const = 0;
virtual void getMostProbableString(const DicTraverseSession *const traverseSession,
const float weightOfLangModelVsSpatialModel,
SuggestionResults *const outSuggestionResults) const = 0;
diff --git a/native/jni/src/suggest/core/result/suggestions_output_utils.cpp b/native/jni/src/suggest/core/result/suggestions_output_utils.cpp
index 3283f6deb..74db95953 100644
--- a/native/jni/src/suggest/core/result/suggestions_output_utils.cpp
+++ b/native/jni/src/suggest/core/result/suggestions_output_utils.cpp
@@ -76,6 +76,52 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
weightOfLangModelVsSpatialModelToOutputSuggestions, outSuggestionResults);
}
+/* static */ bool SuggestionsOutputUtils::shouldBlockWord(
+ const SuggestOptions *const suggestOptions, const DicNode *const terminalDicNode,
+ const WordAttributes wordAttributes, const bool isLastWord) {
+ const bool currentWordExactMatch =
+ ErrorTypeUtils::isExactMatch(terminalDicNode->getContainedErrorTypes());
+ // When we have to block offensive words, non-exact matched offensive words should not be
+ // output.
+ const bool shouldBlockOffensiveWords = suggestOptions->blockOffensiveWords();
+
+ const bool isBlockedOffensiveWord = shouldBlockOffensiveWords &&
+ wordAttributes.isPossiblyOffensive();
+
+ // This function is called in two situations:
+ //
+ // 1) At the end of a search, in which case terminalDicNode will point to the last DicNode
+ // of the search, and isLastWord will be true.
+ // "fuck"
+ // |
+ // \ terminalDicNode (isLastWord=true, currentWordExactMatch=true)
+ // In this case, if the current word is an exact match, we will always let the word
+ // through, even if the user is blocking offensive words (it's exactly what they typed!)
+ //
+ // 2) In the middle of the search, when we hit a terminal node, to decide whether or not
+ // to start a new search at root, to try to match the rest of the input. In this case,
+ // terminalDicNode will point to the terminal node we just hit, and isLastWord will be
+ // false.
+ // "fuckvthis"
+ // |
+ // \ terminalDicNode (isLastWord=false, currentWordExactMatch=true)
+ //
+ // In this case, we should NOT allow the match through (correcting "fuckthis" to "fuck this"
+ // when offensive words are blocked would be a bad idea).
+ //
+ // In the case of a multi-word correction where the offensive word is typed last (eg.
+ // for the input "allfuck"), this function will be called with isLastWord==true, but
+ // currentWordExactMatch==false. So we are OK in this case as well.
+ // "allfuck"
+ // |
+ // \ terminalDicNode (isLastWord=true, currentWordExactMatch=false)
+ if (isLastWord && currentWordExactMatch) {
+ return false;
+ } else {
+ return isBlockedOffensiveWord;
+ }
+}
+
/* static */ void SuggestionsOutputUtils::outputSuggestionsOfDicNode(
const Scoring *const scoringPolicy, DicTraverseSession *traverseSession,
const DicNode *const terminalDicNode, const float weightOfLangModelVsSpatialModel,
@@ -98,24 +144,16 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
const bool isExactMatchWithIntentionalOmission =
ErrorTypeUtils::isExactMatchWithIntentionalOmission(
terminalDicNode->getContainedErrorTypes());
- const bool isFirstCharUppercase = terminalDicNode->isFirstCharUppercase();
- // Heuristic: We exclude probability=0 first-char-uppercase words from exact match.
- // (e.g. "AMD" and "and")
- const bool isSafeExactMatch = isExactMatch
- && !(wordAttributes.isPossiblyOffensive() && isFirstCharUppercase);
const int outputTypeFlags =
(wordAttributes.isPossiblyOffensive() ? Dictionary::KIND_FLAG_POSSIBLY_OFFENSIVE : 0)
- | ((isSafeExactMatch && boostExactMatches) ? Dictionary::KIND_FLAG_EXACT_MATCH : 0)
+ | ((isExactMatch && boostExactMatches) ? Dictionary::KIND_FLAG_EXACT_MATCH : 0)
| (isExactMatchWithIntentionalOmission ?
Dictionary::KIND_FLAG_EXACT_MATCH_WITH_INTENTIONAL_OMISSION : 0);
-
// Entries that are blacklisted or do not represent a word should not be output.
const bool isValidWord = !(wordAttributes.isBlacklisted() || wordAttributes.isNotAWord());
- // When we have to block offensive words, non-exact matched offensive words should not be
- // output.
- const bool blockOffensiveWords = traverseSession->getSuggestOptions()->blockOffensiveWords();
- const bool isBlockedOffensiveWord = blockOffensiveWords && wordAttributes.isPossiblyOffensive()
- && !isSafeExactMatch;
+
+ const bool shouldBlockThisWord = shouldBlockWord(traverseSession->getSuggestOptions(),
+ terminalDicNode, wordAttributes, true /* isLastWord */);
// Increase output score of top typing suggestion to ensure autocorrection.
// TODO: Better integration with java side autocorrection logic.
@@ -123,11 +161,11 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
compoundDistance, traverseSession->getInputSize(),
terminalDicNode->getContainedErrorTypes(),
(forceCommitMultiWords && terminalDicNode->hasMultipleWords()),
- boostExactMatches);
+ boostExactMatches, wordAttributes.getProbability() == 0);
// Don't output invalid or blocked offensive words. However, we still need to submit their
// shortcuts if any.
- if (isValidWord && !isBlockedOffensiveWord) {
+ if (isValidWord && !shouldBlockThisWord) {
int codePoints[MAX_WORD_LENGTH];
terminalDicNode->outputResult(codePoints);
const int indexToPartialCommit = outputSecondWordFirstLetterInputIndex ?
diff --git a/native/jni/src/suggest/core/result/suggestions_output_utils.h b/native/jni/src/suggest/core/result/suggestions_output_utils.h
index bf8497828..eca1f78b2 100644
--- a/native/jni/src/suggest/core/result/suggestions_output_utils.h
+++ b/native/jni/src/suggest/core/result/suggestions_output_utils.h
@@ -18,6 +18,7 @@
#define LATINIME_SUGGESTIONS_OUTPUT_UTILS
#include "defines.h"
+#include "suggest/core/dictionary/word_attributes.h"
namespace latinime {
@@ -25,11 +26,19 @@ class BinaryDictionaryShortcutIterator;
class DicNode;
class DicTraverseSession;
class Scoring;
+class SuggestOptions;
class SuggestionResults;
class SuggestionsOutputUtils {
public:
/**
+ * Returns true if we should block the incoming word, in the context of the user's
+ * preferences to include or not include possibly offensive words
+ */
+ static bool shouldBlockWord(const SuggestOptions *const suggestOptions,
+ const DicNode *const terminalDicNode, const WordAttributes wordAttributes,
+ const bool isLastWord);
+ /**
* Outputs the final list of suggestions (i.e., terminal nodes).
*/
static void outputSuggestions(const Scoring *const scoringPolicy,
diff --git a/native/jni/src/suggest/core/suggest.cpp b/native/jni/src/suggest/core/suggest.cpp
index 68a36454e..c372d668b 100644
--- a/native/jni/src/suggest/core/suggest.cpp
+++ b/native/jni/src/suggest/core/suggest.cpp
@@ -416,6 +416,11 @@ void Suggest::createNextWordDicNode(DicTraverseSession *traverseSession, DicNode
traverseSession->getDictionaryStructurePolicy()->getWordAttributesInContext(
dicNode->getPrevWordIds(), dicNode->getWordId(),
traverseSession->getMultiBigramMap());
+ if (SuggestionsOutputUtils::shouldBlockWord(traverseSession->getSuggestOptions(),
+ dicNode, wordAttributes, false /* isLastWord */)) {
+ return;
+ }
+
if (!TRAVERSAL->isGoodToTraverseNextWord(dicNode, wordAttributes.getProbability())) {
return;
}
diff --git a/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h b/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h
index 44c2f443f..7a5acd7d5 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h
@@ -134,15 +134,17 @@ class HeaderPolicy : public DictionaryHeaderStructurePolicy {
// same so we use them for both here.
switch (mDictFormatVersion) {
case FormatUtils::VERSION_2:
- return FormatUtils::VERSION_2;
case FormatUtils::VERSION_201:
- return FormatUtils::VERSION_201;
+ AKLOGE("Dictionary versions 2 and 201 are incompatible with this version");
+ return FormatUtils::UNKNOWN_VERSION;
+ case FormatUtils::VERSION_202:
+ return FormatUtils::VERSION_202;
case FormatUtils::VERSION_4_ONLY_FOR_TESTING:
return FormatUtils::VERSION_4_ONLY_FOR_TESTING;
- case FormatUtils::VERSION_4:
- return FormatUtils::VERSION_4;
- case FormatUtils::VERSION_4_DEV:
- return FormatUtils::VERSION_4_DEV;
+ case FormatUtils::VERSION_402:
+ return FormatUtils::VERSION_402;
+ case FormatUtils::VERSION_403:
+ return FormatUtils::VERSION_403;
default:
return FormatUtils::UNKNOWN_VERSION;
}
@@ -245,7 +247,7 @@ class HeaderPolicy : public DictionaryHeaderStructurePolicy {
}
bool supportsBeginningOfSentence() const {
- return mDictFormatVersion >= FormatUtils::VERSION_4;
+ return mDictFormatVersion >= FormatUtils::VERSION_402;
}
const int *getCodePointTable() const {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.cpp
index 41a8b13b8..19ed0d468 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.cpp
@@ -111,11 +111,12 @@ typedef DictionaryHeaderStructurePolicy::AttributeMap AttributeMap;
switch (version) {
case FormatUtils::VERSION_2:
case FormatUtils::VERSION_201:
- // Version 2 or 201 dictionary writing is not supported.
+ case FormatUtils::VERSION_202:
+ // None of the static dictionaries (v2x) support writing
return false;
case FormatUtils::VERSION_4_ONLY_FOR_TESTING:
- case FormatUtils::VERSION_4:
- case FormatUtils::VERSION_4_DEV:
+ case FormatUtils::VERSION_402:
+ case FormatUtils::VERSION_403:
return buffer->writeUintAndAdvancePosition(version /* data */,
HEADER_DICTIONARY_VERSION_SIZE, writingPos);
default:
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/content/bigram_dict_content.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/content/bigram_dict_content.cpp
index 9e1adff70..15ac88319 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/content/bigram_dict_content.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/content/bigram_dict_content.cpp
@@ -65,6 +65,8 @@ const BigramEntry BigramDictContent::getBigramEntryAndAdvancePosition(
(encodedTargetTerminalId == Ver4DictConstants::INVALID_BIGRAM_TARGET_TERMINAL_ID) ?
Ver4DictConstants::NOT_A_TERMINAL_ID : encodedTargetTerminalId;
if (mHasHistoricalInfo) {
+ // Hack for better migration.
+ count += level;
const HistoricalInfo historicalInfo(timestamp, level, count);
return BigramEntry(hasNext, probability, &historicalInfo, targetTerminalId);
} else {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/content/probability_dict_content.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/content/probability_dict_content.cpp
index ef6166ffd..61ef4aa42 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/content/probability_dict_content.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/content/probability_dict_content.cpp
@@ -50,7 +50,8 @@ const ProbabilityEntry ProbabilityDictContent::getProbabilityEntry(const int ter
Ver4DictConstants::WORD_LEVEL_FIELD_SIZE, &entryPos);
const int count = buffer->readUintAndAdvancePosition(
Ver4DictConstants::WORD_COUNT_FIELD_SIZE, &entryPos);
- const HistoricalInfo historicalInfo(timestamp, level, count);
+ // Hack for better migration.
+ const HistoricalInfo historicalInfo(timestamp, level, count + level);
return ProbabilityEntry(flags, probability, &historicalInfo);
} else {
return ProbabilityEntry(flags, probability);
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 08e39ce43..9455222dd 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
@@ -140,7 +140,7 @@ const WordAttributes Ver4PatriciaTriePolicy::getWordAttributesInContext(
const WordAttributes Ver4PatriciaTriePolicy::getWordAttributes(const int probability,
const PtNodeParams &ptNodeParams) const {
- return WordAttributes(probability, ptNodeParams.isBlacklisted(), ptNodeParams.isNotAWord(),
+ return WordAttributes(probability, false /* isBlacklisted */, ptNodeParams.isNotAWord(),
ptNodeParams.getProbability() == 0);
}
@@ -164,7 +164,7 @@ int Ver4PatriciaTriePolicy::getProbabilityOfWord(const WordIdArrayView prevWordI
}
const int ptNodePos = getTerminalPtNodePosFromWordId(wordId);
const PtNodeParams ptNodeParams(mNodeReader.fetchPtNodeParamsInBufferFromPtNodePos(ptNodePos));
- if (ptNodeParams.isDeleted() || ptNodeParams.isBlacklisted() || ptNodeParams.isNotAWord()) {
+ if (ptNodeParams.isDeleted() || ptNodeParams.isNotAWord()) {
return NOT_A_PROBABILITY;
}
if (prevWordIds.empty()) {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.cpp
index 372c9e36f..9a9a21b6b 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.cpp
@@ -58,7 +58,7 @@ namespace latinime {
const DictionaryHeaderStructurePolicy::AttributeMap *const attributeMap) {
FormatUtils::FORMAT_VERSION dictFormatVersion = FormatUtils::getFormatVersion(formatVersion);
switch (dictFormatVersion) {
- case FormatUtils::VERSION_4: {
+ case FormatUtils::VERSION_402: {
return newPolicyForOnMemoryV4Dict<backward::v402::Ver4DictConstants,
backward::v402::Ver4DictBuffers,
backward::v402::Ver4DictBuffers::Ver4DictBuffersPtr,
@@ -66,7 +66,7 @@ namespace latinime {
dictFormatVersion, locale, attributeMap);
}
case FormatUtils::VERSION_4_ONLY_FOR_TESTING:
- case FormatUtils::VERSION_4_DEV: {
+ case FormatUtils::VERSION_403: {
return newPolicyForOnMemoryV4Dict<Ver4DictConstants, Ver4DictBuffers,
Ver4DictBuffers::Ver4DictBuffersPtr, Ver4PatriciaTriePolicy>(
dictFormatVersion, locale, attributeMap);
@@ -115,9 +115,10 @@ template<class DictConstants, class DictBuffers, class DictBuffersPtr, class Str
switch (formatVersion) {
case FormatUtils::VERSION_2:
case FormatUtils::VERSION_201:
- AKLOGE("Given path is a directory but the format is version 2 or 201. path: %s", path);
+ case FormatUtils::VERSION_202:
+ AKLOGE("Given path is a directory but the format is version 2xx. path: %s", path);
break;
- case FormatUtils::VERSION_4: {
+ case FormatUtils::VERSION_402: {
return newPolicyForV4Dict<backward::v402::Ver4DictConstants,
backward::v402::Ver4DictBuffers,
backward::v402::Ver4DictBuffers::Ver4DictBuffersPtr,
@@ -125,7 +126,7 @@ template<class DictConstants, class DictBuffers, class DictBuffersPtr, class Str
headerFilePath, formatVersion, std::move(mmappedBuffer));
}
case FormatUtils::VERSION_4_ONLY_FOR_TESTING:
- case FormatUtils::VERSION_4_DEV: {
+ case FormatUtils::VERSION_403: {
return newPolicyForV4Dict<Ver4DictConstants, Ver4DictBuffers,
Ver4DictBuffers::Ver4DictBuffersPtr, Ver4PatriciaTriePolicy>(
headerFilePath, formatVersion, std::move(mmappedBuffer));
@@ -177,11 +178,14 @@ template<class DictConstants, class DictBuffers, class DictBuffersPtr, class Str
switch (FormatUtils::detectFormatVersion(mmappedBuffer->getReadOnlyByteArrayView())) {
case FormatUtils::VERSION_2:
case FormatUtils::VERSION_201:
+ AKLOGE("Dictionary versions 2 and 201 are incompatible with this version");
+ break;
+ case FormatUtils::VERSION_202:
return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(
new PatriciaTriePolicy(std::move(mmappedBuffer)));
case FormatUtils::VERSION_4_ONLY_FOR_TESTING:
- case FormatUtils::VERSION_4:
- case FormatUtils::VERSION_4_DEV:
+ case FormatUtils::VERSION_402:
+ case FormatUtils::VERSION_403:
AKLOGE("Given path is a file but the format is version 4. path: %s", path);
break;
default:
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h
index 585e87a24..e52706e07 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h
@@ -144,17 +144,6 @@ class PtNodeParams {
return PatriciaTrieReadingUtils::isTerminal(mFlags);
}
- AK_FORCE_INLINE bool isBlacklisted() const {
- // Note: this method will be removed in the next change.
- // It is used in getProbabilityOfWord and getWordAttributes for both v402 and v403.
- // * getProbabilityOfWord will be changed to no longer return NOT_A_PROBABILITY
- // when isBlacklisted (i.e. to only check if isNotAWord or isDeleted)
- // * getWordAttributes will be changed to always return blacklisted=false and
- // isPossiblyOffensive according to the function below (instead of the current
- // behaviour of checking if the probability is zero)
- return PatriciaTrieReadingUtils::isPossiblyOffensive(mFlags);
- }
-
AK_FORCE_INLINE bool isPossiblyOffensive() const {
return PatriciaTrieReadingUtils::isPossiblyOffensive(mFlags);
}
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 66fd18a52..59873612a 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
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-
#include "suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h"
#include "defines.h"
@@ -317,8 +316,8 @@ const WordAttributes PatriciaTriePolicy::getWordAttributesInContext(
const WordAttributes PatriciaTriePolicy::getWordAttributes(const int probability,
const PtNodeParams &ptNodeParams) const {
- return WordAttributes(probability, ptNodeParams.isBlacklisted(), ptNodeParams.isNotAWord(),
- ptNodeParams.getProbability() == 0);
+ return WordAttributes(probability, false /* isBlacklisted */, ptNodeParams.isNotAWord(),
+ ptNodeParams.isPossiblyOffensive());
}
int PatriciaTriePolicy::getProbability(const int unigramProbability,
@@ -345,10 +344,9 @@ int PatriciaTriePolicy::getProbabilityOfWord(const WordIdArrayView prevWordIds,
const int ptNodePos = getTerminalPtNodePosFromWordId(wordId);
const PtNodeParams ptNodeParams =
mPtNodeReader.fetchPtNodeParamsInBufferFromPtNodePos(ptNodePos);
- if (ptNodeParams.isNotAWord() || ptNodeParams.isBlacklisted()) {
- // If this is not a word, or if it's a blacklisted entry, it should behave as
- // having no probability outside of the suggestion process (where it should be used
- // for shortcuts).
+ if (ptNodeParams.isNotAWord()) {
+ // If this is not a word, it should behave as having no probability outside of the
+ // suggestion process (where it should be used for shortcuts).
return NOT_A_PROBABILITY;
}
if (!prevWordIds.empty()) {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/dynamic_language_model_probability_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/dynamic_language_model_probability_utils.cpp
new file mode 100644
index 000000000..b0fbb3e72
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/dynamic_language_model_probability_utils.cpp
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#include "suggest/policyimpl/dictionary/structure/v4/content/dynamic_language_model_probability_utils.h"
+
+namespace latinime {
+
+// These counts are used to provide stable probabilities even if the user's input count is small.
+const int DynamicLanguageModelProbabilityUtils::ASSUMED_MIN_COUNT_FOR_UNIGRAMS = 8192;
+const int DynamicLanguageModelProbabilityUtils::ASSUMED_MIN_COUNT_FOR_BIGRAMS = 2;
+const int DynamicLanguageModelProbabilityUtils::ASSUMED_MIN_COUNT_FOR_TRIGRAMS = 2;
+
+// These are encoded backoff weights.
+// Note that we give positive value for trigrams that means the weight is more than 1.
+// TODO: Apply backoff for main dictionaries and quit giving a positive backoff weight.
+const int DynamicLanguageModelProbabilityUtils::ENCODED_BACKOFF_WEIGHT_FOR_UNIGRAMS = -32;
+const int DynamicLanguageModelProbabilityUtils::ENCODED_BACKOFF_WEIGHT_FOR_BIGRAMS = 0;
+const int DynamicLanguageModelProbabilityUtils::ENCODED_BACKOFF_WEIGHT_FOR_TRIGRAMS = 8;
+
+// This value is used to remove too old entries from the dictionary.
+const int DynamicLanguageModelProbabilityUtils::DURATION_TO_DISCARD_ENTRY_IN_SECONDS =
+ 300 * 24 * 60 * 60; // 300 days
+
+} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/dynamic_language_model_probability_utils.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/dynamic_language_model_probability_utils.h
new file mode 100644
index 000000000..88bc58fe8
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/dynamic_language_model_probability_utils.h
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+#ifndef LATINIME_DYNAMIC_LANGUAGE_MODEL_PROBABILITY_UTILS_H
+#define LATINIME_DYNAMIC_LANGUAGE_MODEL_PROBABILITY_UTILS_H
+
+#include <algorithm>
+
+#include "defines.h"
+#include "suggest/core/dictionary/property/historical_info.h"
+#include "utils/time_keeper.h"
+
+namespace latinime {
+
+class DynamicLanguageModelProbabilityUtils {
+ public:
+ static float computeRawProbabilityFromCounts(const int count, const int contextCount,
+ const int matchedWordCountInContext) {
+ int minCount = 0;
+ switch (matchedWordCountInContext) {
+ case 1:
+ minCount = ASSUMED_MIN_COUNT_FOR_UNIGRAMS;
+ break;
+ case 2:
+ minCount = ASSUMED_MIN_COUNT_FOR_BIGRAMS;
+ break;
+ case 3:
+ minCount = ASSUMED_MIN_COUNT_FOR_TRIGRAMS;
+ break;
+ default:
+ AKLOGE("computeRawProbabilityFromCounts is called with invalid "
+ "matchedWordCountInContext (%d).", matchedWordCountInContext);
+ ASSERT(false);
+ return 0.0f;
+ }
+ return static_cast<float>(count) / static_cast<float>(std::max(contextCount, minCount));
+ }
+
+ static float backoff(const int ngramProbability, const int matchedWordCountInContext) {
+ int probability = NOT_A_PROBABILITY;
+
+ switch (matchedWordCountInContext) {
+ case 1:
+ probability = ngramProbability + ENCODED_BACKOFF_WEIGHT_FOR_UNIGRAMS;
+ break;
+ case 2:
+ probability = ngramProbability + ENCODED_BACKOFF_WEIGHT_FOR_BIGRAMS;
+ break;
+ case 3:
+ probability = ngramProbability + ENCODED_BACKOFF_WEIGHT_FOR_TRIGRAMS;
+ break;
+ default:
+ AKLOGE("backoff is called with invalid matchedWordCountInContext (%d).",
+ matchedWordCountInContext);
+ ASSERT(false);
+ return NOT_A_PROBABILITY;
+ }
+ return std::min(std::max(probability, NOT_A_PROBABILITY), MAX_PROBABILITY);
+ }
+
+ static int getDecayedProbability(const int probability, const HistoricalInfo historicalInfo) {
+ const int elapsedTime = TimeKeeper::peekCurrentTime() - historicalInfo.getTimestamp();
+ if (elapsedTime < 0) {
+ AKLOGE("The elapsed time is negatime value. Timestamp overflow?");
+ return NOT_A_PROBABILITY;
+ }
+ // TODO: Improve this logic.
+ // We don't modify probability depending on the elapsed time.
+ return probability;
+ }
+
+ static int shouldRemoveEntryDuringGC(const HistoricalInfo historicalInfo) {
+ // TODO: Improve this logic.
+ const int elapsedTime = TimeKeeper::peekCurrentTime() - historicalInfo.getTimestamp();
+ return elapsedTime > DURATION_TO_DISCARD_ENTRY_IN_SECONDS;
+ }
+
+ static int getPriorityToPreventFromEviction(const HistoricalInfo historicalInfo) {
+ // TODO: Improve this logic.
+ // More recently input entries get higher priority.
+ return historicalInfo.getTimestamp();
+ }
+
+private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(DynamicLanguageModelProbabilityUtils);
+
+ static_assert(MAX_PREV_WORD_COUNT_FOR_N_GRAM <= 2, "Max supported Ngram is Trigram.");
+
+ static const int ASSUMED_MIN_COUNT_FOR_UNIGRAMS;
+ static const int ASSUMED_MIN_COUNT_FOR_BIGRAMS;
+ static const int ASSUMED_MIN_COUNT_FOR_TRIGRAMS;
+
+ static const int ENCODED_BACKOFF_WEIGHT_FOR_UNIGRAMS;
+ static const int ENCODED_BACKOFF_WEIGHT_FOR_BIGRAMS;
+ static const int ENCODED_BACKOFF_WEIGHT_FOR_TRIGRAMS;
+
+ static const int DURATION_TO_DISCARD_ENTRY_IN_SECONDS;
+};
+
+} // namespace latinime
+#endif /* LATINIME_DYNAMIC_LANGUAGE_MODEL_PROBABILITY_UTILS_H */
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp
index 05a3a6356..31b1ea696 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp
@@ -19,11 +19,11 @@
#include <algorithm>
#include <cstring>
-#include "suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h"
+#include "suggest/policyimpl/dictionary/structure/v4/content/dynamic_language_model_probability_utils.h"
+#include "suggest/policyimpl/dictionary/utils/probability_utils.h"
namespace latinime {
-const int LanguageModelDictContent::DUMMY_PROBABILITY_FOR_VALID_WORDS = 1;
const int LanguageModelDictContent::TRIE_MAP_BUFFER_INDEX = 0;
const int LanguageModelDictContent::GLOBAL_COUNTERS_BUFFER_INDEX = 1;
@@ -39,7 +39,8 @@ bool LanguageModelDictContent::runGC(
}
const WordAttributes LanguageModelDictContent::getWordAttributes(const WordIdArrayView prevWordIds,
- const int wordId, const HeaderPolicy *const headerPolicy) const {
+ const int wordId, const bool mustMatchAllPrevWords,
+ const HeaderPolicy *const headerPolicy) const {
int bitmapEntryIndices[MAX_PREV_WORD_COUNT_FOR_N_GRAM + 1];
bitmapEntryIndices[0] = mTrieMap.getRootBitmapEntryIndex();
int maxPrevWordCount = 0;
@@ -53,7 +54,15 @@ const WordAttributes LanguageModelDictContent::getWordAttributes(const WordIdArr
bitmapEntryIndices[i + 1] = nextBitmapEntryIndex;
}
+ const ProbabilityEntry unigramProbabilityEntry = getProbabilityEntry(wordId);
+ if (mHasHistoricalInfo && unigramProbabilityEntry.getHistoricalInfo()->getCount() == 0) {
+ // The word should be treated as a invalid word.
+ return WordAttributes();
+ }
for (int i = maxPrevWordCount; i >= 0; --i) {
+ if (mustMatchAllPrevWords && prevWordIds.size() > static_cast<size_t>(i)) {
+ break;
+ }
const TrieMap::Result result = mTrieMap.get(wordId, bitmapEntryIndices[i]);
if (!result.mIsValid) {
continue;
@@ -62,36 +71,39 @@ const WordAttributes LanguageModelDictContent::getWordAttributes(const WordIdArr
ProbabilityEntry::decode(result.mValue, mHasHistoricalInfo);
int probability = NOT_A_PROBABILITY;
if (mHasHistoricalInfo) {
- const int rawProbability = ForgettingCurveUtils::decodeProbability(
- probabilityEntry.getHistoricalInfo(), headerPolicy);
- if (rawProbability == NOT_A_PROBABILITY) {
- // The entry should not be treated as a valid entry.
- continue;
- }
+ const HistoricalInfo *const historicalInfo = probabilityEntry.getHistoricalInfo();
+ int contextCount = 0;
if (i == 0) {
// unigram
- probability = rawProbability;
+ contextCount = mGlobalCounters.getTotalCount();
} else {
const ProbabilityEntry prevWordProbabilityEntry = getNgramProbabilityEntry(
prevWordIds.skip(1 /* n */).limit(i - 1), prevWordIds[0]);
if (!prevWordProbabilityEntry.isValid()) {
continue;
}
- if (prevWordProbabilityEntry.representsBeginningOfSentence()) {
- probability = rawProbability;
- } else {
- const int prevWordRawProbability = ForgettingCurveUtils::decodeProbability(
- prevWordProbabilityEntry.getHistoricalInfo(), headerPolicy);
- probability = std::min(MAX_PROBABILITY - prevWordRawProbability
- + rawProbability, MAX_PROBABILITY);
+ if (prevWordProbabilityEntry.representsBeginningOfSentence()
+ && historicalInfo->getCount() == 1) {
+ // BoS ngram requires multiple contextCount.
+ continue;
}
+ contextCount = prevWordProbabilityEntry.getHistoricalInfo()->getCount();
}
+ const float rawProbability =
+ DynamicLanguageModelProbabilityUtils::computeRawProbabilityFromCounts(
+ historicalInfo->getCount(), contextCount, i + 1);
+ const int encodedRawProbability =
+ ProbabilityUtils::encodeRawProbability(rawProbability);
+ const int decayedProbability =
+ DynamicLanguageModelProbabilityUtils::getDecayedProbability(
+ encodedRawProbability, *historicalInfo);
+ probability = DynamicLanguageModelProbabilityUtils::backoff(
+ decayedProbability, i + 1 /* n */);
} else {
probability = probabilityEntry.getProbability();
}
// TODO: Some flags in unigramProbabilityEntry should be overwritten by flags in
// probabilityEntry.
- const ProbabilityEntry unigramProbabilityEntry = getProbabilityEntry(wordId);
return WordAttributes(probability, unigramProbabilityEntry.isBlacklisted(),
unigramProbabilityEntry.isNotAWord(),
unigramProbabilityEntry.isPossiblyOffensive());
@@ -167,7 +179,8 @@ void LanguageModelDictContent::exportAllNgramEntriesRelatedToWordInner(
ProbabilityEntry::decode(entry.value(), mHasHistoricalInfo);
if (probabilityEntry.isValid()) {
const WordAttributes wordAttributes = getWordAttributes(
- WordIdArrayView(*prevWordIds), wordId, headerPolicy);
+ WordIdArrayView(*prevWordIds), wordId, true /* mustMatchAllPrevWords */,
+ headerPolicy);
outBummpedFullEntryInfo->emplace_back(*prevWordIds, wordId,
wordAttributes, probabilityEntry);
}
@@ -231,7 +244,7 @@ bool LanguageModelDictContent::updateAllEntriesOnInputWord(const WordIdArrayView
return false;
}
mGlobalCounters.updateMaxValueOfCounters(
- updatedUnigramProbabilityEntry.getHistoricalInfo()->getCount());
+ updatedNgramProbabilityEntry.getHistoricalInfo()->getCount());
if (!originalNgramProbabilityEntry.isValid()) {
entryCountersToUpdate->incrementNgramCount(i + 2);
}
@@ -242,10 +255,9 @@ bool LanguageModelDictContent::updateAllEntriesOnInputWord(const WordIdArrayView
const ProbabilityEntry LanguageModelDictContent::createUpdatedEntryFrom(
const ProbabilityEntry &originalProbabilityEntry, const bool isValid,
const HistoricalInfo historicalInfo, const HeaderPolicy *const headerPolicy) const {
- const HistoricalInfo updatedHistoricalInfo = ForgettingCurveUtils::createUpdatedHistoricalInfo(
- originalProbabilityEntry.getHistoricalInfo(), isValid ?
- DUMMY_PROBABILITY_FOR_VALID_WORDS : NOT_A_PROBABILITY,
- &historicalInfo, headerPolicy);
+ const HistoricalInfo updatedHistoricalInfo = HistoricalInfo(historicalInfo.getTimestamp(),
+ 0 /* level */, originalProbabilityEntry.getHistoricalInfo()->getCount()
+ + historicalInfo.getCount());
if (originalProbabilityEntry.isValid()) {
return ProbabilityEntry(originalProbabilityEntry.getFlags(), &updatedHistoricalInfo);
} else {
@@ -311,7 +323,7 @@ int LanguageModelDictContent::getBitmapEntryIndex(const WordIdArrayView prevWord
bool LanguageModelDictContent::updateAllProbabilityEntriesForGCInner(const int bitmapEntryIndex,
const int prevWordCount, const HeaderPolicy *const headerPolicy,
- MutableEntryCounters *const outEntryCounters) {
+ const bool needsToHalveCounters, MutableEntryCounters *const outEntryCounters) {
for (const auto &entry : mTrieMap.getEntriesInSpecifiedLevel(bitmapEntryIndex)) {
if (prevWordCount > MAX_PREV_WORD_COUNT_FOR_N_GRAM) {
AKLOGE("Invalid prevWordCount. prevWordCount: %d, MAX_PREV_WORD_COUNT_FOR_N_GRAM: %d.",
@@ -328,33 +340,41 @@ bool LanguageModelDictContent::updateAllProbabilityEntriesForGCInner(const int b
}
continue;
}
- if (mHasHistoricalInfo && !probabilityEntry.representsBeginningOfSentence()
- && probabilityEntry.isValid()) {
- const HistoricalInfo historicalInfo = ForgettingCurveUtils::createHistoricalInfoToSave(
- probabilityEntry.getHistoricalInfo(), headerPolicy);
- if (ForgettingCurveUtils::needsToKeep(&historicalInfo, headerPolicy)) {
- // Update the entry.
- const ProbabilityEntry updatedEntry(probabilityEntry.getFlags(), &historicalInfo);
- if (!mTrieMap.put(entry.key(), updatedEntry.encode(mHasHistoricalInfo),
- bitmapEntryIndex)) {
- return false;
- }
- } else {
+ if (mHasHistoricalInfo && probabilityEntry.isValid()) {
+ const HistoricalInfo *originalHistoricalInfo = probabilityEntry.getHistoricalInfo();
+ if (DynamicLanguageModelProbabilityUtils::shouldRemoveEntryDuringGC(
+ *originalHistoricalInfo)) {
// Remove the entry.
if (!mTrieMap.remove(entry.key(), bitmapEntryIndex)) {
return false;
}
continue;
}
+ if (needsToHalveCounters) {
+ const int updatedCount = originalHistoricalInfo->getCount() / 2;
+ if (updatedCount == 0) {
+ // Remove the entry.
+ if (!mTrieMap.remove(entry.key(), bitmapEntryIndex)) {
+ return false;
+ }
+ continue;
+ }
+ const HistoricalInfo historicalInfoToSave(originalHistoricalInfo->getTimestamp(),
+ originalHistoricalInfo->getLevel(), updatedCount);
+ const ProbabilityEntry updatedEntry(probabilityEntry.getFlags(),
+ &historicalInfoToSave);
+ if (!mTrieMap.put(entry.key(), updatedEntry.encode(mHasHistoricalInfo),
+ bitmapEntryIndex)) {
+ return false;
+ }
+ }
}
- if (!probabilityEntry.representsBeginningOfSentence()) {
- outEntryCounters->incrementNgramCount(prevWordCount + 1);
- }
+ outEntryCounters->incrementNgramCount(prevWordCount + 1);
if (!entry.hasNextLevelMap()) {
continue;
}
if (!updateAllProbabilityEntriesForGCInner(entry.getNextLevelBitmapEntryIndex(),
- prevWordCount + 1, headerPolicy, outEntryCounters)) {
+ prevWordCount + 1, headerPolicy, needsToHalveCounters, outEntryCounters)) {
return false;
}
}
@@ -408,11 +428,11 @@ bool LanguageModelDictContent::getEntryInfo(const HeaderPolicy *const headerPoli
}
const ProbabilityEntry probabilityEntry =
ProbabilityEntry::decode(entry.value(), mHasHistoricalInfo);
- const int probability = (mHasHistoricalInfo) ?
- ForgettingCurveUtils::decodeProbability(probabilityEntry.getHistoricalInfo(),
- headerPolicy) : probabilityEntry.getProbability();
- outEntryInfo->emplace_back(probability,
- probabilityEntry.getHistoricalInfo()->getTimestamp(),
+ const int priority = mHasHistoricalInfo
+ ? DynamicLanguageModelProbabilityUtils::getPriorityToPreventFromEviction(
+ *probabilityEntry.getHistoricalInfo())
+ : probabilityEntry.getProbability();
+ outEntryInfo->emplace_back(priority, probabilityEntry.getHistoricalInfo()->getCount(),
entry.key(), targetLevel, prevWordIds->data());
}
return true;
@@ -420,11 +440,11 @@ bool LanguageModelDictContent::getEntryInfo(const HeaderPolicy *const headerPoli
bool LanguageModelDictContent::EntryInfoToTurncate::Comparator::operator()(
const EntryInfoToTurncate &left, const EntryInfoToTurncate &right) const {
- if (left.mProbability != right.mProbability) {
- return left.mProbability < right.mProbability;
+ if (left.mPriority != right.mPriority) {
+ return left.mPriority < right.mPriority;
}
- if (left.mTimestamp != right.mTimestamp) {
- return left.mTimestamp > right.mTimestamp;
+ if (left.mCount != right.mCount) {
+ return left.mCount < right.mCount;
}
if (left.mKey != right.mKey) {
return left.mKey < right.mKey;
@@ -441,10 +461,9 @@ bool LanguageModelDictContent::EntryInfoToTurncate::Comparator::operator()(
return false;
}
-LanguageModelDictContent::EntryInfoToTurncate::EntryInfoToTurncate(const int probability,
- const int timestamp, const int key, const int prevWordCount, const int *const prevWordIds)
- : mProbability(probability), mTimestamp(timestamp), mKey(key),
- mPrevWordCount(prevWordCount) {
+LanguageModelDictContent::EntryInfoToTurncate::EntryInfoToTurncate(const int priority,
+ const int count, const int key, const int prevWordCount, const int *const prevWordIds)
+ : mPriority(priority), mCount(count), mKey(key), mPrevWordCount(prevWordCount) {
memmove(mPrevWordIds, prevWordIds, mPrevWordCount * sizeof(mPrevWordIds[0]));
}
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h
index 5b92b96e3..9678c35f9 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h
@@ -151,13 +151,14 @@ class LanguageModelDictContent {
const LanguageModelDictContent *const originalContent);
const WordAttributes getWordAttributes(const WordIdArrayView prevWordIds, const int wordId,
- const HeaderPolicy *const headerPolicy) const;
+ const bool mustMatchAllPrevWords, const HeaderPolicy *const headerPolicy) const;
ProbabilityEntry getProbabilityEntry(const int wordId) const {
return getNgramProbabilityEntry(WordIdArrayView(), wordId);
}
bool setProbabilityEntry(const int wordId, const ProbabilityEntry *const probabilityEntry) {
+ mGlobalCounters.addToTotalCount(probabilityEntry->getHistoricalInfo()->getCount());
return setNgramProbabilityEntry(WordIdArrayView(), wordId, probabilityEntry);
}
@@ -180,8 +181,15 @@ class LanguageModelDictContent {
bool updateAllProbabilityEntriesForGC(const HeaderPolicy *const headerPolicy,
MutableEntryCounters *const outEntryCounters) {
- return updateAllProbabilityEntriesForGCInner(mTrieMap.getRootBitmapEntryIndex(),
- 0 /* prevWordCount */, headerPolicy, outEntryCounters);
+ if (!updateAllProbabilityEntriesForGCInner(mTrieMap.getRootBitmapEntryIndex(),
+ 0 /* prevWordCount */, headerPolicy, mGlobalCounters.needsToHalveCounters(),
+ outEntryCounters)) {
+ return false;
+ }
+ if (mGlobalCounters.needsToHalveCounters()) {
+ mGlobalCounters.halveCounters();
+ }
+ return true;
}
// entryCounts should be created by updateAllProbabilityEntries.
@@ -206,11 +214,12 @@ class LanguageModelDictContent {
DISALLOW_ASSIGNMENT_OPERATOR(Comparator);
};
- EntryInfoToTurncate(const int probability, const int timestamp, const int key,
+ EntryInfoToTurncate(const int priority, const int count, const int key,
const int prevWordCount, const int *const prevWordIds);
- int mProbability;
- int mTimestamp;
+ int mPriority;
+ // TODO: Remove.
+ int mCount;
int mKey;
int mPrevWordCount;
int mPrevWordIds[MAX_PREV_WORD_COUNT_FOR_N_GRAM + 1];
@@ -219,8 +228,6 @@ class LanguageModelDictContent {
DISALLOW_DEFAULT_CONSTRUCTOR(EntryInfoToTurncate);
};
- // TODO: Remove
- static const int DUMMY_PROBABILITY_FOR_VALID_WORDS;
static const int TRIE_MAP_BUFFER_INDEX;
static const int GLOBAL_COUNTERS_BUFFER_INDEX;
@@ -233,7 +240,8 @@ class LanguageModelDictContent {
int createAndGetBitmapEntryIndex(const WordIdArrayView prevWordIds);
int getBitmapEntryIndex(const WordIdArrayView prevWordIds) const;
bool updateAllProbabilityEntriesForGCInner(const int bitmapEntryIndex, const int prevWordCount,
- const HeaderPolicy *const headerPolicy, MutableEntryCounters *const outEntryCounters);
+ const HeaderPolicy *const headerPolicy, const bool needsToHalveCounters,
+ MutableEntryCounters *const outEntryCounters);
bool turncateEntriesInSpecifiedLevel(const HeaderPolicy *const headerPolicy,
const int maxEntryCount, const int targetLevel, int *const outEntryCount);
bool getEntryInfo(const HeaderPolicy *const headerPolicy, const int targetLevel,
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_global_counters.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_global_counters.h
index 9953aa425..283c2691a 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_global_counters.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_global_counters.h
@@ -63,6 +63,10 @@ class LanguageModelDictContentGlobalCounters {
mTotalCount += 1;
}
+ void addToTotalCount(const int count) {
+ mTotalCount += count;
+ }
+
void updateMaxValueOfCounters(const int count) {
mMaxValueOfCounters = std::max(count, mMaxValueOfCounters);
}
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/probability_entry.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/probability_entry.h
index f4d340f86..9c4ab18e4 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/probability_entry.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/probability_entry.h
@@ -105,7 +105,7 @@ class ProbabilityEntry {
encodedEntry = (encodedEntry << (Ver4DictConstants::WORD_LEVEL_FIELD_SIZE * CHAR_BIT))
| static_cast<uint8_t>(mHistoricalInfo.getLevel());
encodedEntry = (encodedEntry << (Ver4DictConstants::WORD_COUNT_FIELD_SIZE * CHAR_BIT))
- | static_cast<uint8_t>(mHistoricalInfo.getCount());
+ | static_cast<uint16_t>(mHistoricalInfo.getCount());
} else {
encodedEntry = (encodedEntry << (Ver4DictConstants::PROBABILITY_SIZE * CHAR_BIT))
| static_cast<uint8_t>(mProbability);
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.cpp
index eb6080a24..bd89b8da7 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.cpp
@@ -49,8 +49,8 @@ const int Ver4DictConstants::TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE = 3;
const int Ver4DictConstants::NOT_A_TERMINAL_ADDRESS = 0;
const int Ver4DictConstants::TERMINAL_ID_FIELD_SIZE = 4;
const int Ver4DictConstants::TIME_STAMP_FIELD_SIZE = 4;
-const int Ver4DictConstants::WORD_LEVEL_FIELD_SIZE = 1;
-const int Ver4DictConstants::WORD_COUNT_FIELD_SIZE = 1;
+const int Ver4DictConstants::WORD_LEVEL_FIELD_SIZE = 0;
+const int Ver4DictConstants::WORD_COUNT_FIELD_SIZE = 2;
const uint8_t Ver4DictConstants::FLAG_REPRESENTS_BEGINNING_OF_SENTENCE = 0x1;
const uint8_t Ver4DictConstants::FLAG_NOT_A_VALID_ENTRY = 0x2;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h
index 600b5ffe4..13d7a5714 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_constants.h
@@ -47,6 +47,7 @@ class Ver4DictConstants {
static const int NOT_A_TERMINAL_ADDRESS;
static const int TERMINAL_ID_FIELD_SIZE;
static const int TIME_STAMP_FIELD_SIZE;
+ // TODO: Remove
static const int WORD_LEVEL_FIELD_SIZE;
static const int WORD_COUNT_FIELD_SIZE;
// Flags in probability entry.
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 d3de322f9..1992d4a5a 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
@@ -110,7 +110,7 @@ const WordAttributes Ver4PatriciaTriePolicy::getWordAttributesInContext(
return WordAttributes();
}
return mBuffers->getLanguageModelDictContent()->getWordAttributes(prevWordIds, wordId,
- mHeaderPolicy);
+ false /* mustMatchAllPrevWords */, mHeaderPolicy);
}
int Ver4PatriciaTriePolicy::getProbabilityOfWord(const WordIdArrayView prevWordIds,
@@ -118,18 +118,13 @@ int Ver4PatriciaTriePolicy::getProbabilityOfWord(const WordIdArrayView prevWordI
if (wordId == NOT_A_WORD_ID || prevWordIds.contains(NOT_A_WORD_ID)) {
return NOT_A_PROBABILITY;
}
- const ProbabilityEntry probabilityEntry =
- mBuffers->getLanguageModelDictContent()->getNgramProbabilityEntry(prevWordIds, wordId);
- if (!probabilityEntry.isValid() || probabilityEntry.isBlacklisted()
- || probabilityEntry.isNotAWord()) {
+ const WordAttributes wordAttributes =
+ mBuffers->getLanguageModelDictContent()->getWordAttributes(prevWordIds, wordId,
+ true /* mustMatchAllPrevWords */, mHeaderPolicy);
+ if (wordAttributes.isBlacklisted() || wordAttributes.isNotAWord()) {
return NOT_A_PROBABILITY;
}
- if (mHeaderPolicy->hasHistoricalInfoOfWords()) {
- return ForgettingCurveUtils::decodeProbability(probabilityEntry.getHistoricalInfo(),
- mHeaderPolicy);
- } else {
- return probabilityEntry.getProbability();
- }
+ return wordAttributes.getProbability();
}
BinaryDictionaryShortcutIterator Ver4PatriciaTriePolicy::getShortcutIterator(
@@ -151,10 +146,16 @@ void Ver4PatriciaTriePolicy::iterateNgramEntries(const WordIdArrayView prevWordI
if (!probabilityEntry.isValid()) {
continue;
}
- const int probability = probabilityEntry.hasHistoricalInfo() ?
- ForgettingCurveUtils::decodeProbability(
- probabilityEntry.getHistoricalInfo(), mHeaderPolicy) :
- probabilityEntry.getProbability();
+ int probability = NOT_A_PROBABILITY;
+ if (probabilityEntry.hasHistoricalInfo()) {
+ // TODO: Quit checking count here.
+ // If count <= 1, the word can be an invaild word. The actual probability should
+ // be checked using getWordAttributesInContext() in onVisitEntry().
+ probability = probabilityEntry.getHistoricalInfo()->getCount() <= 1 ?
+ NOT_A_PROBABILITY : 0;
+ } else {
+ probability = probabilityEntry.getProbability();
+ }
listener->onVisitEntry(probability, entry.getWordId());
}
}
@@ -386,25 +387,35 @@ bool Ver4PatriciaTriePolicy::updateEntriesForWordWithNgramContext(
AKLOGE("Cannot add unigarm entry in updateEntriesForWordWithNgramContext().");
return false;
}
+ if (!isValidWord) {
+ return true;
+ }
wordId = getWordId(wordCodePoints, false /* tryLowerCaseSearch */);
}
WordIdArray<MAX_PREV_WORD_COUNT_FOR_N_GRAM> prevWordIdArray;
const WordIdArrayView prevWordIds = ngramContext->getPrevWordIds(this, &prevWordIdArray,
false /* tryLowerCaseSearch */);
- if (prevWordIds.firstOrDefault(NOT_A_WORD_ID) == NOT_A_WORD_ID
- && ngramContext->isNthPrevWordBeginningOfSentence(1 /* n */)) {
- const UnigramProperty beginningOfSentenceUnigramProperty(
- true /* representsBeginningOfSentence */,
- true /* isNotAWord */, false /* isPossiblyOffensive */, NOT_A_PROBABILITY,
- HistoricalInfo(historicalInfo.getTimestamp(), 0 /* level */, 0 /* count */));
- if (!addUnigramEntry(ngramContext->getNthPrevWordCodePoints(1 /* n */),
- &beginningOfSentenceUnigramProperty)) {
- AKLOGE("Cannot add BoS entry in updateEntriesForWordWithNgramContext().");
+ if (ngramContext->isNthPrevWordBeginningOfSentence(1 /* n */)) {
+ if (prevWordIds.firstOrDefault(NOT_A_WORD_ID) == NOT_A_WORD_ID) {
+ const UnigramProperty beginningOfSentenceUnigramProperty(
+ true /* representsBeginningOfSentence */,
+ true /* isNotAWord */, false /* isPossiblyOffensive */, NOT_A_PROBABILITY,
+ HistoricalInfo(historicalInfo.getTimestamp(), 0 /* level */, 0 /* count */));
+ if (!addUnigramEntry(ngramContext->getNthPrevWordCodePoints(1 /* n */),
+ &beginningOfSentenceUnigramProperty)) {
+ AKLOGE("Cannot add BoS entry in updateEntriesForWordWithNgramContext().");
+ return false;
+ }
+ // Refresh word ids.
+ ngramContext->getPrevWordIds(this, &prevWordIdArray, false /* tryLowerCaseSearch */);
+ }
+ // Update entries for beginning of sentence.
+ if (!mBuffers->getMutableLanguageModelDictContent()->updateAllEntriesOnInputWord(
+ prevWordIds.skip(1 /* n */), prevWordIds[0], true /* isVaild */, historicalInfo,
+ mHeaderPolicy, &mEntryCounters)) {
return false;
}
- // Refresh word ids.
- ngramContext->getPrevWordIds(this, &prevWordIdArray, false /* tryLowerCaseSearch */);
}
if (!mBuffers->getMutableLanguageModelDictContent()->updateAllEntriesOnInputWord(prevWordIds,
wordId, updateAsAValidWord, historicalInfo, mHeaderPolicy, &mEntryCounters)) {
@@ -542,7 +553,7 @@ const WordProperty Ver4PatriciaTriePolicy::getWordProperty(
}
}
const WordAttributes wordAttributes = languageModelDictContent->getWordAttributes(
- WordIdArrayView(), wordId, mHeaderPolicy);
+ WordIdArrayView(), wordId, true /* mustMatchAllPrevWords */, mHeaderPolicy);
const ProbabilityEntry probabilityEntry = languageModelDictContent->getProbabilityEntry(wordId);
const HistoricalInfo *const historicalInfo = probabilityEntry.getHistoricalInfo();
const UnigramProperty unigramProperty(probabilityEntry.representsBeginningOfSentence(),
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.cpp
index 9d8e86675..edcb43678 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.cpp
@@ -44,13 +44,13 @@ const int DictFileWritingUtils::SIZE_OF_BUFFER_SIZE_FIELD = 4;
TimeKeeper::setCurrentTime();
const FormatUtils::FORMAT_VERSION formatVersion = FormatUtils::getFormatVersion(dictVersion);
switch (formatVersion) {
- case FormatUtils::VERSION_4:
+ case FormatUtils::VERSION_402:
return createEmptyV4DictFile<backward::v402::Ver4DictConstants,
backward::v402::Ver4DictBuffers,
backward::v402::Ver4DictBuffers::Ver4DictBuffersPtr>(
filePath, localeAsCodePointVector, attributeMap, formatVersion);
case FormatUtils::VERSION_4_ONLY_FOR_TESTING:
- case FormatUtils::VERSION_4_DEV:
+ case FormatUtils::VERSION_403:
return createEmptyV4DictFile<Ver4DictConstants, Ver4DictBuffers,
Ver4DictBuffers::Ver4DictBuffersPtr>(
filePath, localeAsCodePointVector, attributeMap, formatVersion);
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.cpp
index 0cffe569d..e225c235e 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.cpp
@@ -28,15 +28,17 @@ const size_t FormatUtils::DICTIONARY_MINIMUM_SIZE = 12;
/* static */ FormatUtils::FORMAT_VERSION FormatUtils::getFormatVersion(const int formatVersion) {
switch (formatVersion) {
case VERSION_2:
- return VERSION_2;
case VERSION_201:
- return VERSION_201;
+ AKLOGE("Dictionary versions 2 and 201 are incompatible with this version");
+ return UNKNOWN_VERSION;
+ case VERSION_202:
+ return VERSION_202;
case VERSION_4_ONLY_FOR_TESTING:
return VERSION_4_ONLY_FOR_TESTING;
- case VERSION_4:
- return VERSION_4;
- case VERSION_4_DEV:
- return VERSION_4_DEV;
+ case VERSION_402:
+ return VERSION_402;
+ case VERSION_403:
+ return VERSION_403;
default:
return UNKNOWN_VERSION;
}
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.h b/native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.h
index 96310086b..1616efcce 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/format_utils.h
@@ -31,11 +31,15 @@ class FormatUtils {
public:
enum FORMAT_VERSION {
// These MUST have the same values as the relevant constants in FormatSpec.java.
+ // TODO: Remove VERSION_2 and VERSION_201 when we:
+ // * Confirm that old versions of LatinIME download old-format dictionaries
+ // * We no longer need the corresponding constants on the Java side for dicttool
VERSION_2 = 2,
VERSION_201 = 201,
+ VERSION_202 = 202,
VERSION_4_ONLY_FOR_TESTING = 399,
- VERSION_4 = 402,
- VERSION_4_DEV = 403,
+ VERSION_402 = 402,
+ VERSION_403 = 403,
UNKNOWN_VERSION = -1
};
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/probability_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/utils/probability_utils.cpp
new file mode 100644
index 000000000..e8fa06942
--- /dev/null
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/probability_utils.cpp
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+#include "suggest/policyimpl/dictionary/utils/probability_utils.h"
+
+namespace latinime {
+
+const float ProbabilityUtils::PROBABILITY_ENCODING_SCALER = 8.58923700372f;
+
+} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/probability_utils.h b/native/jni/src/suggest/policyimpl/dictionary/utils/probability_utils.h
index 3b339e61a..2050af1e9 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/probability_utils.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/probability_utils.h
@@ -17,6 +17,9 @@
#ifndef LATINIME_PROBABILITY_UTILS_H
#define LATINIME_PROBABILITY_UTILS_H
+#include <algorithm>
+#include <cmath>
+
#include "defines.h"
namespace latinime {
@@ -47,8 +50,20 @@ class ProbabilityUtils {
+ static_cast<int>(static_cast<float>(bigramProbability + 1) * stepSize);
}
+ // Encode probability using the same way as we are doing for main dictionaries.
+ static AK_FORCE_INLINE int encodeRawProbability(const float rawProbability) {
+ const float probability = static_cast<float>(MAX_PROBABILITY)
+ + log2f(rawProbability) * PROBABILITY_ENCODING_SCALER;
+ if (probability < 0.0f) {
+ return 0;
+ }
+ return std::min(static_cast<int>(probability + 0.5f), MAX_PROBABILITY);
+ }
+
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ProbabilityUtils);
+
+ static const float PROBABILITY_ENCODING_SCALER;
};
}
#endif /* LATINIME_PROBABILITY_UTILS_H */
diff --git a/native/jni/src/suggest/policyimpl/typing/scoring_params.cpp b/native/jni/src/suggest/policyimpl/typing/scoring_params.cpp
index a6f9a8b23..856808a74 100644
--- a/native/jni/src/suggest/policyimpl/typing/scoring_params.cpp
+++ b/native/jni/src/suggest/policyimpl/typing/scoring_params.cpp
@@ -24,6 +24,7 @@ const int ScoringParams::THRESHOLD_NEXT_WORD_PROBABILITY_FOR_CAPPED = 120;
const float ScoringParams::AUTOCORRECT_OUTPUT_THRESHOLD = 1.0f;
const float ScoringParams::EXACT_MATCH_PROMOTION = 1.1f;
+const float ScoringParams::PERFECT_MATCH_PROMOTION = 1.1f;
const float ScoringParams::CASE_ERROR_PENALTY_FOR_EXACT_MATCH = 0.01f;
const float ScoringParams::ACCENT_ERROR_PENALTY_FOR_EXACT_MATCH = 0.02f;
const float ScoringParams::DIGRAPH_PENALTY_FOR_EXACT_MATCH = 0.03f;
diff --git a/native/jni/src/suggest/policyimpl/typing/scoring_params.h b/native/jni/src/suggest/policyimpl/typing/scoring_params.h
index b8f889559..6f327a370 100644
--- a/native/jni/src/suggest/policyimpl/typing/scoring_params.h
+++ b/native/jni/src/suggest/policyimpl/typing/scoring_params.h
@@ -34,6 +34,7 @@ class ScoringParams {
static const int THRESHOLD_SHORT_WORD_LENGTH;
static const float EXACT_MATCH_PROMOTION;
+ static const float PERFECT_MATCH_PROMOTION;
static const float CASE_ERROR_PENALTY_FOR_EXACT_MATCH;
static const float ACCENT_ERROR_PENALTY_FOR_EXACT_MATCH;
static const float DIGRAPH_PENALTY_FOR_EXACT_MATCH;
diff --git a/native/jni/src/suggest/policyimpl/typing/typing_scoring.h b/native/jni/src/suggest/policyimpl/typing/typing_scoring.h
index 0240bcf54..6acd767ea 100644
--- a/native/jni/src/suggest/policyimpl/typing/typing_scoring.h
+++ b/native/jni/src/suggest/policyimpl/typing/typing_scoring.h
@@ -44,23 +44,50 @@ class TypingScoring : public Scoring {
AK_FORCE_INLINE int calculateFinalScore(const float compoundDistance, const int inputSize,
const ErrorTypeUtils::ErrorType containedErrorTypes, const bool forceCommit,
- const bool boostExactMatches) const {
+ const bool boostExactMatches, const bool hasProbabilityZero) const {
const float maxDistance = ScoringParams::DISTANCE_WEIGHT_LANGUAGE
+ static_cast<float>(inputSize) * ScoringParams::TYPING_MAX_OUTPUT_SCORE_PER_INPUT;
float score = ScoringParams::TYPING_BASE_OUTPUT_SCORE - compoundDistance / maxDistance;
if (forceCommit) {
score += ScoringParams::AUTOCORRECT_OUTPUT_THRESHOLD;
}
- if (boostExactMatches && ErrorTypeUtils::isExactMatch(containedErrorTypes)) {
- score += ScoringParams::EXACT_MATCH_PROMOTION;
- if ((ErrorTypeUtils::MATCH_WITH_WRONG_CASE & containedErrorTypes) != 0) {
- score -= ScoringParams::CASE_ERROR_PENALTY_FOR_EXACT_MATCH;
+ if (hasProbabilityZero) {
+ // Previously, when both legitimate 0-frequency words (such as distracters) and
+ // offensive words were encoded in the same way, distracters would never show up
+ // when the user blocked offensive words (the default setting, as well as the
+ // setting for regression tests).
+ //
+ // When b/11031090 was fixed and a separate encoding was used for offensive words,
+ // 0-frequency words would no longer be blocked when they were an "exact match"
+ // (where case mismatches and accent mismatches would be considered an "exact
+ // match"). The exact match boosting functionality meant that, for example, when
+ // the user typed "mt" they would be suggested the word "Mt", although they most
+ // probably meant to type "my".
+ //
+ // For this reason, we introduced this change, which does the following:
+ // * Defines the "perfect match" as a really exact match, with no room for case or
+ // accent mismatches
+ // * When the target word has probability zero (as "Mt" does, because it is a
+ // distracter), ONLY boost its score if it is a perfect match.
+ //
+ // By doing this, when the user types "mt", the word "Mt" will NOT be boosted, and
+ // they will get "my". However, if the user makes an explicit effort to type "Mt",
+ // we do boost the word "Mt" so that the user's input is not autocorrected to "My".
+ if (boostExactMatches && ErrorTypeUtils::isPerfectMatch(containedErrorTypes)) {
+ score += ScoringParams::PERFECT_MATCH_PROMOTION;
}
- if ((ErrorTypeUtils::MATCH_WITH_MISSING_ACCENT & containedErrorTypes) != 0) {
- score -= ScoringParams::ACCENT_ERROR_PENALTY_FOR_EXACT_MATCH;
- }
- if ((ErrorTypeUtils::MATCH_WITH_DIGRAPH & containedErrorTypes) != 0) {
- score -= ScoringParams::DIGRAPH_PENALTY_FOR_EXACT_MATCH;
+ } else {
+ if (boostExactMatches && ErrorTypeUtils::isExactMatch(containedErrorTypes)) {
+ score += ScoringParams::EXACT_MATCH_PROMOTION;
+ if ((ErrorTypeUtils::MATCH_WITH_WRONG_CASE & containedErrorTypes) != 0) {
+ score -= ScoringParams::CASE_ERROR_PENALTY_FOR_EXACT_MATCH;
+ }
+ if ((ErrorTypeUtils::MATCH_WITH_MISSING_ACCENT & containedErrorTypes) != 0) {
+ score -= ScoringParams::ACCENT_ERROR_PENALTY_FOR_EXACT_MATCH;
+ }
+ if ((ErrorTypeUtils::MATCH_WITH_DIGRAPH & containedErrorTypes) != 0) {
+ score -= ScoringParams::DIGRAPH_PENALTY_FOR_EXACT_MATCH;
+ }
}
}
return static_cast<int>(score * SUGGEST_INTERFACE_OUTPUT_SCALE);
diff --git a/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_test.cpp b/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_test.cpp
index 4469dc715..313a9af10 100644
--- a/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_test.cpp
+++ b/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content_test.cpp
@@ -52,16 +52,14 @@ TEST(LanguageModelDictContentTest, TestUnigramProbabilityWithHistoricalInfo) {
const int flag = 0xF0;
const int timestamp = 0x3FFFFFFF;
- const int level = 3;
const int count = 10;
const int wordId = 100;
- const HistoricalInfo historicalInfo(timestamp, level, count);
+ const HistoricalInfo historicalInfo(timestamp, 0 /* level */, count);
const ProbabilityEntry probabilityEntry(flag, &historicalInfo);
languageModelDictContent.setProbabilityEntry(wordId, &probabilityEntry);
const ProbabilityEntry entry = languageModelDictContent.getProbabilityEntry(wordId);
EXPECT_EQ(flag, entry.getFlags());
EXPECT_EQ(timestamp, entry.getHistoricalInfo()->getTimestamp());
- EXPECT_EQ(level, entry.getHistoricalInfo()->getLevel());
EXPECT_EQ(count, entry.getHistoricalInfo()->getCount());
// Remove
@@ -108,14 +106,14 @@ TEST(LanguageModelDictContentTest, TestGetWordProbability) {
languageModelDictContent.setNgramProbabilityEntry(prevWordIds.limit(1), wordId,
&bigramProbabilityEntry);
EXPECT_EQ(bigramProbability, languageModelDictContent.getWordAttributes(prevWordIds, wordId,
- nullptr /* headerPolicy */).getProbability());
+ false /* mustMatchAllPrevWords */, nullptr /* headerPolicy */).getProbability());
const ProbabilityEntry trigramProbabilityEntry(flag, trigramProbability);
languageModelDictContent.setNgramProbabilityEntry(prevWordIds.limit(1),
prevWordIds[1], &probabilityEntry);
languageModelDictContent.setNgramProbabilityEntry(prevWordIds.limit(2), wordId,
&trigramProbabilityEntry);
EXPECT_EQ(trigramProbability, languageModelDictContent.getWordAttributes(prevWordIds, wordId,
- nullptr /* headerPolicy */).getProbability());
+ false /* mustMatchAllPrevWords */, nullptr /* headerPolicy */).getProbability());
}
} // namespace
diff --git a/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/probability_entry_test.cpp b/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/probability_entry_test.cpp
index 260b347ce..eb78034ba 100644
--- a/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/probability_entry_test.cpp
+++ b/native/jni/tests/suggest/policyimpl/dictionary/structure/v4/content/probability_entry_test.cpp
@@ -39,20 +39,18 @@ TEST(ProbabilityEntryTest, TestEncodeDecode) {
TEST(ProbabilityEntryTest, TestEncodeDecodeWithHistoricalInfo) {
const int flag = 0xF0;
const int timestamp = 0x3FFFFFFF;
- const int level = 3;
- const int count = 10;
+ const int count = 0xABCD;
- const HistoricalInfo historicalInfo(timestamp, level, count);
+ const HistoricalInfo historicalInfo(timestamp, 0 /* level */, count);
const ProbabilityEntry entry(flag, &historicalInfo);
const uint64_t encodedEntry = entry.encode(true /* hasHistoricalInfo */);
- EXPECT_EQ(0xF03FFFFFFF030Aull, encodedEntry);
+ EXPECT_EQ(0xF03FFFFFFFABCDull, encodedEntry);
const ProbabilityEntry decodedEntry =
ProbabilityEntry::decode(encodedEntry, true /* hasHistoricalInfo */);
EXPECT_EQ(flag, decodedEntry.getFlags());
EXPECT_EQ(timestamp, decodedEntry.getHistoricalInfo()->getTimestamp());
- EXPECT_EQ(level, decodedEntry.getHistoricalInfo()->getLevel());
EXPECT_EQ(count, decodedEntry.getHistoricalInfo()->getCount());
}
diff --git a/native/jni/tests/suggest/policyimpl/dictionary/utils/format_utils_test.cpp b/native/jni/tests/suggest/policyimpl/dictionary/utils/format_utils_test.cpp
index 15f560cd1..494200568 100644
--- a/native/jni/tests/suggest/policyimpl/dictionary/utils/format_utils_test.cpp
+++ b/native/jni/tests/suggest/policyimpl/dictionary/utils/format_utils_test.cpp
@@ -62,14 +62,14 @@ TEST(FormatUtilsTest, TestDetectFormatVersion) {
}
{
const std::vector<uint8_t> buffer =
- getBuffer(FormatUtils::MAGIC_NUMBER, FormatUtils::VERSION_4, 0, 0);
- EXPECT_EQ(FormatUtils::VERSION_4, FormatUtils::detectFormatVersion(
+ getBuffer(FormatUtils::MAGIC_NUMBER, FormatUtils::VERSION_402, 0, 0);
+ EXPECT_EQ(FormatUtils::VERSION_402, FormatUtils::detectFormatVersion(
ReadOnlyByteArrayView(buffer.data(), buffer.size())));
}
{
const std::vector<uint8_t> buffer =
- getBuffer(FormatUtils::MAGIC_NUMBER, FormatUtils::VERSION_4_DEV, 0, 0);
- EXPECT_EQ(FormatUtils::VERSION_4_DEV, FormatUtils::detectFormatVersion(
+ getBuffer(FormatUtils::MAGIC_NUMBER, FormatUtils::VERSION_403, 0, 0);
+ EXPECT_EQ(FormatUtils::VERSION_403, FormatUtils::detectFormatVersion(
ReadOnlyByteArrayView(buffer.data(), buffer.size())));
}
diff --git a/native/jni/tests/suggest/policyimpl/dictionary/utils/probability_utils_test.cpp b/native/jni/tests/suggest/policyimpl/dictionary/utils/probability_utils_test.cpp
new file mode 100644
index 000000000..be1f278c6
--- /dev/null
+++ b/native/jni/tests/suggest/policyimpl/dictionary/utils/probability_utils_test.cpp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+#include "suggest/policyimpl/dictionary/utils/probability_utils.h"
+
+#include <gtest/gtest.h>
+
+#include "defines.h"
+
+namespace latinime {
+namespace {
+
+TEST(ProbabilityUtilsTest, TestEncodeRawProbability) {
+ EXPECT_EQ(MAX_PROBABILITY, ProbabilityUtils::encodeRawProbability(1.0f));
+ EXPECT_EQ(MAX_PROBABILITY - 9, ProbabilityUtils::encodeRawProbability(0.5f));
+ EXPECT_EQ(0, ProbabilityUtils::encodeRawProbability(0.0f));
+}
+
+} // namespace
+} // namespace latinime
diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
index f90b266b6..039330c87 100644
--- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
+++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
@@ -49,7 +49,7 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
private static final String TEST_LOCALE = "test";
private static final int DUMMY_PROBABILITY = 0;
private static final int[] DICT_FORMAT_VERSIONS =
- new int[] { FormatSpec.VERSION4, FormatSpec.VERSION4_DEV };
+ new int[] { FormatSpec.VERSION402, FormatSpec.VERSION403, FormatSpec.VERSION4_DEV };
private static final String DICTIONARY_ID = "TestDecayingBinaryDictionary";
private int mCurrentTime = 0;
@@ -59,6 +59,7 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
super.setUp();
mCurrentTime = 0;
mDictFilesToBeDeleted.clear();
+ setCurrentTimeForTestMode(mCurrentTime);
}
@Override
@@ -71,12 +72,12 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
super.tearDown();
}
- private static boolean supportsBeginningOfSentence(final int formatVersion) {
- return formatVersion > FormatSpec.VERSION401;
+ private static boolean supportsCountBasedNgram(final int formatVersion) {
+ return formatVersion >= FormatSpec.VERSION403;
}
private static boolean supportsNgram(final int formatVersion) {
- return formatVersion >= FormatSpec.VERSION4_DEV;
+ return formatVersion >= FormatSpec.VERSION403;
}
private void onInputWord(final BinaryDictionary binaryDictionary, final String word,
@@ -142,19 +143,13 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
private File createEmptyDictionaryWithAttributeMapAndGetFile(final int formatVersion,
final HashMap<String, String> attributeMap) {
- if (formatVersion == FormatSpec.VERSION4
- || formatVersion == FormatSpec.VERSION4_ONLY_FOR_TESTING
- || formatVersion == FormatSpec.VERSION4_DEV) {
- try {
- final File dictFile = createEmptyVer4DictionaryAndGetFile(formatVersion,
- attributeMap);
- mDictFilesToBeDeleted.add(dictFile);
- return dictFile;
- } catch (final IOException e) {
- fail(e.toString());
- }
- } else {
- fail("Dictionary format version " + formatVersion + " is not supported.");
+ try {
+ final File dictFile = createEmptyVer4DictionaryAndGetFile(formatVersion,
+ attributeMap);
+ mDictFilesToBeDeleted.add(dictFile);
+ return dictFile;
+ } catch (final IOException e) {
+ fail(e.toString());
}
return null;
}
@@ -263,12 +258,10 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
onInputWord(binaryDictionary, "a", false /* isValidWord */);
assertTrue(binaryDictionary.isValidWord("a"));
- onInputWord(binaryDictionary, "b", true /* isValidWord */);
- assertTrue(binaryDictionary.isValidWord("b"));
-
onInputWordWithPrevWord(binaryDictionary, "b", false /* isValidWord */, "a");
assertFalse(isValidBigram(binaryDictionary, "a", "b"));
onInputWordWithPrevWord(binaryDictionary, "b", false /* isValidWord */, "a");
+ assertTrue(binaryDictionary.isValidWord("b"));
assertTrue(isValidBigram(binaryDictionary, "a", "b"));
onInputWordWithPrevWord(binaryDictionary, "c", true /* isValidWord */, "a");
@@ -284,16 +277,12 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
return;
}
- onInputWordWithPrevWords(binaryDictionary, "c", false /* isValidWord */, "b", "a");
- assertFalse(isValidTrigram(binaryDictionary, "a", "b", "c"));
- assertFalse(isValidBigram(binaryDictionary, "b", "c"));
- onInputWordWithPrevWords(binaryDictionary, "c", false /* isValidWord */, "b", "a");
+ onInputWordWithPrevWords(binaryDictionary, "c", true /* isValidWord */, "b", "a");
assertTrue(isValidTrigram(binaryDictionary, "a", "b", "c"));
assertTrue(isValidBigram(binaryDictionary, "b", "c"));
-
- onInputWordWithPrevWords(binaryDictionary, "d", true /* isValidWord */, "b", "a");
- assertTrue(isValidTrigram(binaryDictionary, "a", "b", "d"));
- assertTrue(isValidBigram(binaryDictionary, "b", "d"));
+ onInputWordWithPrevWords(binaryDictionary, "d", false /* isValidWord */, "c", "b");
+ assertFalse(isValidTrigram(binaryDictionary, "b", "c", "d"));
+ assertFalse(isValidBigram(binaryDictionary, "c", "d"));
onInputWordWithPrevWords(binaryDictionary, "cd", true /* isValidWord */, "b", "a");
assertTrue(isValidTrigram(binaryDictionary, "a", "b", "cd"));
@@ -312,6 +301,13 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
onInputWord(binaryDictionary, "a", true /* isValidWord */);
assertTrue(binaryDictionary.isValidWord("a"));
forcePassingShortTime(binaryDictionary);
+ if (supportsCountBasedNgram(formatVersion)) {
+ // Count based ngram language model doesn't support decaying based on the elapsed time.
+ assertTrue(binaryDictionary.isValidWord("a"));
+ } else {
+ assertFalse(binaryDictionary.isValidWord("a"));
+ }
+ forcePassingLongTime(binaryDictionary);
assertFalse(binaryDictionary.isValidWord("a"));
onInputWord(binaryDictionary, "a", true /* isValidWord */);
@@ -327,6 +323,12 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
onInputWordWithPrevWord(binaryDictionary, "b", true /* isValidWord */, "a");
assertTrue(isValidBigram(binaryDictionary, "a", "b"));
forcePassingShortTime(binaryDictionary);
+ if (supportsCountBasedNgram(formatVersion)) {
+ assertTrue(isValidBigram(binaryDictionary, "a", "b"));
+ } else {
+ assertFalse(isValidBigram(binaryDictionary, "a", "b"));
+ }
+ forcePassingLongTime(binaryDictionary);
assertFalse(isValidBigram(binaryDictionary, "a", "b"));
onInputWord(binaryDictionary, "a", true /* isValidWord */);
@@ -349,7 +351,7 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
onInputWordWithPrevWord(binaryDictionary, "bc", true /* isValidWord */, "ab");
onInputWordWithPrevWords(binaryDictionary, "cd", true /* isValidWord */, "bc", "ab");
assertTrue(isValidTrigram(binaryDictionary, "ab", "bc", "cd"));
- forcePassingShortTime(binaryDictionary);
+ forcePassingLongTime(binaryDictionary);
assertFalse(isValidTrigram(binaryDictionary, "ab", "bc", "cd"));
onInputWord(binaryDictionary, "ab", true /* isValidWord */);
@@ -540,7 +542,7 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
assertTrue(bigramCountBeforeGC > bigramCountAfterGC);
}
}
-
+ forcePassingShortTime(binaryDictionary);
assertTrue(Integer.parseInt(binaryDictionary.getPropertyForGettingStats(
BinaryDictionary.BIGRAM_COUNT_QUERY)) > 0);
assertTrue(Integer.parseInt(binaryDictionary.getPropertyForGettingStats(
@@ -666,14 +668,17 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
assertEquals(toFormatVersion, binaryDictionary.getFormatVersion());
assertTrue(binaryDictionary.isValidWord("aaa"));
assertFalse(binaryDictionary.isValidWord("bbb"));
- assertTrue(binaryDictionary.getFrequency("aaa") < binaryDictionary.getFrequency("ccc"));
- onInputWord(binaryDictionary, "bbb", false /* isValidWord */);
- assertTrue(binaryDictionary.isValidWord("bbb"));
+ if (supportsCountBasedNgram(toFormatVersion)) {
+ assertTrue(binaryDictionary.getFrequency("aaa") < binaryDictionary.getFrequency("ccc"));
+ onInputWord(binaryDictionary, "bbb", false /* isValidWord */);
+ assertTrue(binaryDictionary.isValidWord("bbb"));
+ }
assertTrue(isValidBigram(binaryDictionary, "aaa", "abc"));
assertFalse(isValidBigram(binaryDictionary, "aaa", "bbb"));
- onInputWordWithPrevWord(binaryDictionary, "bbb", false /* isValidWord */, "aaa");
- assertTrue(isValidBigram(binaryDictionary, "aaa", "bbb"));
-
+ if (supportsCountBasedNgram(toFormatVersion)) {
+ onInputWordWithPrevWord(binaryDictionary, "bbb", false /* isValidWord */, "aaa");
+ assertTrue(isValidBigram(binaryDictionary, "aaa", "bbb"));
+ }
if (supportsNgram(toFormatVersion)) {
assertTrue(isValidTrigram(binaryDictionary, "aaa", "abc", "xyz"));
assertFalse(isValidTrigram(binaryDictionary, "aaa", "abc", "def"));
@@ -686,9 +691,7 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
public void testBeginningOfSentence() {
for (final int formatVersion : DICT_FORMAT_VERSIONS) {
- if (supportsBeginningOfSentence(formatVersion)) {
- testBeginningOfSentence(formatVersion);
- }
+ testBeginningOfSentence(formatVersion);
}
}
@@ -716,10 +719,8 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
assertFalse(binaryDictionary.isValidNgram(beginningOfSentenceContext, "aaa"));
assertFalse(binaryDictionary.isValidNgram(beginningOfSentenceContext, "bbb"));
onInputWordWithBeginningOfSentenceContext(binaryDictionary, "aaa", true /* isValidWord */);
- assertFalse(binaryDictionary.isValidNgram(beginningOfSentenceContext, "aaa"));
onInputWordWithBeginningOfSentenceContext(binaryDictionary, "aaa", true /* isValidWord */);
onInputWordWithBeginningOfSentenceContext(binaryDictionary, "bbb", true /* isValidWord */);
- assertFalse(binaryDictionary.isValidNgram(beginningOfSentenceContext, "bbb"));
onInputWordWithBeginningOfSentenceContext(binaryDictionary, "bbb", true /* isValidWord */);
assertTrue(binaryDictionary.isValidNgram(beginningOfSentenceContext, "aaa"));
assertTrue(binaryDictionary.isValidNgram(beginningOfSentenceContext, "bbb"));
diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
index a1ae93c2f..fcaa8cdca 100644
--- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
@@ -45,19 +45,11 @@ public class BinaryDictionaryTests extends AndroidTestCase {
private static final String TEST_DICT_FILE_EXTENSION = ".testDict";
private static final String TEST_LOCALE = "test";
private static final int[] DICT_FORMAT_VERSIONS =
- new int[] { FormatSpec.VERSION4, FormatSpec.VERSION4_DEV };
+ new int[] { FormatSpec.VERSION402, FormatSpec.VERSION403, FormatSpec.VERSION4_DEV };
private static final String DICTIONARY_ID = "TestBinaryDictionary";
- private static boolean canCheckBigramProbability(final int formatVersion) {
- return formatVersion > FormatSpec.VERSION401;
- }
-
- private static boolean supportsBeginningOfSentence(final int formatVersion) {
- return formatVersion > FormatSpec.VERSION401;
- }
-
private static boolean supportsNgram(final int formatVersion) {
- return formatVersion >= FormatSpec.VERSION4_DEV;
+ return formatVersion >= FormatSpec.VERSION403;
}
private HashSet<File> mDictFilesToBeDeleted = new HashSet<>();
@@ -84,19 +76,13 @@ public class BinaryDictionaryTests extends AndroidTestCase {
private File createEmptyDictionaryWithAttributesAndGetFile(final int formatVersion,
final HashMap<String, String> attributeMap) {
- if (formatVersion == FormatSpec.VERSION4
- || formatVersion == FormatSpec.VERSION4_ONLY_FOR_TESTING
- || formatVersion == FormatSpec.VERSION4_DEV) {
- try {
- final File dictFile = createEmptyVer4DictionaryAndGetFile(formatVersion,
- attributeMap);
- mDictFilesToBeDeleted.add(dictFile);
- return dictFile;
- } catch (final IOException e) {
- fail(e.toString());
- }
- } else {
- fail("Dictionary format version " + formatVersion + " is not supported.");
+ try {
+ final File dictFile = createEmptyVer4DictionaryAndGetFile(formatVersion,
+ attributeMap);
+ mDictFilesToBeDeleted.add(dictFile);
+ return dictFile;
+ } catch (final IOException e) {
+ fail(e.toString());
}
return null;
}
@@ -350,18 +336,14 @@ public class BinaryDictionaryTests extends AndroidTestCase {
assertTrue(isValidBigram(binaryDictionary, "aaa", "bcc"));
assertTrue(isValidBigram(binaryDictionary, "abb", "aaa"));
assertTrue(isValidBigram(binaryDictionary, "abb", "bcc"));
- if (canCheckBigramProbability(formatVersion)) {
- assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "abb"));
- assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "bcc"));
- assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abb", "aaa"));
- assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abb", "bcc"));
- }
+ assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "abb"));
+ assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "bcc"));
+ assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abb", "aaa"));
+ assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abb", "bcc"));
addBigramWords(binaryDictionary, "aaa", "abb", updatedBigramProbability);
- if (canCheckBigramProbability(formatVersion)) {
- assertEquals(updatedBigramProbability,
- getBigramProbability(binaryDictionary, "aaa", "abb"));
- }
+ assertEquals(updatedBigramProbability,
+ getBigramProbability(binaryDictionary, "aaa", "abb"));
assertFalse(isValidBigram(binaryDictionary, "bcc", "aaa"));
assertFalse(isValidBigram(binaryDictionary, "bcc", "bbc"));
@@ -381,17 +363,12 @@ public class BinaryDictionaryTests extends AndroidTestCase {
addUnigramWord(binaryDictionary, "abc", unigramProbability);
addUnigramWord(binaryDictionary, "f", unigramProbability);
- if (canCheckBigramProbability(formatVersion)) {
- assertEquals(bigramProbability,
- getBigramProbability(binaryDictionary, "abcde", "fghij"));
- }
+ assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abcde", "fghij"));
assertEquals(Dictionary.NOT_A_PROBABILITY,
getBigramProbability(binaryDictionary, "abcde", "fgh"));
addBigramWords(binaryDictionary, "abcde", "fghij", updatedBigramProbability);
- if (canCheckBigramProbability(formatVersion)) {
- assertEquals(updatedBigramProbability,
- getBigramProbability(binaryDictionary, "abcde", "fghij"));
- }
+ assertEquals(updatedBigramProbability,
+ getBigramProbability(binaryDictionary, "abcde", "fghij"));
}
public void testRandomlyAddBigramWords() {
@@ -441,10 +418,8 @@ public class BinaryDictionaryTests extends AndroidTestCase {
final int bigramProbability = bigramProbabilities.get(bigram);
assertEquals(bigramProbability != Dictionary.NOT_A_PROBABILITY,
isValidBigram(binaryDictionary, bigram.first, bigram.second));
- if (canCheckBigramProbability(formatVersion)) {
- assertEquals(bigramProbability,
- getBigramProbability(binaryDictionary, bigram.first, bigram.second));
- }
+ assertEquals(bigramProbability,
+ getBigramProbability(binaryDictionary, bigram.first, bigram.second));
}
}
@@ -594,12 +569,10 @@ public class BinaryDictionaryTests extends AndroidTestCase {
assertEquals(unigramProbability, binaryDictionary.getFrequency("aaa"));
assertEquals(unigramProbability, binaryDictionary.getFrequency("abb"));
assertEquals(unigramProbability, binaryDictionary.getFrequency("bcc"));
- if (canCheckBigramProbability(formatVersion)) {
- assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "abb"));
- assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "bcc"));
- assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abb", "aaa"));
- assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abb", "bcc"));
- }
+ assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "abb"));
+ assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "bcc"));
+ assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abb", "aaa"));
+ assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abb", "bcc"));
assertFalse(isValidBigram(binaryDictionary, "bcc", "aaa"));
assertFalse(isValidBigram(binaryDictionary, "bcc", "bbc"));
assertFalse(isValidBigram(binaryDictionary, "aaa", "aaa"));
@@ -661,10 +634,8 @@ public class BinaryDictionaryTests extends AndroidTestCase {
final int bigramProbability = bigramProbabilities.get(bigram);
assertEquals(bigramProbability != Dictionary.NOT_A_PROBABILITY,
isValidBigram(binaryDictionary, bigram.first, bigram.second));
- if (canCheckBigramProbability(formatVersion)) {
- assertEquals(bigramProbability,
- getBigramProbability(binaryDictionary, bigram.first, bigram.second));
- }
+ assertEquals(bigramProbability,
+ getBigramProbability(binaryDictionary, bigram.first, bigram.second));
}
}
@@ -768,10 +739,8 @@ public class BinaryDictionaryTests extends AndroidTestCase {
probability = Dictionary.NOT_A_PROBABILITY;
}
- if (canCheckBigramProbability(formatVersion)) {
- assertEquals(probability,
- getBigramProbability(binaryDictionary, bigram.first, bigram.second));
- }
+ assertEquals(probability,
+ getBigramProbability(binaryDictionary, bigram.first, bigram.second));
assertEquals(probability != Dictionary.NOT_A_PROBABILITY,
isValidBigram(binaryDictionary, bigram.first, bigram.second));
}
@@ -971,10 +940,8 @@ public class BinaryDictionaryTests extends AndroidTestCase {
for (final WeightedString bigramTarget : wordProperty.getBigrams()) {
final String word1 = bigramTarget.mWord;
assertTrue(bigramWord1s.contains(word1));
- if (canCheckBigramProbability(formatVersion)) {
- final int bigramProbability = bigramProbabilities.get(new Pair<>(word0, word1));
- assertEquals(bigramProbability, bigramTarget.getProbability());
- }
+ final int bigramProbability = bigramProbabilities.get(new Pair<>(word0, word1));
+ assertEquals(bigramProbability, bigramTarget.getProbability());
}
}
}
@@ -1057,10 +1024,8 @@ public class BinaryDictionaryTests extends AndroidTestCase {
final String word1 = bigramTarget.mWord;
assertTrue(bigramWord1s.contains(word1));
final Pair<String, String> bigram = new Pair<>(word0, word1);
- if (canCheckBigramProbability(formatVersion)) {
- final int bigramProbability = bigramProbabilitiesToCheckLater.get(bigram);
- assertEquals(bigramProbability, bigramTarget.getProbability());
- }
+ final int bigramProbability = bigramProbabilitiesToCheckLater.get(bigram);
+ assertEquals(bigramProbability, bigramTarget.getProbability());
bigramSet.remove(bigram);
}
}
@@ -1198,7 +1163,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
public void testPossiblyOffensiveAttributeMaintained() {
final BinaryDictionary binaryDictionary =
- getEmptyBinaryDictionary(FormatSpec.VERSION4_DEV);
+ getEmptyBinaryDictionary(FormatSpec.VERSION403);
binaryDictionary.addUnigramEntry("ddd", 100, null, Dictionary.NOT_A_PROBABILITY,
false, true, true, 0);
WordProperty wordProperty = binaryDictionary.getWordProperty("ddd", false);
@@ -1236,11 +1201,9 @@ public class BinaryDictionaryTests extends AndroidTestCase {
assertEquals(toFormatVersion, binaryDictionary.getFormatVersion());
assertEquals(unigramProbability, binaryDictionary.getFrequency("aaa"));
assertEquals(unigramProbability, binaryDictionary.getFrequency("bbb"));
- if (canCheckBigramProbability(toFormatVersion)) {
- assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "bbb"));
- assertEquals(bigramProbability, binaryDictionary.getNgramProbability(
- NgramContext.BEGINNING_OF_SENTENCE, "aaa"));
- }
+ assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "bbb"));
+ assertEquals(bigramProbability, binaryDictionary.getNgramProbability(
+ NgramContext.BEGINNING_OF_SENTENCE, "aaa"));
assertTrue(isValidBigram(binaryDictionary, "aaa", "bbb"));
WordProperty wordProperty = binaryDictionary.getWordProperty("ccc",
false /* isBeginningOfSentence */);
@@ -1311,10 +1274,8 @@ public class BinaryDictionaryTests extends AndroidTestCase {
binaryDictionary.getPropertyForGettingStats(BinaryDictionary.UNIGRAM_COUNT_QUERY)));
for (final Pair<String, String> bigram : bigrams) {
- if (canCheckBigramProbability(toFormatVersion)) {
- assertEquals((int)bigramProbabilities.get(bigram),
- getBigramProbability(binaryDictionary, bigram.first, bigram.second));
- }
+ assertEquals((int)bigramProbabilities.get(bigram),
+ getBigramProbability(binaryDictionary, bigram.first, bigram.second));
assertTrue(isValidBigram(binaryDictionary, bigram.first, bigram.second));
}
assertEquals(bigramProbabilities.size(), Integer.parseInt(
@@ -1323,9 +1284,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
public void testBeginningOfSentence() {
for (final int formatVersion : DICT_FORMAT_VERSIONS) {
- if (supportsBeginningOfSentence(formatVersion)) {
- testBeginningOfSentence(formatVersion);
- }
+ testBeginningOfSentence(formatVersion);
}
}
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
index a35fa13ce..d239f8dac 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
@@ -314,14 +314,14 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
final String dictVersion = Long.toString(System.currentTimeMillis());
final String codePointTableAttribute = DictionaryHeader.CODE_POINT_TABLE_KEY;
final File file = BinaryDictUtils.getDictFile(dictName, dictVersion,
- BinaryDictUtils.VERSION201_OPTIONS, getContext().getCacheDir());
+ BinaryDictUtils.STATIC_OPTIONS, getContext().getCacheDir());
// Write a test dictionary
final DictEncoder dictEncoder = new Ver2DictEncoder(file,
Ver2DictEncoder.CODE_POINT_TABLE_ON);
final FormatSpec.FormatOptions formatOptions =
new FormatSpec.FormatOptions(
- FormatSpec.MINIMUM_SUPPORTED_VERSION_OF_CODE_POINT_TABLE);
+ FormatSpec.MINIMUM_SUPPORTED_STATIC_VERSION);
final FusionDictionary sourcedict = new FusionDictionary(new PtNodeArray(),
BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions));
addUnigrams(words.size(), sourcedict, words, null /* shortcutMap */);
@@ -359,11 +359,11 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
final List<String> results = new ArrayList<>();
runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_BUFFER,
- BinaryDictUtils.VERSION2_OPTIONS);
+ BinaryDictUtils.STATIC_OPTIONS);
runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_BUFFER,
- BinaryDictUtils.VERSION4_OPTIONS_WITHOUT_TIMESTAMP);
+ BinaryDictUtils.DYNAMIC_OPTIONS_WITHOUT_TIMESTAMP);
runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_BUFFER,
- BinaryDictUtils.VERSION4_OPTIONS_WITH_TIMESTAMP);
+ BinaryDictUtils.DYNAMIC_OPTIONS_WITH_TIMESTAMP);
for (final String result : results) {
Log.d(TAG, result);
}
@@ -373,11 +373,11 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
final List<String> results = new ArrayList<>();
runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_ARRAY,
- BinaryDictUtils.VERSION2_OPTIONS);
+ BinaryDictUtils.STATIC_OPTIONS);
runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_ARRAY,
- BinaryDictUtils.VERSION4_OPTIONS_WITHOUT_TIMESTAMP);
+ BinaryDictUtils.DYNAMIC_OPTIONS_WITHOUT_TIMESTAMP);
runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_ARRAY,
- BinaryDictUtils.VERSION4_OPTIONS_WITH_TIMESTAMP);
+ BinaryDictUtils.DYNAMIC_OPTIONS_WITH_TIMESTAMP);
for (final String result : results) {
Log.d(TAG, result);
@@ -501,7 +501,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
final ArrayList<String> results = new ArrayList<>();
runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_BUFFER,
- BinaryDictUtils.VERSION2_OPTIONS);
+ BinaryDictUtils.STATIC_OPTIONS);
for (final String result : results) {
Log.d(TAG, result);
@@ -512,7 +512,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
final ArrayList<String> results = new ArrayList<>();
runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_ARRAY,
- BinaryDictUtils.VERSION2_OPTIONS);
+ BinaryDictUtils.STATIC_OPTIONS);
for (final String result : results) {
Log.d(TAG, result);
@@ -623,9 +623,9 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
final ArrayList<String> results = new ArrayList<>();
runGetTerminalPositionTests(BinaryDictUtils.USE_BYTE_ARRAY,
- BinaryDictUtils.VERSION2_OPTIONS);
+ BinaryDictUtils.STATIC_OPTIONS);
runGetTerminalPositionTests(BinaryDictUtils.USE_BYTE_BUFFER,
- BinaryDictUtils.VERSION2_OPTIONS);
+ BinaryDictUtils.STATIC_OPTIONS);
for (final String result : results) {
Log.d(TAG, result);
@@ -633,7 +633,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
}
public void testVer2DictGetWordProperty() {
- final FormatOptions formatOptions = BinaryDictUtils.VERSION2_OPTIONS;
+ final FormatOptions formatOptions = BinaryDictUtils.STATIC_OPTIONS;
final ArrayList<String> words = sWords;
final HashMap<String, List<String>> shortcuts = sShortcuts;
final String dictName = "testGetWordProperty";
@@ -669,7 +669,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
}
public void testVer2DictIteration() {
- final FormatOptions formatOptions = BinaryDictUtils.VERSION2_OPTIONS;
+ final FormatOptions formatOptions = BinaryDictUtils.STATIC_OPTIONS;
final ArrayList<String> words = sWords;
final HashMap<String, List<String>> shortcuts = sShortcuts;
final SparseArray<List<Integer>> bigrams = sEmptyBigrams;
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
index 60e38250f..ce905c499 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
@@ -819,12 +819,18 @@ public class BinaryDictEncoderUtils {
final ArrayList<Entry<Integer, Integer>> codePointOccurrenceArray)
throws IOException, UnsupportedFormatException {
final int version = formatOptions.mVersion;
- if (version < FormatSpec.MINIMUM_SUPPORTED_VERSION
- || version > FormatSpec.MAXIMUM_SUPPORTED_VERSION) {
+ if ((version >= FormatSpec.MINIMUM_SUPPORTED_STATIC_VERSION &&
+ version <= FormatSpec.MAXIMUM_SUPPORTED_STATIC_VERSION) || (
+ version >= FormatSpec.MINIMUM_SUPPORTED_DYNAMIC_VERSION &&
+ version <= FormatSpec.MAXIMUM_SUPPORTED_DYNAMIC_VERSION)) {
+ // Dictionary is valid
+ } else {
throw new UnsupportedFormatException("Requested file format version " + version
- + ", but this implementation only supports versions "
- + FormatSpec.MINIMUM_SUPPORTED_VERSION + " through "
- + FormatSpec.MAXIMUM_SUPPORTED_VERSION);
+ + ", but this implementation only supports static versions "
+ + FormatSpec.MINIMUM_SUPPORTED_STATIC_VERSION + " through "
+ + FormatSpec.MAXIMUM_SUPPORTED_STATIC_VERSION + " and dynamic versions "
+ + FormatSpec.MINIMUM_SUPPORTED_DYNAMIC_VERSION + " through "
+ + FormatSpec.MAXIMUM_SUPPORTED_DYNAMIC_VERSION);
}
ByteArrayOutputStream headerBuffer = new ByteArrayOutputStream(256);
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java
index 8eabf749d..9c1e4cf84 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java
@@ -28,13 +28,11 @@ public class BinaryDictUtils {
public static final String TEST_DICT_FILE_EXTENSION = ".testDict";
- public static final FormatSpec.FormatOptions VERSION2_OPTIONS =
- new FormatSpec.FormatOptions(FormatSpec.VERSION2);
- public static final FormatSpec.FormatOptions VERSION201_OPTIONS =
- new FormatSpec.FormatOptions(FormatSpec.VERSION201);
- public static final FormatSpec.FormatOptions VERSION4_OPTIONS_WITHOUT_TIMESTAMP =
+ public static final FormatSpec.FormatOptions STATIC_OPTIONS =
+ new FormatSpec.FormatOptions(FormatSpec.VERSION202);
+ public static final FormatSpec.FormatOptions DYNAMIC_OPTIONS_WITHOUT_TIMESTAMP =
new FormatSpec.FormatOptions(FormatSpec.VERSION4, false /* hasTimestamp */);
- public static final FormatSpec.FormatOptions VERSION4_OPTIONS_WITH_TIMESTAMP =
+ public static final FormatSpec.FormatOptions DYNAMIC_OPTIONS_WITH_TIMESTAMP =
new FormatSpec.FormatOptions(FormatSpec.VERSION4, true /* hasTimestamp */);
public static DictionaryOptions makeDictionaryOptions(final String id, final String version,
@@ -55,7 +53,8 @@ public class BinaryDictUtils {
public static File getDictFile(final String name, final String version,
final FormatOptions formatOptions, final File directory) {
if (formatOptions.mVersion == FormatSpec.VERSION2
- || formatOptions.mVersion == FormatSpec.VERSION201) {
+ || formatOptions.mVersion == FormatSpec.VERSION201
+ || formatOptions.mVersion == FormatSpec.VERSION202) {
return new File(directory, name + "." + version + TEST_DICT_FILE_EXTENSION);
} else if (formatOptions.mVersion == FormatSpec.VERSION4) {
return new File(directory, name + "." + version);
@@ -71,7 +70,7 @@ public class BinaryDictUtils {
file.mkdir();
}
return new Ver4DictEncoder(file);
- } else if (formatOptions.mVersion == FormatSpec.VERSION2) {
+ } else if (formatOptions.mVersion == FormatSpec.VERSION202) {
return new Ver2DictEncoder(file, Ver2DictEncoder.CODE_POINT_TABLE_OFF);
} else {
throw new RuntimeException("The format option has a wrong version : "
diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
index 457e7af8e..5c261a94d 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
@@ -178,7 +178,8 @@ public class Ver2DictDecoder extends AbstractDictDecoder {
throw new IOException("Cannot read the dictionary header.");
}
if (header.mFormatOptions.mVersion != FormatSpec.VERSION2 &&
- header.mFormatOptions.mVersion != FormatSpec.VERSION201) {
+ header.mFormatOptions.mVersion != FormatSpec.VERSION201 &&
+ header.mFormatOptions.mVersion != FormatSpec.VERSION202) {
throw new UnsupportedFormatException("File header has a wrong version : "
+ header.mFormatOptions.mVersion);
}
diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java
index 2c2152be7..b52b8c485 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java
@@ -124,7 +124,8 @@ public class Ver2DictEncoder implements DictEncoder {
@Override
public void writeDictionary(final FusionDictionary dict, final FormatOptions formatOptions)
throws IOException, UnsupportedFormatException {
- if (formatOptions.mVersion > FormatSpec.VERSION201) {
+ // We no longer support anything but the latest version of v2.
+ if (formatOptions.mVersion != FormatSpec.VERSION202) {
throw new UnsupportedFormatException(
"The given format options has wrong version number : "
+ formatOptions.mVersion);
diff --git a/tests/src/com/android/inputmethod/latin/utils/CollectionUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/CollectionUtilsTests.java
index a5979c3df..dc4e2e4bb 100644
--- a/tests/src/com/android/inputmethod/latin/utils/CollectionUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/CollectionUtilsTests.java
@@ -29,14 +29,45 @@ import java.util.Collections;
@SmallTest
public class CollectionUtilsTests extends AndroidTestCase {
/**
+ * Tests that {@link CollectionUtils#arrayAsList(Object[],int,int)} fails as expected
+ * with some invalid inputs.
+ */
+ public void testArrayAsListFailure() {
+ final String[] array = { "0", "1" };
+ // Negative start
+ try {
+ CollectionUtils.arrayAsList(array, -1, 1);
+ fail("Failed to catch start < 0");
+ } catch (final IllegalArgumentException e) {
+ assertEquals("Invalid start: -1 end: 1 with array.length: 2", e.getMessage());
+ }
+ // start > end
+ try {
+ CollectionUtils.arrayAsList(array, 1, -1);
+ fail("Failed to catch start > end");
+ } catch (final IllegalArgumentException e) {
+ assertEquals("Invalid start: 1 end: -1 with array.length: 2", e.getMessage());
+ }
+ // end > array.length
+ try {
+ CollectionUtils.arrayAsList(array, 1, 3);
+ fail("Failed to catch end > array.length");
+ } catch (final IllegalArgumentException e) {
+ assertEquals("Invalid start: 1 end: 3 with array.length: 2", e.getMessage());
+ }
+ }
+
+ /**
* Tests that {@link CollectionUtils#arrayAsList(Object[],int,int)} gives the expected
* results for a few valid inputs.
*/
public void testArrayAsList() {
- final String[] array = { "0", "1", "2", "3", "4" };
final ArrayList<String> empty = new ArrayList<>();
+ assertEquals(empty, CollectionUtils.arrayAsList(new String[] { }, 0, 0));
+ final String[] array = { "0", "1", "2", "3", "4" };
assertEquals(empty, CollectionUtils.arrayAsList(array, 0, 0));
assertEquals(empty, CollectionUtils.arrayAsList(array, 1, 1));
+ assertEquals(empty, CollectionUtils.arrayAsList(array, array.length, array.length));
final ArrayList<String> expected123 = new ArrayList<>(Arrays.asList("1", "2", "3"));
assertEquals(expected123, CollectionUtils.arrayAsList(array, 1, 4));
}
diff --git a/tools/dicttool/Android.mk b/tools/dicttool/Android.mk
index 81c0706c1..42659253a 100644
--- a/tools/dicttool/Android.mk
+++ b/tools/dicttool/Android.mk
@@ -42,15 +42,11 @@ LATINIME_TESTS_SRC_DIR := $(LATINIME_LOCAL_DIR)/tests/src/com/android/inputmetho
# a significant part of the dependencies are mocked in the compat/ directory, with empty or
# nearly-empty implementations, for parts that we don't use in Dicttool.
LATINIME_SRC_FILES_FOR_DICTTOOL := \
- event/Combiner.java \
- event/Event.java \
latin/BinaryDictionary.java \
latin/DicTraverseSession.java \
latin/Dictionary.java \
- latin/LastComposedWord.java \
latin/NgramContext.java \
latin/SuggestedWords.java \
- latin/WordComposer.java \
latin/settings/NativeSuggestOptions.java \
latin/settings/SettingsValuesForSuggestion.java \
latin/utils/BinaryDictionaryUtils.java \
diff --git a/tools/dicttool/compat/com/android/inputmethod/event/CombinerChain.java b/tools/dicttool/compat/com/android/inputmethod/event/CombinerChain.java
deleted file mode 100644
index c4457a1b7..000000000
--- a/tools/dicttool/compat/com/android/inputmethod/event/CombinerChain.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.event;
-
-import java.util.ArrayList;
-
-/**
- * Compatibility class that stands in for the combiner chain in LatinIME.
- *
- * This is not used by dicttool, it's just needed by the dependency chain.
- */
-// TODO: there should not be a dependency to this in dicttool, so there
-// should be a sensible way to separate them cleanly.
-public class CombinerChain {
- private StringBuilder mComposingWord;
- public CombinerChain(final String initialText, final Combiner... combinerList) {
- mComposingWord = new StringBuilder(initialText);
- }
-
- public Event processEvent(final ArrayList<Event> previousEvents, final Event newEvent) {
- return newEvent;
- }
-
- public void applyProcessedEvent(final Event event) {
- mComposingWord.append(event.getTextToCommit());
- }
-
- public CharSequence getComposingWordWithCombiningFeedback() {
- return mComposingWord;
- }
-
- public void reset() {
- mComposingWord.setLength(0);
- }
-
- public static Combiner[] createCombiners(final String spec) {
- // Dicttool never uses a combiner at all, so we just return a zero-sized array.
- return new Combiner[0];
- }
-}
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java
index 48d2e5922..955c5728c 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java
@@ -98,6 +98,7 @@ public class CombinedInputOutput {
String word = null;
ProbabilityInfo probabilityInfo = new ProbabilityInfo(0);
boolean isNotAWord = false;
+ boolean isPossiblyOffensive = false;
ArrayList<WeightedString> bigrams = new ArrayList<>();
ArrayList<WeightedString> shortcuts = new ArrayList<>();
while (null != (line = reader.readLine())) {
@@ -106,7 +107,7 @@ public class CombinedInputOutput {
if (args[0].matches(CombinedFormatUtils.WORD_TAG + "=.*")) {
if (null != word) {
dict.add(word, probabilityInfo, shortcuts.isEmpty() ? null : shortcuts,
- isNotAWord, false /* isPossiblyOffensive */);
+ isNotAWord, isPossiblyOffensive);
for (WeightedString s : bigrams) {
dict.setBigram(word, s.mWord, s.mProbabilityInfo);
}
@@ -114,27 +115,37 @@ public class CombinedInputOutput {
if (!shortcuts.isEmpty()) shortcuts = new ArrayList<>();
if (!bigrams.isEmpty()) bigrams = new ArrayList<>();
isNotAWord = false;
+ isPossiblyOffensive = false;
for (String param : args) {
final String params[] = param.split("=", 2);
if (2 != params.length) throw new RuntimeException("Wrong format : " + line);
- if (CombinedFormatUtils.WORD_TAG.equals(params[0])) {
- word = params[1];
- } else if (CombinedFormatUtils.PROBABILITY_TAG.equals(params[0])) {
- probabilityInfo = new ProbabilityInfo(Integer.parseInt(params[1]),
- probabilityInfo.mTimestamp, probabilityInfo.mLevel,
- probabilityInfo.mCount);
- } else if (CombinedFormatUtils.HISTORICAL_INFO_TAG.equals(params[0])) {
- final String[] historicalInfoParams =
- params[1].split(CombinedFormatUtils.HISTORICAL_INFO_SEPARATOR);
- if (historicalInfoParams.length != HISTORICAL_INFO_ELEMENT_COUNT) {
- throw new RuntimeException("Wrong format (historical info) : " + line);
- }
- probabilityInfo = new ProbabilityInfo(probabilityInfo.mProbability,
- Integer.parseInt(historicalInfoParams[0]),
- Integer.parseInt(historicalInfoParams[1]),
- Integer.parseInt(historicalInfoParams[2]));
- } else if (CombinedFormatUtils.NOT_A_WORD_TAG.equals(params[0])) {
- isNotAWord = "true".equals(params[1]);
+ switch (params[0]) {
+ case CombinedFormatUtils.WORD_TAG:
+ word = params[1];
+ break;
+ case CombinedFormatUtils.PROBABILITY_TAG:
+ probabilityInfo = new ProbabilityInfo(Integer.parseInt(params[1]),
+ probabilityInfo.mTimestamp, probabilityInfo.mLevel,
+ probabilityInfo.mCount);
+ break;
+ case CombinedFormatUtils.HISTORICAL_INFO_TAG:
+ final String[] historicalInfoParams = params[1].split(
+ CombinedFormatUtils.HISTORICAL_INFO_SEPARATOR);
+ if (historicalInfoParams.length != HISTORICAL_INFO_ELEMENT_COUNT) {
+ throw new RuntimeException("Wrong format (historical info) : "
+ + line);
+ }
+ probabilityInfo = new ProbabilityInfo(probabilityInfo.mProbability,
+ Integer.parseInt(historicalInfoParams[0]),
+ Integer.parseInt(historicalInfoParams[1]),
+ Integer.parseInt(historicalInfoParams[2]));
+ break;
+ case CombinedFormatUtils.NOT_A_WORD_TAG:
+ isNotAWord = CombinedFormatUtils.isLiteralTrue(params[1]);
+ break;
+ case CombinedFormatUtils.POSSIBLY_OFFENSIVE_TAG:
+ isPossiblyOffensive = CombinedFormatUtils.isLiteralTrue(params[1]);
+ break;
}
}
} else if (args[0].matches(CombinedFormatUtils.SHORTCUT_TAG + "=.*")) {
@@ -190,7 +201,7 @@ public class CombinedInputOutput {
}
if (null != word) {
dict.add(word, probabilityInfo, shortcuts.isEmpty() ? null : shortcuts, isNotAWord,
- false /* isPossiblyOffensive */);
+ isPossiblyOffensive);
for (WeightedString s : bigrams) {
dict.setBigram(word, s.mWord, s.mProbabilityInfo);
}
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CommandList.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CommandList.java
index 0d93c7fa9..07450ca51 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CommandList.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CommandList.java
@@ -18,6 +18,7 @@ package com.android.inputmethod.latin.dicttool;
public class CommandList {
public static void populate() {
+ // TODO: Move some commands to native code.
Dicttool.addCommand("info", Info.class);
Dicttool.addCommand("diff", Diff.class);
Dicttool.addCommand("compress", Compress.Compressor.class);
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/DictionaryMaker.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/DictionaryMaker.java
index 8f9e4a3a6..6187853c8 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/DictionaryMaker.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/DictionaryMaker.java
@@ -120,7 +120,7 @@ public class DictionaryMaker {
String inputCombined = null;
String outputBinary = null;
String outputCombined = null;
- int outputBinaryFormatVersion = FormatSpec.VERSION201; // the default version is 201.
+ int outputBinaryFormatVersion = FormatSpec.VERSION202; // the default version is 202.
// Don't use code point table by default.
int codePointTableMode = Ver2DictEncoder.CODE_POINT_TABLE_OFF;