aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dictionaries/cs_wordlist.combined.gzbin948265 -> 948263 bytes
-rw-r--r--dictionaries/da_wordlist.combined.gzbin1017659 -> 1017659 bytes
-rw-r--r--dictionaries/de_wordlist.combined.gzbin1292098 -> 1292115 bytes
-rw-r--r--dictionaries/el_wordlist.combined.gzbin1134962 -> 1134961 bytes
-rw-r--r--dictionaries/en_GB_wordlist.combined.gzbin860515 -> 860515 bytes
-rw-r--r--dictionaries/en_US_wordlist.combined.gzbin877693 -> 877695 bytes
-rw-r--r--dictionaries/en_emoji.combined.gzbin4530 -> 4530 bytes
-rw-r--r--dictionaries/en_wordlist.combined.gzbin909065 -> 909067 bytes
-rw-r--r--dictionaries/es_wordlist.combined.gzbin951637 -> 951635 bytes
-rw-r--r--dictionaries/fi_wordlist.combined.gzbin1269545 -> 1269544 bytes
-rw-r--r--dictionaries/fr_emoji.combined.gzbin4511 -> 4511 bytes
-rw-r--r--dictionaries/fr_wordlist.combined.gzbin1106538 -> 1106539 bytes
-rw-r--r--dictionaries/hr_wordlist.combined.gzbin1014512 -> 1014511 bytes
-rw-r--r--dictionaries/it_wordlist.combined.gzbin933696 -> 933697 bytes
-rw-r--r--dictionaries/iw_wordlist.combined.gzbin465922 -> 465924 bytes
-rw-r--r--dictionaries/lt_wordlist.combined.gzbin980894 -> 980893 bytes
-rw-r--r--dictionaries/lv_wordlist.combined.gzbin970377 -> 970376 bytes
-rw-r--r--dictionaries/nb_wordlist.combined.gzbin964888 -> 964757 bytes
-rw-r--r--dictionaries/nl_wordlist.combined.gzbin1053244 -> 1053242 bytes
-rw-r--r--dictionaries/pl_wordlist.combined.gzbin1089295 -> 1089296 bytes
-rw-r--r--dictionaries/pt_BR_wordlist.combined.gzbin878505 -> 878505 bytes
-rw-r--r--dictionaries/pt_PT_wordlist.combined.gzbin1105961 -> 1105959 bytes
-rw-r--r--dictionaries/ru_wordlist.combined.gzbin1384966 -> 1384967 bytes
-rw-r--r--dictionaries/sl_wordlist.combined.gzbin315163 -> 315164 bytes
-rw-r--r--dictionaries/sr_wordlist.combined.gzbin1052033 -> 1052031 bytes
-rw-r--r--dictionaries/sv_wordlist.combined.gzbin1139282 -> 1139281 bytes
-rw-r--r--dictionaries/tr_wordlist.combined.gzbin925947 -> 925948 bytes
-rw-r--r--java/res/color/key_text_color_holo.xml48
-rw-r--r--java/res/raw/main_de.dictbin1605763 -> 1605763 bytes
-rw-r--r--java/res/raw/main_en.dictbin1070464 -> 1070464 bytes
-rw-r--r--java/res/raw/main_es.dictbin1138908 -> 1138908 bytes
-rw-r--r--java/res/raw/main_fr.dictbin1329188 -> 1329188 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.dictbin2229479 -> 2229479 bytes
-rw-r--r--java/res/values-af/strings-config-important-notice.xml6
-rw-r--r--java/res/values-af/strings.xml8
-rw-r--r--java/res/values-am/strings-config-important-notice.xml6
-rw-r--r--java/res/values-am/strings.xml8
-rw-r--r--java/res/values-ar/strings-config-important-notice.xml6
-rw-r--r--java/res/values-ar/strings.xml2
-rw-r--r--java/res/values-az-rAZ/strings-config-important-notice.xml6
-rw-r--r--java/res/values-bg/strings-config-important-notice.xml6
-rw-r--r--java/res/values-ca/strings-config-important-notice.xml8
-rw-r--r--java/res/values-ca/strings.xml2
-rw-r--r--java/res/values-cs/strings-config-important-notice.xml6
-rw-r--r--java/res/values-da/strings-config-important-notice.xml6
-rw-r--r--java/res/values-da/strings.xml8
-rw-r--r--java/res/values-de/strings-config-important-notice.xml6
-rw-r--r--java/res/values-el/strings-config-important-notice.xml6
-rw-r--r--java/res/values-el/strings.xml2
-rw-r--r--java/res/values-en-rGB/strings-config-important-notice.xml6
-rw-r--r--java/res/values-en-rIN/strings-config-important-notice.xml6
-rw-r--r--java/res/values-es-rUS/strings-config-important-notice.xml6
-rw-r--r--java/res/values-es-rUS/strings.xml2
-rw-r--r--java/res/values-es/strings-config-important-notice.xml6
-rw-r--r--java/res/values-es/strings.xml2
-rw-r--r--java/res/values-et-rEE/strings-config-important-notice.xml6
-rw-r--r--java/res/values-fa/strings-config-important-notice.xml6
-rw-r--r--java/res/values-fi/strings-config-important-notice.xml6
-rw-r--r--java/res/values-fr-rCA/strings-config-important-notice.xml6
-rw-r--r--java/res/values-fr-rCA/strings.xml2
-rw-r--r--java/res/values-fr/strings-config-important-notice.xml6
-rw-r--r--java/res/values-fr/strings.xml8
-rw-r--r--java/res/values-hi/strings-config-important-notice.xml6
-rw-r--r--java/res/values-hi/strings.xml2
-rw-r--r--java/res/values-hr/strings-config-important-notice.xml6
-rw-r--r--java/res/values-hr/strings.xml2
-rw-r--r--java/res/values-hu/strings-config-important-notice.xml6
-rw-r--r--java/res/values-hu/strings.xml2
-rw-r--r--java/res/values-hy-rAM/strings-config-important-notice.xml6
-rw-r--r--java/res/values-in/strings-config-important-notice.xml6
-rw-r--r--java/res/values-in/strings.xml8
-rw-r--r--java/res/values-it/strings-config-important-notice.xml6
-rw-r--r--java/res/values-it/strings.xml8
-rw-r--r--java/res/values-iw/strings-config-important-notice.xml6
-rw-r--r--java/res/values-iw/strings.xml2
-rw-r--r--java/res/values-ja/strings-config-important-notice.xml6
-rw-r--r--java/res/values-ka-rGE/strings-config-important-notice.xml6
-rw-r--r--java/res/values-km-rKH/strings-config-important-notice.xml6
-rw-r--r--java/res/values-ko/strings-config-important-notice.xml6
-rw-r--r--java/res/values-lo-rLA/strings-config-important-notice.xml6
-rw-r--r--java/res/values-lt/strings-config-important-notice.xml6
-rw-r--r--java/res/values-lt/strings.xml2
-rw-r--r--java/res/values-lv/strings-config-important-notice.xml6
-rw-r--r--java/res/values-mn-rMN/strings-config-important-notice.xml6
-rw-r--r--java/res/values-ms-rMY/strings-config-important-notice.xml6
-rw-r--r--java/res/values-ms-rMY/strings.xml8
-rw-r--r--java/res/values-nb/strings-config-important-notice.xml6
-rw-r--r--java/res/values-nb/strings.xml2
-rw-r--r--java/res/values-ne-rNP/strings-config-important-notice.xml6
-rw-r--r--java/res/values-nl/strings-config-important-notice.xml6
-rw-r--r--java/res/values-pl/strings-config-important-notice.xml6
-rw-r--r--java/res/values-pl/strings.xml8
-rw-r--r--java/res/values-pt-rPT/strings-config-important-notice.xml6
-rw-r--r--java/res/values-pt-rPT/strings.xml2
-rw-r--r--java/res/values-pt/strings-config-important-notice.xml6
-rw-r--r--java/res/values-pt/strings.xml2
-rw-r--r--java/res/values-ro/strings-config-important-notice.xml8
-rw-r--r--java/res/values-ro/strings.xml8
-rw-r--r--java/res/values-ru/strings-config-important-notice.xml6
-rw-r--r--java/res/values-sk/strings-config-important-notice.xml6
-rw-r--r--java/res/values-sl/strings-config-important-notice.xml6
-rw-r--r--java/res/values-sl/strings.xml2
-rw-r--r--java/res/values-sr/strings-config-important-notice.xml6
-rw-r--r--java/res/values-sr/strings.xml8
-rw-r--r--java/res/values-sv/strings-config-important-notice.xml6
-rw-r--r--java/res/values-sv/strings.xml2
-rw-r--r--java/res/values-sw/strings-config-important-notice.xml6
-rw-r--r--java/res/values-sw/strings.xml2
-rw-r--r--java/res/values-th/strings-config-important-notice.xml6
-rw-r--r--java/res/values-tl/strings-config-important-notice.xml6
-rw-r--r--java/res/values-tl/strings.xml12
-rw-r--r--java/res/values-tr/strings-config-important-notice.xml8
-rw-r--r--java/res/values-uk/strings-config-important-notice.xml6
-rw-r--r--java/res/values-uk/strings.xml8
-rw-r--r--java/res/values-vi/strings-config-important-notice.xml6
-rw-r--r--java/res/values-vi/strings.xml2
-rw-r--r--java/res/values-zh-rCN/strings-config-important-notice.xml6
-rw-r--r--java/res/values-zh-rHK/strings-config-important-notice.xml6
-rw-r--r--java/res/values-zh-rTW/strings-config-important-notice.xml6
-rw-r--r--java/res/values-zh-rTW/strings.xml2
-rw-r--r--java/res/values-zu/strings-config-important-notice.xml6
-rw-r--r--java/res/values-zu/strings.xml2
-rw-r--r--java/res/values/attrs.xml2
-rw-r--r--java/res/values/colors.xml4
-rw-r--r--java/res/values/themes-gb.xml2
-rw-r--r--java/res/values/themes-ics.xml2
-rw-r--r--java/res/values/themes-klp.xml2
-rw-r--r--java/res/xml/row_pcqwerty5.xml16
-rw-r--r--java/res/xml/rowkeys_symbols_shift1.xml8
-rw-r--r--java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java28
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java27
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyDetector.java3
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java24
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardView.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/EmojiLayoutParams.java6
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyDrawParams.java9
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java5
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java4
-rw-r--r--java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java72
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java6
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java2
-rw-r--r--java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java56
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java18
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryWriter.java92
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java358
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java74
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputConnection.java8
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java22
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java2
-rw-r--r--java/src/com/android/inputmethod/latin/UserBinaryDictionary.java29
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java6
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java2
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java2
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java5
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/DictEncoder.java2
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java8
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FormatSpec.java18
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java18
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java33
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java4
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java39
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java49
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java1
-rw-r--r--java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java55
-rw-r--r--java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java6
-rw-r--r--native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp11
-rw-r--r--native/jni/src/suggest/core/policy/dictionary_header_structure_policy.h2
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/bigram/ver4_bigram_list_policy.cpp10
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp20
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h70
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.cpp7
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.cpp13
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.cpp2
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.h8
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp9
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h7
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp11
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h6
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp40
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.cpp142
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h60
-rw-r--r--tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetTestsBase.java145
-rw-r--r--tests/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSetTests.java106
-rw-r--r--tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java2
-rw-r--r--tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java9
-rw-r--r--tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoderTests.java6
-rw-r--r--tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java4
-rw-r--r--tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java2
-rw-r--r--tools/dicttool/src/com/android/inputmethod/latin/dicttool/DictionaryMaker.java2
-rw-r--r--tools/dicttool/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java22
-rw-r--r--tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java3
-rw-r--r--tools/make-keyboard-text/res/values-af/donottranslate-more-keys.xml1
196 files changed, 1379 insertions, 1014 deletions
diff --git a/dictionaries/cs_wordlist.combined.gz b/dictionaries/cs_wordlist.combined.gz
index 7829d6573..94ba863a2 100644
--- a/dictionaries/cs_wordlist.combined.gz
+++ b/dictionaries/cs_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/da_wordlist.combined.gz b/dictionaries/da_wordlist.combined.gz
index e7140195b..b4baf627f 100644
--- a/dictionaries/da_wordlist.combined.gz
+++ b/dictionaries/da_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/de_wordlist.combined.gz b/dictionaries/de_wordlist.combined.gz
index 6a4bd445c..400718df1 100644
--- a/dictionaries/de_wordlist.combined.gz
+++ b/dictionaries/de_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/el_wordlist.combined.gz b/dictionaries/el_wordlist.combined.gz
index 74effa34b..599734cf8 100644
--- a/dictionaries/el_wordlist.combined.gz
+++ b/dictionaries/el_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/en_GB_wordlist.combined.gz b/dictionaries/en_GB_wordlist.combined.gz
index ff69f64c8..22685d1ce 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 2c80bc49d..92a3761df 100644
--- a/dictionaries/en_US_wordlist.combined.gz
+++ b/dictionaries/en_US_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/en_emoji.combined.gz b/dictionaries/en_emoji.combined.gz
index 0fc009df7..4d9cf1b59 100644
--- a/dictionaries/en_emoji.combined.gz
+++ b/dictionaries/en_emoji.combined.gz
Binary files differ
diff --git a/dictionaries/en_wordlist.combined.gz b/dictionaries/en_wordlist.combined.gz
index 06fb64fe8..f8b71c821 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 0a48b6d11..56617db99 100644
--- a/dictionaries/es_wordlist.combined.gz
+++ b/dictionaries/es_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/fi_wordlist.combined.gz b/dictionaries/fi_wordlist.combined.gz
index eefbfe51a..b7332ad3e 100644
--- a/dictionaries/fi_wordlist.combined.gz
+++ b/dictionaries/fi_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/fr_emoji.combined.gz b/dictionaries/fr_emoji.combined.gz
index f2929770d..5c9c7a096 100644
--- a/dictionaries/fr_emoji.combined.gz
+++ b/dictionaries/fr_emoji.combined.gz
Binary files differ
diff --git a/dictionaries/fr_wordlist.combined.gz b/dictionaries/fr_wordlist.combined.gz
index b568838e4..697f36799 100644
--- a/dictionaries/fr_wordlist.combined.gz
+++ b/dictionaries/fr_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/hr_wordlist.combined.gz b/dictionaries/hr_wordlist.combined.gz
index 864f67651..9a2086f1f 100644
--- a/dictionaries/hr_wordlist.combined.gz
+++ b/dictionaries/hr_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/it_wordlist.combined.gz b/dictionaries/it_wordlist.combined.gz
index ac977e303..5a5cbdc7a 100644
--- a/dictionaries/it_wordlist.combined.gz
+++ b/dictionaries/it_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/iw_wordlist.combined.gz b/dictionaries/iw_wordlist.combined.gz
index 36b047894..13eab9f17 100644
--- a/dictionaries/iw_wordlist.combined.gz
+++ b/dictionaries/iw_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/lt_wordlist.combined.gz b/dictionaries/lt_wordlist.combined.gz
index 029722d95..961266bb8 100644
--- a/dictionaries/lt_wordlist.combined.gz
+++ b/dictionaries/lt_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/lv_wordlist.combined.gz b/dictionaries/lv_wordlist.combined.gz
index 41e1c28bd..ae906a9db 100644
--- a/dictionaries/lv_wordlist.combined.gz
+++ b/dictionaries/lv_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/nb_wordlist.combined.gz b/dictionaries/nb_wordlist.combined.gz
index b699912b7..1c0f2cfb9 100644
--- a/dictionaries/nb_wordlist.combined.gz
+++ b/dictionaries/nb_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/nl_wordlist.combined.gz b/dictionaries/nl_wordlist.combined.gz
index 89c238830..37ba8ab42 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 2b53f69cb..ba71a5581 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 2d22447e4..02df1c1ee 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 1504165d0..bcd50ab03 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 8e654e9a1..acde9bc73 100644
--- a/dictionaries/ru_wordlist.combined.gz
+++ b/dictionaries/ru_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/sl_wordlist.combined.gz b/dictionaries/sl_wordlist.combined.gz
index 55e1bb1c8..a7240fe5b 100644
--- a/dictionaries/sl_wordlist.combined.gz
+++ b/dictionaries/sl_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/sr_wordlist.combined.gz b/dictionaries/sr_wordlist.combined.gz
index 8488a08b4..30ce99670 100644
--- a/dictionaries/sr_wordlist.combined.gz
+++ b/dictionaries/sr_wordlist.combined.gz
Binary files differ
diff --git a/dictionaries/sv_wordlist.combined.gz b/dictionaries/sv_wordlist.combined.gz
index 63425206e..b6ebab320 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 0251778c7..306cea184 100644
--- a/dictionaries/tr_wordlist.combined.gz
+++ b/dictionaries/tr_wordlist.combined.gz
Binary files differ
diff --git a/java/res/color/key_text_color_holo.xml b/java/res/color/key_text_color_holo.xml
deleted file mode 100644
index d034a945f..000000000
--- a/java/res/color/key_text_color_holo.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- Functional keys. -->
- <item android:state_single="true" android:state_pressed="true"
- android:color="@color/key_text_color_functional_holo" />
- <item android:state_single="true"
- android:color="@color/key_text_color_functional_holo" />
-
- <!-- Action keys. -->
- <item android:state_active="true" android:state_pressed="true"
- android:color="@color/key_text_color_normal_holo" />
- <item android:state_active="true"
- android:color="@color/key_text_color_normal_holo" />
-
- <!-- Toggle keys. Use checkable/checked state. -->
- <item android:state_checkable="true" android:state_checked="true" android:state_pressed="true"
- android:color="@color/key_text_color_normal_holo" />
- <item android:state_checkable="true" android:state_pressed="true"
- android:color="@color/key_text_color_normal_holo" />
- <item android:state_checkable="true" android:state_checked="true"
- android:color="@color/key_text_color_normal_holo" />
- <item android:state_checkable="true"
- android:color="@color/key_text_color_normal_holo" />
-
- <!-- Empty background keys. -->
- <item android:state_empty="true"
- android:color="@color/key_text_color_normal_holo" />
-
- <!-- Normal keys. -->
- <item android:state_pressed="true"
- android:color="@color/key_text_color_normal_holo" />
- <item android:color="@color/key_text_color_normal_holo" />
-</selector>
diff --git a/java/res/raw/main_de.dict b/java/res/raw/main_de.dict
index c65698d7b..3cbf7105d 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 57f3fe7c1..49adc9a19 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 261ab8c87..fe24cd624 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 c240d9665..94d1b9670 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 98135ce8e..ff11b9798 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 21bbe7c67..9fa50442a 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 c2b1e67b3..0f08f1735 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-config-important-notice.xml b/java/res/values-af/strings-config-important-notice.xml
index d0f328fd3..7c4dea563 100644
--- a/java/res/values-af/strings-config-important-notice.xml
+++ b/java/res/values-af/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Leer uit jou kommunikasie en getikte data om voorstelle te verbeter"</string>
</resources>
diff --git a/java/res/values-af/strings.xml b/java/res/values-af/strings.xml
index df43b13c7..59494aaff 100644
--- a/java/res/values-af/strings.xml
+++ b/java/res/values-af/strings.xml
@@ -167,10 +167,10 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Kies \'n woordeboeklêer om te installeer"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Moet hierdie lêer regtig vir <xliff:g id="LANGUAGE_NAME">%s</xliff:g> geïnstalleer word?"</string>
<string name="error" msgid="8940763624668513648">"Daar was \'n fout"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Gooi kontaktewoordeboek weg"</string>
- <string name="prefs_dump_user_dict" msgid="294870685041741951">"Gooi persoonlike woordeboek weg"</string>
- <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Gooi gebruikergeskiedeniswoordeboek weg"</string>
- <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Gooi personaliseringwoordeboek weg"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Lys kontaktewoordeboek"</string>
+ <string name="prefs_dump_user_dict" msgid="294870685041741951">"Lys persoonlike woordeboek"</string>
+ <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Lys gebruikergeskiedeniswoordeboek"</string>
+ <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Lys personaliseringwoordeboek"</string>
<string name="button_default" msgid="3988017840431881491">"Verstek"</string>
<string name="setup_welcome_title" msgid="6112821709832031715">"Welkom by <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="setup_welcome_additional_description" msgid="8150252008545768953">"met Gebaar-tik"</string>
diff --git a/java/res/values-am/strings-config-important-notice.xml b/java/res/values-am/strings-config-important-notice.xml
index 5bef0436c..ad64b6aca 100644
--- a/java/res/values-am/strings-config-important-notice.xml
+++ b/java/res/values-am/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"የአስተያየት ጥቆማዎችን ለማሻሻል ከእርስዎ ግንኙነቶች እና የተተየበ ውሂብ ይማሩ"</string>
</resources>
diff --git a/java/res/values-am/strings.xml b/java/res/values-am/strings.xml
index 3921fd135..6d4c5bf88 100644
--- a/java/res/values-am/strings.xml
+++ b/java/res/values-am/strings.xml
@@ -167,10 +167,10 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"የሚጭኑት የመዝገበ-ቃላት ፋይል ይምረጡ"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"እውን ይሄ ፋይል ለ<xliff:g id="LANGUAGE_NAME">%s</xliff:g> ይጫን?"</string>
<string name="error" msgid="8940763624668513648">"ስህተት ተከስቶ ነበር"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"የእውቂያዎች መዝገበ-ቃላትን ያራግፉ"</string>
- <string name="prefs_dump_user_dict" msgid="294870685041741951">"የግል መዝገበ-ቃላትን ያራግፉ"</string>
- <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"የተጠቃሚ ታሪክ መዝገበ-ቃላትን ያራግፉ"</string>
- <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"የግላዊነት ማላበሻ መዝገበ-ቃላትን ያራግፉ"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"የእውቂያዎች መዝገበ-ቃላትን ዝርዝር ይፍጠሩ"</string>
+ <string name="prefs_dump_user_dict" msgid="294870685041741951">"የግል መዝገበ-ቃላትን ዝርዝር ይፍጠሩ"</string>
+ <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"የተጠቃሚ ታሪክ መዝገበ-ቃላትን ዝርዝር ይፍጠሩ"</string>
+ <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"የግላዊነት ማላበሻ መዝገበ-ቃላትን ዝርዝር ይፍጠሩ"</string>
<string name="button_default" msgid="3988017840431881491">"ነባሪ"</string>
<string name="setup_welcome_title" msgid="6112821709832031715">"እንኳን ወደ <xliff:g id="APPLICATION_NAME">%s</xliff:g> በደህና መጡ"</string>
<string name="setup_welcome_additional_description" msgid="8150252008545768953">"በጣት ምልክት መተየብ"</string>
diff --git a/java/res/values-ar/strings-config-important-notice.xml b/java/res/values-ar/strings-config-important-notice.xml
index 36600af24..5e716c4a0 100644
--- a/java/res/values-ar/strings-config-important-notice.xml
+++ b/java/res/values-ar/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"التعلم من اتصالاتك والبيانات التي تكتبها لتحسين الاقتراحات"</string>
</resources>
diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml
index a0c26cf9c..f6ac11768 100644
--- a/java/res/values-ar/strings.xml
+++ b/java/res/values-ar/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"تحديد ملف قاموس للتثبيت"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"هل تريد حقًا تثبيت هذا الملف للغة <xliff:g id="LANGUAGE_NAME">%s</xliff:g>؟"</string>
<string name="error" msgid="8940763624668513648">"حدث خطأ"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"تفريغ معجم جهات الاتصال"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"عرض جهات الاتصال"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"تفريغ المعجم الشخصي"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"تفريغ معجم سجل المستخدم"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"تفريغ معجم التخصيص"</string>
diff --git a/java/res/values-az-rAZ/strings-config-important-notice.xml b/java/res/values-az-rAZ/strings-config-important-notice.xml
index 1815443c2..fa6f9522d 100644
--- a/java/res/values-az-rAZ/strings-config-important-notice.xml
+++ b/java/res/values-az-rAZ/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Əlaqələrdən və təkliflərin inkişafı üçün yazdığınız datadan öyrənin "</string>
</resources>
diff --git a/java/res/values-bg/strings-config-important-notice.xml b/java/res/values-bg/strings-config-important-notice.xml
index b6b766637..06f14087f 100644
--- a/java/res/values-bg/strings-config-important-notice.xml
+++ b/java/res/values-bg/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Ползване на съобщ. ви и въведени от вас данни за подобр. на предлож."</string>
</resources>
diff --git a/java/res/values-ca/strings-config-important-notice.xml b/java/res/values-ca/strings-config-important-notice.xml
index eadb5695e..57a7ade17 100644
--- a/java/res/values-ca/strings-config-important-notice.xml
+++ b/java/res/values-ca/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
- <string name="use_personalized_dicts_summary" msgid="590432261305469627">"Considera comunicacions i dades introduïdes per millorar sugger."</string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
+ <string name="use_personalized_dicts_summary" msgid="590432261305469627">"Considera comunicacions i dades introd. per millorar suggeriments"</string>
</resources>
diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml
index 7137aa59c..5afaca093 100644
--- a/java/res/values-ca/strings.xml
+++ b/java/res/values-ca/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Selecció d\'un fitxer de diccionari per instal·lar"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Realment vols instal·lar aquest fitxer per a <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"S\'ha produït un error"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Esborrar el diccionari de contactes"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Genera el diccionari de contactes"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"Esborrar el diccionari personal"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Esborrar dicc. d\'histor. d\'usuaris"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Esborrar diccionari de personalitz."</string>
diff --git a/java/res/values-cs/strings-config-important-notice.xml b/java/res/values-cs/strings-config-important-notice.xml
index bb2f03abc..f69e94642 100644
--- a/java/res/values-cs/strings-config-important-notice.xml
+++ b/java/res/values-cs/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Zlepšovat návrhy na základě vaší komunikace a zadaných dat"</string>
</resources>
diff --git a/java/res/values-da/strings-config-important-notice.xml b/java/res/values-da/strings-config-important-notice.xml
index 57d32cd74..a167b3145 100644
--- a/java/res/values-da/strings-config-important-notice.xml
+++ b/java/res/values-da/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Giv bedre forslag ud fra tidligere kommunikation og data"</string>
</resources>
diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml
index babea965c..7c0af04db 100644
--- a/java/res/values-da/strings.xml
+++ b/java/res/values-da/strings.xml
@@ -167,10 +167,10 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Vælg den ordbog, som du vil installere"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Vil du virkelig installere denne fil for <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Der opstod en fejl"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Eksportér ordbog for kontakter"</string>
- <string name="prefs_dump_user_dict" msgid="294870685041741951">"Eksportér personlig ordbog"</string>
- <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Eksportér ordbog for brugerhistorik"</string>
- <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Eksportér ordbog for tilpasning"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Gem ordbog for kontakter"</string>
+ <string name="prefs_dump_user_dict" msgid="294870685041741951">"Gem personlig ordbog"</string>
+ <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Gem ordbog for brugerhistorik"</string>
+ <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Gem ordbog for tilpasning"</string>
<string name="button_default" msgid="3988017840431881491">"Standard"</string>
<string name="setup_welcome_title" msgid="6112821709832031715">"Velkommen til <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="setup_welcome_additional_description" msgid="8150252008545768953">"med glidende indtastning"</string>
diff --git a/java/res/values-de/strings-config-important-notice.xml b/java/res/values-de/strings-config-important-notice.xml
index 5a8420229..6734a1ce3 100644
--- a/java/res/values-de/strings-config-important-notice.xml
+++ b/java/res/values-de/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Vorschläge anhand bisheriger Nachrichten und Eingaben verbessern"</string>
</resources>
diff --git a/java/res/values-el/strings-config-important-notice.xml b/java/res/values-el/strings-config-important-notice.xml
index 4ee3532c8..3e0c45bc8 100644
--- a/java/res/values-el/strings-config-important-notice.xml
+++ b/java/res/values-el/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Χρήση επικοινωνιών/δεδομένων πληκτρολόγησης για βελτίωση προτάσεων"</string>
</resources>
diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml
index 5e888e0fd..4ea576ce1 100644
--- a/java/res/values-el/strings.xml
+++ b/java/res/values-el/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Επιλογή αρχείου λεξικού για εγκατάσταση"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Εγκατάσταση αυτού του αρχείου για τα <xliff:g id="LANGUAGE_NAME">%s</xliff:g>;"</string>
<string name="error" msgid="8940763624668513648">"Παρουσιάστηκε σφάλμα."</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Αποτύπωση λεξικού επαφών"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Εξαγωγή λεξικού επαφών"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"Αποτύπωση προσωπικού λεξικού"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Αποτύπωση λεξικού ιστορικού χρήστη"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Αποτύπωση λεξικού εξατομίκευσης"</string>
diff --git a/java/res/values-en-rGB/strings-config-important-notice.xml b/java/res/values-en-rGB/strings-config-important-notice.xml
index a7ae30062..5530dbefc 100644
--- a/java/res/values-en-rGB/strings-config-important-notice.xml
+++ b/java/res/values-en-rGB/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Learn from your communications and typed data to improve suggestions"</string>
</resources>
diff --git a/java/res/values-en-rIN/strings-config-important-notice.xml b/java/res/values-en-rIN/strings-config-important-notice.xml
index a7ae30062..5530dbefc 100644
--- a/java/res/values-en-rIN/strings-config-important-notice.xml
+++ b/java/res/values-en-rIN/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Learn from your communications and typed data to improve suggestions"</string>
</resources>
diff --git a/java/res/values-es-rUS/strings-config-important-notice.xml b/java/res/values-es-rUS/strings-config-important-notice.xml
index b39cfbabf..4561842f0 100644
--- a/java/res/values-es-rUS/strings-config-important-notice.xml
+++ b/java/res/values-es-rUS/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Aprende de mensajes y datos ingresados para mejorar las sugerencias."</string>
</resources>
diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml
index c900c6aee..50583e8be 100644
--- a/java/res/values-es-rUS/strings.xml
+++ b/java/res/values-es-rUS/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Seleccionar archivo de diccionario para instalar"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"¿Realmente quieres instalar este archivo para <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Se produjo un error."</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Volcar diccionario de contactos"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Generar diccionario de contactos"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"Volcar diccionario personal"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Volcar diccionario hist. usuario"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Volcar diccionario personalización"</string>
diff --git a/java/res/values-es/strings-config-important-notice.xml b/java/res/values-es/strings-config-important-notice.xml
index 4d82e8b37..1068ea88e 100644
--- a/java/res/values-es/strings-config-important-notice.xml
+++ b/java/res/values-es/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Aprende de mensajes y datos escritos para mejorar sugerencias"</string>
</resources>
diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml
index ad7547f70..3427751dc 100644
--- a/java/res/values-es/strings.xml
+++ b/java/res/values-es/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Selecciona un archivo de diccionario para instalar"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"¿Seguro que quieres instalar este archivo para <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Se ha producido un error"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Volcar diccionario de contactos"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Generar diccionario de contactos"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"Volcar diccionario personal"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Volcar diccionario historial usuario"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Volcar diccionario personalización"</string>
diff --git a/java/res/values-et-rEE/strings-config-important-notice.xml b/java/res/values-et-rEE/strings-config-important-notice.xml
index c08d04576..d77b7f902 100644
--- a/java/res/values-et-rEE/strings-config-important-notice.xml
+++ b/java/res/values-et-rEE/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Kommunikats. ja sisestatud andmetest õppimine soovit. täiustamiseks"</string>
</resources>
diff --git a/java/res/values-fa/strings-config-important-notice.xml b/java/res/values-fa/strings-config-important-notice.xml
index b4e0335d7..915f3d4c6 100644
--- a/java/res/values-fa/strings-config-important-notice.xml
+++ b/java/res/values-fa/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"یادگیری از ارتباطات و اطلاعات تایپ شده شما برای بهبود پیشنهادات"</string>
</resources>
diff --git a/java/res/values-fi/strings-config-important-notice.xml b/java/res/values-fi/strings-config-important-notice.xml
index 2646501d5..316781bd5 100644
--- a/java/res/values-fi/strings-config-important-notice.xml
+++ b/java/res/values-fi/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Ehdotusten parannus viestinnän ja kirjoitettujen tietojen avulla"</string>
</resources>
diff --git a/java/res/values-fr-rCA/strings-config-important-notice.xml b/java/res/values-fr-rCA/strings-config-important-notice.xml
index 05b452c51..506101d8d 100644
--- a/java/res/values-fr-rCA/strings-config-important-notice.xml
+++ b/java/res/values-fr-rCA/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Apprendre de vos communic. et données entrées pour amél. suggestions"</string>
</resources>
diff --git a/java/res/values-fr-rCA/strings.xml b/java/res/values-fr-rCA/strings.xml
index dcb1119c2..cb6daeeda 100644
--- a/java/res/values-fr-rCA/strings.xml
+++ b/java/res/values-fr-rCA/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Sélectionner un fichier de dictionnaire à installer"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Installer ce fichier pour la langue « <xliff:g id="LANGUAGE_NAME">%s</xliff:g> »?"</string>
<string name="error" msgid="8940763624668513648">"Une erreur s\'est produite"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Vider le dictionnaire des contacts"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Extraire dictionnaire des contacts"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"Vider le dictionnaire personnel"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Vider dictionnaire hist. utilisateur"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Vider dictionnaire personnalisation"</string>
diff --git a/java/res/values-fr/strings-config-important-notice.xml b/java/res/values-fr/strings-config-important-notice.xml
index 21000de07..1672ee0f3 100644
--- a/java/res/values-fr/strings-config-important-notice.xml
+++ b/java/res/values-fr/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Améliorer suggestions en fonction des messages et données saisies"</string>
</resources>
diff --git a/java/res/values-fr/strings.xml b/java/res/values-fr/strings.xml
index 3cd6e2696..e3243c3ed 100644
--- a/java/res/values-fr/strings.xml
+++ b/java/res/values-fr/strings.xml
@@ -167,10 +167,10 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Sélectionner un fichier de dictionnaire à installer"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Installer ce fichier pour la langue \"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>\" ?"</string>
<string name="error" msgid="8940763624668513648">"Une erreur s\'est produite"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Supprimer dictionnaire des contacts"</string>
- <string name="prefs_dump_user_dict" msgid="294870685041741951">"Supprimer le dictionnaire personnel"</string>
- <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Supprimer l\'ancien dictionnaire"</string>
- <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Suppr. dictionnaire personnalisation"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Extraire dictionnaire des contacts"</string>
+ <string name="prefs_dump_user_dict" msgid="294870685041741951">"Extraire le dictionnaire personnel"</string>
+ <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Extraire dict. de l\'histor. util."</string>
+ <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Extraire dict. de personnalisation"</string>
<string name="button_default" msgid="3988017840431881491">"Par défaut"</string>
<string name="setup_welcome_title" msgid="6112821709832031715">"Bienvenue dans <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="setup_welcome_additional_description" msgid="8150252008545768953">"avec la saisie gestuelle"</string>
diff --git a/java/res/values-hi/strings-config-important-notice.xml b/java/res/values-hi/strings-config-important-notice.xml
index 9a1c12b39..ae6b4c703 100644
--- a/java/res/values-hi/strings-config-important-notice.xml
+++ b/java/res/values-hi/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"सुझावों में सुधार हेतु अपने संचार और लिखे गए डेटा से जानकारी पाएं"</string>
</resources>
diff --git a/java/res/values-hi/strings.xml b/java/res/values-hi/strings.xml
index 04879863f..b752d613a 100644
--- a/java/res/values-hi/strings.xml
+++ b/java/res/values-hi/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"इंस्टॉल करने के लिए कोई शब्दकोश फ़ाइल चुनें"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"क्या वाकई <xliff:g id="LANGUAGE_NAME">%s</xliff:g> के लिए यह फ़ाइल इंस्‍टॉल करें?"</string>
<string name="error" msgid="8940763624668513648">"कोई त्रुटि हुई थी"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"संपर्क शब्दकोश डंप करें"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"संपर्क शब्दकोश सूचीबद्ध करें"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"व्यक्तिगत शब्दकोश डंप करें"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"उपयोगकर्ता इतिहास शब्दकोश डंप करें"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"वैयक्तिकरण शब्दकोश डंप करें"</string>
diff --git a/java/res/values-hr/strings-config-important-notice.xml b/java/res/values-hr/strings-config-important-notice.xml
index c93544ed3..fff191bee 100644
--- a/java/res/values-hr/strings-config-important-notice.xml
+++ b/java/res/values-hr/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Upotrijebi poruke i upisane podatke za poboljšanje prijedloga"</string>
</resources>
diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml
index eb1391fe6..6d7e19120 100644
--- a/java/res/values-hr/strings.xml
+++ b/java/res/values-hr/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Odabir datoteke rječnika za instaliranje"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Želite li zaista instalirati tu datoteku za <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Došlo je do pogreške"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Kopiranje rječnika kontakata"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Ispis rječnika kontakata"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"Kopiranje osobnog rječnika"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Kopiranje rječ. povijesti korisnika"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Kopiranje rječnika za prilagodbu"</string>
diff --git a/java/res/values-hu/strings-config-important-notice.xml b/java/res/values-hu/strings-config-important-notice.xml
index b35c9f06c..4cb3c17ce 100644
--- a/java/res/values-hu/strings-config-important-notice.xml
+++ b/java/res/values-hu/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Javaslatok javítása a kommunikáció és begépelt adatok alapján"</string>
</resources>
diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml
index d4fffecf4..88fd3d6c3 100644
--- a/java/res/values-hu/strings.xml
+++ b/java/res/values-hu/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Válasszon ki egy szótárfájlt a telepítéshez."</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Valóban telepíti ezt a fájlt <xliff:g id="LANGUAGE_NAME">%s</xliff:g> nyelvhez?"</string>
<string name="error" msgid="8940763624668513648">"Hiba történt."</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Névjegyszótár törlése"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Névjegytár kiírása"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"Személyes szótár törlése"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Felhasználóielőzmény-szótár törlése"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Testreszabási szótár törlése"</string>
diff --git a/java/res/values-hy-rAM/strings-config-important-notice.xml b/java/res/values-hy-rAM/strings-config-important-notice.xml
index 0d1588e13..2463c118f 100644
--- a/java/res/values-hy-rAM/strings-config-important-notice.xml
+++ b/java/res/values-hy-rAM/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Բարելավեք առաջարկները` ձեր նամակագրությունից և մուտքագրած տվյալներից"</string>
</resources>
diff --git a/java/res/values-in/strings-config-important-notice.xml b/java/res/values-in/strings-config-important-notice.xml
index c1950c41a..03ca54e02 100644
--- a/java/res/values-in/strings-config-important-notice.xml
+++ b/java/res/values-in/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Belajar dari komunikasi &amp; data terketik untuk meningkatkan saran"</string>
</resources>
diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml
index b7907929e..9964daa89 100644
--- a/java/res/values-in/strings.xml
+++ b/java/res/values-in/strings.xml
@@ -167,10 +167,10 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Pilih file kamus untuk dipasang"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Yakin ingin memasang file ini untuk <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Terjadi kesalahan"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Kosongkan kamus kontak"</string>
- <string name="prefs_dump_user_dict" msgid="294870685041741951">"Kosongkan kamus pribadi"</string>
- <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Kosongkan kamus riwayat pengguna"</string>
- <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Kosongkan kamus hasil personalisasi"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Buat daftar kamus kontak"</string>
+ <string name="prefs_dump_user_dict" msgid="294870685041741951">"Buat daftar kamus pribadi"</string>
+ <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Buat daftar kamus riwayat pengguna"</string>
+ <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Buat daftar kamus personalisasi"</string>
<string name="button_default" msgid="3988017840431881491">"Default"</string>
<string name="setup_welcome_title" msgid="6112821709832031715">"Selamat datang di <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="setup_welcome_additional_description" msgid="8150252008545768953">"dengan Ketikan Isyarat"</string>
diff --git a/java/res/values-it/strings-config-important-notice.xml b/java/res/values-it/strings-config-important-notice.xml
index deff79f89..95b2a1828 100644
--- a/java/res/values-it/strings-config-important-notice.xml
+++ b/java/res/values-it/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Usa comunicazioni e dati digitati per migliorare i suggerimenti"</string>
</resources>
diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml
index a9728f1de..78f398778 100644
--- a/java/res/values-it/strings.xml
+++ b/java/res/values-it/strings.xml
@@ -167,10 +167,10 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Seleziona un file di dizionario da installare"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Vuoi davvero installare questo file per <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Si è verificato un errore"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Scarica dizionario contatti"</string>
- <string name="prefs_dump_user_dict" msgid="294870685041741951">"Scarica dizionario personale"</string>
- <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Scarica dizion. cronologia utente"</string>
- <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Scarica dizionario di personalizz."</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Estrai dizionario contatti"</string>
+ <string name="prefs_dump_user_dict" msgid="294870685041741951">"Estrai dizionario personale"</string>
+ <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Estrai dizion. cronologia utente"</string>
+ <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Estrai dizionario di personalizz."</string>
<string name="button_default" msgid="3988017840431881491">"Predefinito"</string>
<string name="setup_welcome_title" msgid="6112821709832031715">"Benvenuto in <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="setup_welcome_additional_description" msgid="8150252008545768953">"con la Digitazione gestuale"</string>
diff --git a/java/res/values-iw/strings-config-important-notice.xml b/java/res/values-iw/strings-config-important-notice.xml
index c7f352968..0ad8031f0 100644
--- a/java/res/values-iw/strings-config-important-notice.xml
+++ b/java/res/values-iw/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"למד מהתכתבויות ומנתונים שהקלדת כדי לשפר את ההצעות"</string>
</resources>
diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml
index 870623f93..accf80949 100644
--- a/java/res/values-iw/strings.xml
+++ b/java/res/values-iw/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"בחירת קובץ מילון להתקנה"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"האם אתה באמת רוצה להתקין את הקובץ הזה עבור <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"אירעה שגיאה"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"מחק את מילון אנשי הקשר"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"צור מילון אנשי קשר"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"מחק מילון אישי"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"מחק את המילון של היסטוריית המשתמשים"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"מחק את מילון ההתאמה האישית"</string>
diff --git a/java/res/values-ja/strings-config-important-notice.xml b/java/res/values-ja/strings-config-important-notice.xml
index 937ddae5c..31b5a710f 100644
--- a/java/res/values-ja/strings-config-important-notice.xml
+++ b/java/res/values-ja/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"メッセージなどのやり取りや入力したデータから入力候補を予測します"</string>
</resources>
diff --git a/java/res/values-ka-rGE/strings-config-important-notice.xml b/java/res/values-ka-rGE/strings-config-important-notice.xml
index e43ca01b1..02b280cb1 100644
--- a/java/res/values-ka-rGE/strings-config-important-notice.xml
+++ b/java/res/values-ka-rGE/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"უკეთესი შეთავაზებისთვის თქვენი კომუნიკაციიდან და ტექსტიდან სწავლა"</string>
</resources>
diff --git a/java/res/values-km-rKH/strings-config-important-notice.xml b/java/res/values-km-rKH/strings-config-important-notice.xml
index ad0325adb..7f58d613b 100644
--- a/java/res/values-km-rKH/strings-config-important-notice.xml
+++ b/java/res/values-km-rKH/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"សិក្សាការភ្ជាប់របស់អ្នកនិងទិន្នន័យ​ដែលបានបញ្ចូលដើម្បីធ្វើសំណើ​ឲ្យល្អ"</string>
</resources>
diff --git a/java/res/values-ko/strings-config-important-notice.xml b/java/res/values-ko/strings-config-important-notice.xml
index 2ea6e49f4..b8cfb375d 100644
--- a/java/res/values-ko/strings-config-important-notice.xml
+++ b/java/res/values-ko/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"사용자의 대화 내용과 입력한 데이터를 통해 단어 추천의 정확도를 개선합니다."</string>
</resources>
diff --git a/java/res/values-lo-rLA/strings-config-important-notice.xml b/java/res/values-lo-rLA/strings-config-important-notice.xml
index d4e5052bd..079dd6b01 100644
--- a/java/res/values-lo-rLA/strings-config-important-notice.xml
+++ b/java/res/values-lo-rLA/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"ຮຽນຮູ້ຈາກການສື່ສານ ແລະຂໍ້ມູນທີ່ທ່ານເຄີຍພິມເພື່ອປັບປຸງຄຳແນະນຳ"</string>
</resources>
diff --git a/java/res/values-lt/strings-config-important-notice.xml b/java/res/values-lt/strings-config-important-notice.xml
index 633980ece..cb91b5be1 100644
--- a/java/res/values-lt/strings-config-important-notice.xml
+++ b/java/res/values-lt/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Mokytis iš ryšių ir įvestų duomenų, siekiant pagerinti pasiūlymus"</string>
</resources>
diff --git a/java/res/values-lt/strings.xml b/java/res/values-lt/strings.xml
index 9efdc679c..331656fc9 100644
--- a/java/res/values-lt/strings.xml
+++ b/java/res/values-lt/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Pasirinkite diegiamą žodyno failą"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Ar tikrai įdiegti šį failą <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Įvyko klaida"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Iškelti kontaktų žodyną"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Sudaryti kontaktų žodyną"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"Iškelti asmeninį žodyną"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Iškelti naudotojo istorijos žodyną"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Iškelti suasmeninimo žodyną"</string>
diff --git a/java/res/values-lv/strings-config-important-notice.xml b/java/res/values-lv/strings-config-important-notice.xml
index ce2062dd9..916128c5e 100644
--- a/java/res/values-lv/strings-config-important-notice.xml
+++ b/java/res/values-lv/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Izmantojiet saziņu un ievadītos datus, lai uzlabotu ieteikumus."</string>
</resources>
diff --git a/java/res/values-mn-rMN/strings-config-important-notice.xml b/java/res/values-mn-rMN/strings-config-important-notice.xml
index 047cfc7bf..fb07acecf 100644
--- a/java/res/values-mn-rMN/strings-config-important-notice.xml
+++ b/java/res/values-mn-rMN/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Зөвлөмжүүдийг сайжруулахын тулд таны харилцсан, бичсэн зүйлсээс суралцана"</string>
</resources>
diff --git a/java/res/values-ms-rMY/strings-config-important-notice.xml b/java/res/values-ms-rMY/strings-config-important-notice.xml
index e53ada237..f021fe6b6 100644
--- a/java/res/values-ms-rMY/strings-config-important-notice.xml
+++ b/java/res/values-ms-rMY/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Perbaik cadangan berdasarkan komunikasi anda dan data yang ditaip"</string>
</resources>
diff --git a/java/res/values-ms-rMY/strings.xml b/java/res/values-ms-rMY/strings.xml
index 6fbd38c76..33ec0651e 100644
--- a/java/res/values-ms-rMY/strings.xml
+++ b/java/res/values-ms-rMY/strings.xml
@@ -167,10 +167,10 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Pilih fail kamus untuk dipasang"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Betul-betul pasang fail ini untuk <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Berlaku ralat"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Buang kamus kenalan"</string>
- <string name="prefs_dump_user_dict" msgid="294870685041741951">"Buang kamus peribadi"</string>
- <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Buang kamus sejarah pengguna"</string>
- <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Buang kamus pemperibadian"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Longgokan kamus kenalan"</string>
+ <string name="prefs_dump_user_dict" msgid="294870685041741951">"Longgokan kamus peribadi"</string>
+ <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Longgokan kamus sejarah pengguna"</string>
+ <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Longgokan kamus pemperibadian"</string>
<string name="button_default" msgid="3988017840431881491">"Lalai"</string>
<string name="setup_welcome_title" msgid="6112821709832031715">"Selamat datang ke <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="setup_welcome_additional_description" msgid="8150252008545768953">"dengan Taipan Gerak Isyarat"</string>
diff --git a/java/res/values-nb/strings-config-important-notice.xml b/java/res/values-nb/strings-config-important-notice.xml
index 8c79eef0b..f64f41538 100644
--- a/java/res/values-nb/strings-config-important-notice.xml
+++ b/java/res/values-nb/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Bruk kommunikasjonen og inndataene dine for å få bedre forslag"</string>
</resources>
diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml
index 02f13bb41..6a4eaf422 100644
--- a/java/res/values-nb/strings.xml
+++ b/java/res/values-nb/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Velg ordboksfilen du vil installere"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Vil du virkelig installere denne filen for <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Det oppsto en feil"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Tøm kontakter-ordlisten"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Generer ordliste for kontakter"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"Tøm den personlige ordlisten"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Tøm brukerlogg-ordlisten"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Tøm tilpasningsordlisten"</string>
diff --git a/java/res/values-ne-rNP/strings-config-important-notice.xml b/java/res/values-ne-rNP/strings-config-important-notice.xml
index 6945a61cb..71c016ac9 100644
--- a/java/res/values-ne-rNP/strings-config-important-notice.xml
+++ b/java/res/values-ne-rNP/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"सुझावहरू सुधार गर्न सञ्‍चारहरू र टाइप गरिएको डेटाबाट जान्नुहोस्"</string>
</resources>
diff --git a/java/res/values-nl/strings-config-important-notice.xml b/java/res/values-nl/strings-config-important-notice.xml
index f77a1f45a..096e029da 100644
--- a/java/res/values-nl/strings-config-important-notice.xml
+++ b/java/res/values-nl/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Suggesties verbeteren met uw communicatie en getypte gegevens"</string>
</resources>
diff --git a/java/res/values-pl/strings-config-important-notice.xml b/java/res/values-pl/strings-config-important-notice.xml
index 03da01d87..8a78ab0df 100644
--- a/java/res/values-pl/strings-config-important-notice.xml
+++ b/java/res/values-pl/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Analizuj wiadomości i wpisywane dane, by ulepszać podpowiedzi"</string>
</resources>
diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml
index 9d46f61fe..a4a6931c3 100644
--- a/java/res/values-pl/strings.xml
+++ b/java/res/values-pl/strings.xml
@@ -167,10 +167,10 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Wybierz plik słownika do zainstalowania"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Czy na pewno zainstalować ten plik dla języka: <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Wystąpił błąd"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Zrzut słownika kontaktów"</string>
- <string name="prefs_dump_user_dict" msgid="294870685041741951">"Zrzut słownika osobistego"</string>
- <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Zrzut słownika historii użytkownika"</string>
- <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Zrzut słownika personalizacji"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Wyciąg ze słownika kontaktów"</string>
+ <string name="prefs_dump_user_dict" msgid="294870685041741951">"Wyciąg ze słownika osobistego"</string>
+ <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Wyciąg ze słownika historii użytk."</string>
+ <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Wyciąg ze słownika personalizacji"</string>
<string name="button_default" msgid="3988017840431881491">"Domyślne"</string>
<string name="setup_welcome_title" msgid="6112821709832031715">"Witamy w aplikacji <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="setup_welcome_additional_description" msgid="8150252008545768953">"z pisaniem gestami"</string>
diff --git a/java/res/values-pt-rPT/strings-config-important-notice.xml b/java/res/values-pt-rPT/strings-config-important-notice.xml
index 0724173b4..7cc395917 100644
--- a/java/res/values-pt-rPT/strings-config-important-notice.xml
+++ b/java/res/values-pt-rPT/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Aprender com comunicações e dados introd. para melhorar sugestões"</string>
</resources>
diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml
index 8adaa4dde..4311dcd0b 100644
--- a/java/res/values-pt-rPT/strings.xml
+++ b/java/res/values-pt-rPT/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Selecione um ficheiro de dicionário para instalar"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Instalar mesmo este ficheiro para <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Ocorreu um erro"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Descarregar dicionário de contactos"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Transferir dicionário de contactos"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"Descarregar dicionário pessoal"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Desc. dicion. do hist. do utiliz."</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Descarregar dicionário de personal."</string>
diff --git a/java/res/values-pt/strings-config-important-notice.xml b/java/res/values-pt/strings-config-important-notice.xml
index 041a04c26..05fe4d126 100644
--- a/java/res/values-pt/strings-config-important-notice.xml
+++ b/java/res/values-pt/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Aprender com mensagens e dados digitados para melhorar sugestões"</string>
</resources>
diff --git a/java/res/values-pt/strings.xml b/java/res/values-pt/strings.xml
index 966c4021b..5bbab4621 100644
--- a/java/res/values-pt/strings.xml
+++ b/java/res/values-pt/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Selecione um arquivo de dicionário para instalar"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Deseja instalar este arquivo para <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Ocorreu um erro"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Despejar dicionário de contatos"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Listar dicionário de contatos"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"Despejar dicionário pessoal"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Despejar dicio. de hist. do usuário"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Despejar dicion. de personalização"</string>
diff --git a/java/res/values-ro/strings-config-important-notice.xml b/java/res/values-ro/strings-config-important-notice.xml
index ff064577e..2de8dde45 100644
--- a/java/res/values-ro/strings-config-important-notice.xml
+++ b/java/res/values-ro/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
- <string name="use_personalized_dicts_summary" msgid="590432261305469627">"Utilizați mesajele și datele introduse pt. a îmbunătăți sugestiile"</string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
+ <string name="use_personalized_dicts_summary" msgid="590432261305469627">"Utilizează mesajele și datele introduse pt. a îmbunătăți sugestiile"</string>
</resources>
diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml
index ac713d996..b9c89773d 100644
--- a/java/res/values-ro/strings.xml
+++ b/java/res/values-ro/strings.xml
@@ -167,10 +167,10 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Selectați un fișier dicționar de instalat"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Doriți să instalați acest fișier pentru <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"A apărut o eroare"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Eliminați dicționar pers. cont."</string>
- <string name="prefs_dump_user_dict" msgid="294870685041741951">"Eliminați dicționar personal"</string>
- <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Eliminați dicționar istoric utiliz."</string>
- <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Eliminați dicționar personalizare"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Listați dicționar persoane contact"</string>
+ <string name="prefs_dump_user_dict" msgid="294870685041741951">"Listați dicționar personal"</string>
+ <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Listați dicționar istoric utilizator"</string>
+ <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Listați dicționar personalizare"</string>
<string name="button_default" msgid="3988017840431881491">"Prestabilit"</string>
<string name="setup_welcome_title" msgid="6112821709832031715">"Bun venit la <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="setup_welcome_additional_description" msgid="8150252008545768953">"cu Tastarea gestuală"</string>
diff --git a/java/res/values-ru/strings-config-important-notice.xml b/java/res/values-ru/strings-config-important-notice.xml
index b2f215c4b..33828047c 100644
--- a/java/res/values-ru/strings-config-important-notice.xml
+++ b/java/res/values-ru/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Устройство будет запоминать то, что вы вводите чаще всего"</string>
</resources>
diff --git a/java/res/values-sk/strings-config-important-notice.xml b/java/res/values-sk/strings-config-important-notice.xml
index 00365ab07..4adb406c0 100644
--- a/java/res/values-sk/strings-config-important-notice.xml
+++ b/java/res/values-sk/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Zlepšovať návrhy na základe komunikácie a zadaných údajov"</string>
</resources>
diff --git a/java/res/values-sl/strings-config-important-notice.xml b/java/res/values-sl/strings-config-important-notice.xml
index fd14a6a52..29c5351a4 100644
--- a/java/res/values-sl/strings-config-important-notice.xml
+++ b/java/res/values-sl/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Vaša sporočila in vnesene podatke uporabi za boljše predloge"</string>
</resources>
diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml
index 650b69f5f..3dabb7e3e 100644
--- a/java/res/values-sl/strings.xml
+++ b/java/res/values-sl/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Izberite datoteko slovarja, ki jo želite namestiti"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Zares želite namestiti to datoteko za ta jezik: <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Prišlo je do napake"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Izvoz slovarja stikov"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Izpis slovarja stikov"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"Izvoz osebnega slovarja"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Izvoz slovarja zgodovine uporabnika"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Izvoz slovarja za prilagajanje"</string>
diff --git a/java/res/values-sr/strings-config-important-notice.xml b/java/res/values-sr/strings-config-important-notice.xml
index a6eb25ed9..e226a06ee 100644
--- a/java/res/values-sr/strings-config-important-notice.xml
+++ b/java/res/values-sr/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Користи комуникације и унете податке ради побољшања предлога"</string>
</resources>
diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml
index 782830d6f..af8760fd8 100644
--- a/java/res/values-sr/strings.xml
+++ b/java/res/values-sr/strings.xml
@@ -167,10 +167,10 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Избор датотеке речника за инсталирање"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Желите ли стварно да инсталирате ову датотеку за <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Дошло је до грешке"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Избриши речник контаката"</string>
- <string name="prefs_dump_user_dict" msgid="294870685041741951">"Избриши лични речник"</string>
- <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Избриши речник историје корисника"</string>
- <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Избриши персонализовани речник"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Направи сирову копију речника контаката"</string>
+ <string name="prefs_dump_user_dict" msgid="294870685041741951">"Направи сирову копију личног речника"</string>
+ <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Направи сирову копију речника историје корисника"</string>
+ <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Направи сирову копију персонализованог речника"</string>
<string name="button_default" msgid="3988017840431881491">"Подразумевано"</string>
<string name="setup_welcome_title" msgid="6112821709832031715">"Добро дошли у <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="setup_welcome_additional_description" msgid="8150252008545768953">"помоћу Куцања покретима"</string>
diff --git a/java/res/values-sv/strings-config-important-notice.xml b/java/res/values-sv/strings-config-important-notice.xml
index 8d8a08934..d484d6766 100644
--- a/java/res/values-sv/strings-config-important-notice.xml
+++ b/java/res/values-sv/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Få bättre förslag genom att använda tidigare angiven data och annan kommunikation"</string>
</resources>
diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml
index 22a5ce3ef..cda89b827 100644
--- a/java/res/values-sv/strings.xml
+++ b/java/res/values-sv/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Välj en ordboksfil att installera"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Vill du verkligen installera filen för <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Ett fel uppstod"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Dumpa ordlista för kontakter"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Ta fram ordlista för kontakter"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"Dumpa personlig ordlista"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Dumpa ordlista för användarhistorik"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Dumpa anpassad ordlista"</string>
diff --git a/java/res/values-sw/strings-config-important-notice.xml b/java/res/values-sw/strings-config-important-notice.xml
index 10eab64cd..8a74bdd8c 100644
--- a/java/res/values-sw/strings-config-important-notice.xml
+++ b/java/res/values-sw/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Jifunze kutoka kwenye mawasiliano yako na data iliyocharazwa ili kuboresha mapendekezo"</string>
</resources>
diff --git a/java/res/values-sw/strings.xml b/java/res/values-sw/strings.xml
index 50c6aaa38..587e95ad2 100644
--- a/java/res/values-sw/strings.xml
+++ b/java/res/values-sw/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Chagua faili ya kamusi ya kusakinisha"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Ungependa kusakinisha faili hii ya <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Kulikuwa na hitilafu"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Tupa kamusi ya anwani"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Onyesha orodha ya anwani"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"Tupa kamusi ya kibinafsi"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Tupa kamusi ya historia ya mtumiaji"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Tupa kamusi ya kuwekewa mapendeleo"</string>
diff --git a/java/res/values-th/strings-config-important-notice.xml b/java/res/values-th/strings-config-important-notice.xml
index 78342ae70..e156d5f23 100644
--- a/java/res/values-th/strings-config-important-notice.xml
+++ b/java/res/values-th/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"เรียนรู้จากการสื่อสารและข้อมูลที่พิมพ์ของคุณเพื่อปรับปรุงคำแนะนำ"</string>
</resources>
diff --git a/java/res/values-tl/strings-config-important-notice.xml b/java/res/values-tl/strings-config-important-notice.xml
index 687f8610f..5e0c0b32a 100644
--- a/java/res/values-tl/strings-config-important-notice.xml
+++ b/java/res/values-tl/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Pahusayin ang suhestiyon batay sa iyong pag-uusap at na-type na data"</string>
</resources>
diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml
index ac3cb1c0e..c0503a32b 100644
--- a/java/res/values-tl/strings.xml
+++ b/java/res/values-tl/strings.xml
@@ -167,14 +167,10 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Pumili ng file ng diksyunaryo na ii-install"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Talagang ii-install ang file na ito para sa <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Nagkaroon ng error"</string>
- <!-- no translation found for prefs_dump_contacts_dict (7227327764402323097) -->
- <skip />
- <!-- no translation found for prefs_dump_user_dict (294870685041741951) -->
- <skip />
- <!-- no translation found for prefs_dump_user_history_dict (6821075152449554628) -->
- <skip />
- <!-- no translation found for prefs_dump_personalization_dict (7558387996151745284) -->
- <skip />
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Diksyunaryo ng contacts ng Dump"</string>
+ <string name="prefs_dump_user_dict" msgid="294870685041741951">"Personal na diksyunaryo ng Dump"</string>
+ <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Diksyunaryo ng user history ng Dump"</string>
+ <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Personalization dictionary ng Dump"</string>
<string name="button_default" msgid="3988017840431881491">"Default"</string>
<string name="setup_welcome_title" msgid="6112821709832031715">"Maligayang pagdating sa <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="setup_welcome_additional_description" msgid="8150252008545768953">"gamit ang Gesture na Pag-type"</string>
diff --git a/java/res/values-tr/strings-config-important-notice.xml b/java/res/values-tr/strings-config-important-notice.xml
index 06c837871..28e333d46 100644
--- a/java/res/values-tr/strings-config-important-notice.xml
+++ b/java/res/values-tr/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
- <string name="use_personalized_dicts_summary" msgid="590432261305469627">"Önerileri iyileştirmek için iletişimlerimden ve yazılan verilerden öğren"</string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
+ <string name="use_personalized_dicts_summary" msgid="590432261305469627">"Önerileri iyileştirmek için iletşmlrmdn. ve yazılan verilerden öğren"</string>
</resources>
diff --git a/java/res/values-uk/strings-config-important-notice.xml b/java/res/values-uk/strings-config-important-notice.xml
index 3d6a4e759..6172b34e6 100644
--- a/java/res/values-uk/strings-config-important-notice.xml
+++ b/java/res/values-uk/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Пристрій буде запам’ятовувати, що ви пишете, надсилаєте й отримуєте"</string>
</resources>
diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml
index 1ed94ad7a..ee9208ce1 100644
--- a/java/res/values-uk/strings.xml
+++ b/java/res/values-uk/strings.xml
@@ -167,10 +167,10 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Вибрати файл словника, який потрібно встановити"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Справді встановити цей файл для такої мови: <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Сталася помилка"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Дамп словника контактів"</string>
- <string name="prefs_dump_user_dict" msgid="294870685041741951">"Дамп особистого словника"</string>
- <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Дамп словника історії користувача"</string>
- <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Дамп словника персоналізації"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Вивантаження словника контактів"</string>
+ <string name="prefs_dump_user_dict" msgid="294870685041741951">"Вивантаження особистого словника"</string>
+ <string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Вивантаж. словника користув. історії"</string>
+ <string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Вивантаження словника персоналізації"</string>
<string name="button_default" msgid="3988017840431881491">"За умовчанням"</string>
<string name="setup_welcome_title" msgid="6112821709832031715">"Вітаємо в програмі <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="setup_welcome_additional_description" msgid="8150252008545768953">"з функцією Ввід жестами"</string>
diff --git a/java/res/values-vi/strings-config-important-notice.xml b/java/res/values-vi/strings-config-important-notice.xml
index 6528f06ed..b753e18f4 100644
--- a/java/res/values-vi/strings-config-important-notice.xml
+++ b/java/res/values-vi/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Tìm hiểu từ thư từ trao đổi và dữ liệu đã nhập của bạn để cải tiến đề xuất"</string>
</resources>
diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml
index c0ccc7c52..112bc4785 100644
--- a/java/res/values-vi/strings.xml
+++ b/java/res/values-vi/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Chọn tệp từ điển để cài đặt"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Thực sự cài đặt tệp này cho <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Đã xảy ra lỗi"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Lưu vào từ điển danh bạ"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Tạo từ điển danh bạ"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"Lưu vào từ điển cá nhân"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Lưu vào từ điển lịch sử người dùng"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Lưu vào từ điển cá nhân hóa"</string>
diff --git a/java/res/values-zh-rCN/strings-config-important-notice.xml b/java/res/values-zh-rCN/strings-config-important-notice.xml
index 2ffe7d953..2394e31a8 100644
--- a/java/res/values-zh-rCN/strings-config-important-notice.xml
+++ b/java/res/values-zh-rCN/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"根据您的通信记录和以往输入的数据来完善建议"</string>
</resources>
diff --git a/java/res/values-zh-rHK/strings-config-important-notice.xml b/java/res/values-zh-rHK/strings-config-important-notice.xml
index 9e80655a3..3784c7667 100644
--- a/java/res/values-zh-rHK/strings-config-important-notice.xml
+++ b/java/res/values-zh-rHK/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"根據您的通訊記錄和已輸入的資料改善建議"</string>
</resources>
diff --git a/java/res/values-zh-rTW/strings-config-important-notice.xml b/java/res/values-zh-rTW/strings-config-important-notice.xml
index f1bdc7774..692d61cb3 100644
--- a/java/res/values-zh-rTW/strings-config-important-notice.xml
+++ b/java/res/values-zh-rTW/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"根據您的通訊紀錄和以往輸入的資料改善建議項目"</string>
</resources>
diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml
index 8a56f2810..1fdf7e830 100644
--- a/java/res/values-zh-rTW/strings.xml
+++ b/java/res/values-zh-rTW/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"選取要安裝的字典檔案"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"確定要安裝這個<xliff:g id="LANGUAGE_NAME">%s</xliff:g>檔案嗎?"</string>
<string name="error" msgid="8940763624668513648">"發生錯誤"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"捨棄聯絡人字典"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"傾印聯絡人字典"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"捨棄個人字典"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"捨棄使用者紀錄字典"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"捨棄個人化字典"</string>
diff --git a/java/res/values-zu/strings-config-important-notice.xml b/java/res/values-zu/strings-config-important-notice.xml
index 95d5a290c..245b05690 100644
--- a/java/res/values-zu/strings-config-important-notice.xml
+++ b/java/res/values-zu/strings-config-important-notice.xml
@@ -20,7 +20,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="important_notice_title" msgid="1836002733109536160"></string>
- <string name="important_notice_contents" msgid="897137043719116217"></string>
+ <string-array name="important_notice_title_array">
+ </string-array>
+ <string-array name="important_notice_contents_array">
+ </string-array>
<string name="use_personalized_dicts_summary" msgid="590432261305469627">"Funda kusukela kwezokuxhumana zakho nedatha ethayiphiwe ukuze uthuthukise iziphakamiso"</string>
</resources>
diff --git a/java/res/values-zu/strings.xml b/java/res/values-zu/strings.xml
index 42430ba27..f4c0d9255 100644
--- a/java/res/values-zu/strings.xml
+++ b/java/res/values-zu/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Khetha ifayela lesichazamazwi ukuze ulifake"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"Fakela ngempela leli fayela i-<xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"Kube nephutha"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Lahla isichazamazwi soxhumana nabo"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Yenza uhlu isichazamazwi soxhumana nabo"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"Lahla isichazamazwi somuntu siqu"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Lahla isichazamazwi somlando womsebenzisi"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Lahla isichazamazwi sokwenza kube ngokwakho"</string>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 055060642..475e92f2e 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -175,7 +175,7 @@
</declare-styleable>
<declare-styleable name="SuggestionStripView">
- <attr name="suggestionStripOption" format="integer">
+ <attr name="suggestionStripOptions" format="integer">
<!-- This should be aligned with SuggestionStripLayoutHelper.AUTO_CORRECT_* and etc. -->
<flag name="autoCorrectBold" value="0x01" />
<flag name="autoCorrectUnderline" value="0x02" />
diff --git a/java/res/values/colors.xml b/java/res/values/colors.xml
index 93f25a7f6..517174495 100644
--- a/java/res/values/colors.xml
+++ b/java/res/values/colors.xml
@@ -39,6 +39,7 @@
<color name="typed_word_color_ics">#D833B5E5</color>
<color name="suggested_word_color_ics">#B233B5E5</color>
<color name="highlight_translucent_color_ics">#9933B5E5</color>
+ <color name="key_text_color_holo">@android:color/white</color>
<color name="key_text_shadow_color_holo">@android:color/transparent</color>
<color name="key_text_inactivated_color_holo">#66E0E4E5</color>
<color name="key_hint_letter_color_holo">#80000000</color>
@@ -65,7 +66,4 @@
<!-- TODO: Color which should be included in the theme -->
<color name="emoji_key_background_color">#00000000</color>
<color name="emoji_key_pressed_background_color">#30FFFFFF</color>
-
- <color name="key_text_color_normal_holo">@android:color/white</color>
- <color name="key_text_color_functional_holo">@android:color/white</color>
</resources>
diff --git a/java/res/values/themes-gb.xml b/java/res/values/themes-gb.xml
index a460d4f7f..c189da383 100644
--- a/java/res/values/themes-gb.xml
+++ b/java/res/values/themes-gb.xml
@@ -133,7 +133,7 @@
parent="SuggestionStripView"
>
<item name="android:background">@drawable/keyboard_suggest_strip_gb</item>
- <item name="suggestionStripOption">autoCorrectBold|validTypedWordBold</item>
+ <item name="suggestionStripOptions">autoCorrectBold|validTypedWordBold</item>
<item name="colorValidTypedWord">@color/highlight_color_gb</item>
<item name="colorTypedWord">@color/typed_word_color_gb</item>
<item name="colorAutoCorrect">@color/highlight_color_gb</item>
diff --git a/java/res/values/themes-ics.xml b/java/res/values/themes-ics.xml
index caea92186..720eda9ce 100644
--- a/java/res/values/themes-ics.xml
+++ b/java/res/values/themes-ics.xml
@@ -112,7 +112,7 @@
parent="SuggestionStripView"
>
<item name="android:background">@drawable/keyboard_suggest_strip_holo</item>
- <item name="suggestionStripOption">autoCorrectBold|validTypedWordBold</item>
+ <item name="suggestionStripOptions">autoCorrectBold|validTypedWordBold</item>
<item name="colorValidTypedWord">@color/typed_word_color_ics</item>
<item name="colorTypedWord">@color/typed_word_color_ics</item>
<item name="colorAutoCorrect">@color/highlight_color_ics</item>
diff --git a/java/res/values/themes-klp.xml b/java/res/values/themes-klp.xml
index 0599fb65e..830527171 100644
--- a/java/res/values/themes-klp.xml
+++ b/java/res/values/themes-klp.xml
@@ -112,7 +112,7 @@
parent="SuggestionStripView"
>
<item name="android:background">@drawable/keyboard_suggest_strip_holo</item>
- <item name="suggestionStripOption">autoCorrectBold|validTypedWordBold</item>
+ <item name="suggestionStripOptions">autoCorrectBold|validTypedWordBold</item>
<item name="colorValidTypedWord">@color/typed_word_color_klp</item>
<item name="colorTypedWord">@color/typed_word_color_klp</item>
<item name="colorAutoCorrect">@color/highlight_color_klp</item>
diff --git a/java/res/xml/row_pcqwerty5.xml b/java/res/xml/row_pcqwerty5.xml
index a72f38880..f6438ab0f 100644
--- a/java/res/xml/row_pcqwerty5.xml
+++ b/java/res/xml/row_pcqwerty5.xml
@@ -64,18 +64,8 @@
latin:keyStyle="defaultEnterKeyStyle"
latin:keySpec="!icon/enter_key|!code/key_enter"
latin:keyWidth="15.384%p" />
- <switch>
- <case
- latin:keyboardLayoutSetElement="alphabet|alphabetAutomaticShifted"
- >
- <Spacer />
- </case>
- <!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" -->
- <default>
- <Key
- latin:keyStyle="emojiKeyStyle"
- latin:keyWidth="fillRight" />
- </default>
- </switch>
+ <Key
+ latin:keyStyle="emojiKeyStyle"
+ latin:keyWidth="fillRight" />
</Row>
</merge>
diff --git a/java/res/xml/rowkeys_symbols_shift1.xml b/java/res/xml/rowkeys_symbols_shift1.xml
index 7cb3213f0..4c2722c7e 100644
--- a/java/res/xml/rowkeys_symbols_shift1.xml
+++ b/java/res/xml/rowkeys_symbols_shift1.xml
@@ -34,11 +34,11 @@
<!-- U+221A: "√" SQUARE ROOT -->
<Key
latin:keySpec="&#x221A;" />
- <!-- U+03A0: "Π" GREEK CAPITAL LETTER PI
- U+03C0: "π" GREEK SMALL LETTER PI -->
+ <!-- U+03C0: "π" GREEK SMALL LETTER PI
+ U+03A0: "Π" GREEK CAPITAL LETTER PI -->
<Key
- latin:keySpec="&#x03A0;"
- latin:moreKeys="&#x03C0;" />
+ latin:keySpec="&#x03C0;"
+ latin:moreKeys="&#x03A0;" />
<!-- U+00F7: "÷" DIVISION SIGN -->
<Key
latin:keySpec="&#x00F7;" />
diff --git a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
index 4c53b528f..7fff46aaf 100644
--- a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
+++ b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
@@ -25,7 +25,6 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Rect;
-import android.graphics.Typeface;
import android.os.Build;
import android.os.CountDownTimer;
import android.preference.PreferenceManager;
@@ -49,6 +48,8 @@ import android.widget.TextView;
import com.android.inputmethod.keyboard.internal.DynamicGridKeyboard;
import com.android.inputmethod.keyboard.internal.EmojiLayoutParams;
import com.android.inputmethod.keyboard.internal.EmojiPageKeyboardView;
+import com.android.inputmethod.keyboard.internal.KeyDrawParams;
+import com.android.inputmethod.keyboard.internal.KeyVisualAttributes;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SubtypeSwitcher;
@@ -634,20 +635,23 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
// TODO:
}
- // Hack: These parameters are hacky.
- public void startEmojiPalettes(final String switchToAlphaLabel, final int switchToAlphaColor,
- final float switchToAlphaSize, final Typeface switchToAlphaTypeface) {
+ private static void setupAlphabetKey(final TextView alphabetKey, final String label,
+ final KeyDrawParams params) {
+ alphabetKey.setText(label);
+ alphabetKey.setTextColor(params.mTextColor);
+ alphabetKey.setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mLabelSize);
+ alphabetKey.setTypeface(params.mTypeface);
+ }
+
+ public void startEmojiPalettes(final String switchToAlphaLabel,
+ final KeyVisualAttributes keyVisualAttr) {
if (DEBUG_PAGER) {
Log.d(TAG, "allocate emoji palettes memory " + mCurrentPagerPosition);
}
- mAlphabetKeyLeft.setText(switchToAlphaLabel);
- mAlphabetKeyLeft.setTextColor(switchToAlphaColor);
- mAlphabetKeyLeft.setTextSize(TypedValue.COMPLEX_UNIT_PX, switchToAlphaSize);
- mAlphabetKeyLeft.setTypeface(switchToAlphaTypeface);
- mAlphabetKeyRight.setText(switchToAlphaLabel);
- mAlphabetKeyRight.setTextColor(switchToAlphaColor);
- mAlphabetKeyRight.setTextSize(TypedValue.COMPLEX_UNIT_PX, switchToAlphaSize);
- mAlphabetKeyRight.setTypeface(switchToAlphaTypeface);
+ final KeyDrawParams params = new KeyDrawParams();
+ params.updateParams(mEmojiLayoutParams.getActionBarHeight(), keyVisualAttr);
+ setupAlphabetKey(mAlphabetKeyLeft, switchToAlphaLabel, params);
+ setupAlphabetKey(mAlphabetKeyRight, switchToAlphaLabel, params);
mEmojiPager.setAdapter(mEmojiPalettesAdapter);
mEmojiPager.setCurrentItem(mCurrentPagerPosition);
}
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index ceda9ee9a..816a94300 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -137,8 +137,6 @@ public class Key implements Comparable<Key> {
private final OptionalAttributes mOptionalAttributes;
- private static final int DEFAULT_TEXT_COLOR = 0xFFFFFFFF;
-
private static final class OptionalAttributes {
/** Text to output when pressed. This can be multiple characters, like ".com" */
public final String mOutputText;
@@ -585,22 +583,7 @@ public class Key implements Comparable<Key> {
}
public final int selectTextColor(final KeyDrawParams params) {
- if (isShiftedLetterActivated()) {
- return params.mTextInactivatedColor;
- }
- if (params.mTextColorStateList == null) {
- return DEFAULT_TEXT_COLOR;
- }
- final int[] state;
- // TODO: Hack!!!!!!!! Consider having a new attribute for the functional text labels.
- // Currently, we distinguish "input key" from "functional key" by checking the
- // length of the label( > 1) and "functional" attributes (= true).
- if (mLabel != null && mLabel.length() > 1) {
- state = getCurrentDrawableState();
- } else {
- state = KEY_STATE_NORMAL;
- }
- return params.mTextColorStateList.getColorForState(state, DEFAULT_TEXT_COLOR);
+ return isShiftedLetterActivated() ? params.mTextInactivatedColor : params.mTextColor;
}
public final int selectHintTextSize(final KeyDrawParams params) {
@@ -733,10 +716,14 @@ public class Key implements Comparable<Key> {
return (attrs != null) ? attrs.mAltCode : CODE_UNSPECIFIED;
}
+ public int getIconId() {
+ return mIconId;
+ }
+
public Drawable getIcon(final KeyboardIconsSet iconSet, final int alpha) {
final OptionalAttributes attrs = mOptionalAttributes;
final int disabledIconId = (attrs != null) ? attrs.mDisabledIconId : ICON_UNDEFINED;
- final int iconId = mEnabled ? mIconId : disabledIconId;
+ final int iconId = mEnabled ? getIconId() : disabledIconId;
final Drawable icon = iconSet.getIconDrawable(iconId);
if (icon != null) {
icon.setAlpha(alpha);
@@ -748,7 +735,7 @@ public class Key implements Comparable<Key> {
final OptionalAttributes attrs = mOptionalAttributes;
final int previewIconId = (attrs != null) ? attrs.mPreviewIconId : ICON_UNDEFINED;
return previewIconId != ICON_UNDEFINED
- ? iconSet.getIconDrawable(previewIconId) : iconSet.getIconDrawable(mIconId);
+ ? iconSet.getIconDrawable(previewIconId) : iconSet.getIconDrawable(getIconId());
}
public int getWidth() {
diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
index 03d9defa0..87368d4ef 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -86,6 +86,9 @@ public class KeyDetector {
* @return the key that the touch point hits.
*/
public Key detectHitKey(final int x, final int y) {
+ if (mKeyboard == null) {
+ return null;
+ }
final int touchX = getTouchX(x);
final int touchY = getTouchY(y);
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 6215e2710..2711d249b 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -19,7 +19,6 @@ package com.android.inputmethod.keyboard;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
-import android.graphics.Paint;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.ContextThemeWrapper;
@@ -31,7 +30,7 @@ import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
import com.android.inputmethod.keyboard.KeyboardLayoutSet.KeyboardLayoutSetException;
import com.android.inputmethod.keyboard.internal.KeyboardState;
-import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.keyboard.internal.KeyboardTextsSet;
import com.android.inputmethod.latin.InputView;
import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.LatinImeLogger;
@@ -46,7 +45,7 @@ import com.android.inputmethod.latin.utils.ResourceUtils;
public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
private static final String TAG = KeyboardSwitcher.class.getSimpleName();
- static final class KeyboardTheme {
+ public static final class KeyboardTheme {
public final int mThemeId;
public final int mStyleId;
@@ -81,8 +80,9 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
private KeyboardState mState;
private KeyboardLayoutSet mKeyboardLayoutSet;
+ // TODO: The following {@link KeyboardTextsSet} should be in {@link KeyboardLayoutSet}.
+ private final KeyboardTextsSet mKeyboardTextsSet = new KeyboardTextsSet();
private SettingsValues mCurrentSettingsValues;
- private Key mSwitchToAlphaKey;
/** mIsAutoCorrectionActive indicates that auto corrected word will be input instead of
* what user actually typed. */
@@ -163,8 +163,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
mCurrentSettingsValues = settingsValues;
try {
mState.onLoadKeyboard();
- final Keyboard symbols = mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_SYMBOLS);
- mSwitchToAlphaKey = symbols.getKey(Constants.CODE_SWITCH_ALPHA_SYMBOL);
+ mKeyboardTextsSet.setLocale(mSubtypeSwitcher.getCurrentSubtypeLocale());
} catch (KeyboardLayoutSetException e) {
Log.w(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause());
LatinImeLogger.logOnException(e.mKeyboardId.toString(), e.getCause());
@@ -290,10 +289,9 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
@Override
public void setEmojiKeyboard() {
mMainKeyboardFrame.setVisibility(View.GONE);
- final Paint paint = mKeyboardView.newLabelPaint(mSwitchToAlphaKey);
mEmojiPalettesView.startEmojiPalettes(
- mSwitchToAlphaKey.getLabel(), paint.getColor(), paint.getTextSize(),
- paint.getTypeface());
+ mKeyboardTextsSet.getText(KeyboardTextsSet.SWITCH_TO_ALPHA_KEY_LABEL),
+ mKeyboardView.getKeyVisualAttribute());
mEmojiPalettesView.setVisibility(View.VISIBLE);
}
@@ -342,10 +340,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
mState.onCodeInput(code, mLatinIME.getCurrentAutoCapsState());
}
- private boolean isShowingMainKeyboard() {
- return null != mKeyboardView && mKeyboardView.isShown();
- }
-
public boolean isShowingEmojiPalettes() {
return mEmojiPalettesView != null && mEmojiPalettesView.isShown();
}
@@ -378,10 +372,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
}
}
- public boolean isShowingMainKeyboardOrEmojiPalettes() {
- return isShowingMainKeyboard() || isShowingEmojiPalettes();
- }
-
public View onCreateInputView(final boolean isHardwareAcceleratedDrawingEnabled) {
if (mKeyboardView != null) {
mKeyboardView.closing();
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index dd3ab9cce..18e51d392 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -146,6 +146,10 @@ public class KeyboardView extends View {
mPaint.setAntiAlias(true);
}
+ public KeyVisualAttributes getKeyVisualAttribute() {
+ return mKeyVisualAttributes;
+ }
+
private static void blendAlpha(final Paint paint, final int alpha) {
final int color = paint.getColor();
paint.setARGB((paint.getAlpha() * alpha) / Constants.Color.ALPHA_OPAQUE,
diff --git a/java/src/com/android/inputmethod/keyboard/internal/EmojiLayoutParams.java b/java/src/com/android/inputmethod/keyboard/internal/EmojiLayoutParams.java
index 12e063261..d57ea5a94 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/EmojiLayoutParams.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/EmojiLayoutParams.java
@@ -73,9 +73,13 @@ public class EmojiLayoutParams {
ll.setLayoutParams(lp);
}
+ public int getActionBarHeight() {
+ return mEmojiActionBarHeight - mBottomPadding;
+ }
+
public void setActionBarProperties(final LinearLayout ll) {
final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) ll.getLayoutParams();
- lp.height = mEmojiActionBarHeight - mBottomPadding;
+ lp.height = getActionBarHeight();
ll.setLayoutParams(lp);
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyDrawParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyDrawParams.java
index b528b692e..1716fa049 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyDrawParams.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyDrawParams.java
@@ -16,7 +16,6 @@
package com.android.inputmethod.keyboard.internal;
-import android.content.res.ColorStateList;
import android.graphics.Typeface;
import com.android.inputmethod.latin.utils.ResourceUtils;
@@ -33,7 +32,7 @@ public final class KeyDrawParams {
public int mHintLabelSize;
public int mPreviewTextSize;
- public ColorStateList mTextColorStateList;
+ public int mTextColor;
public int mTextInactivatedColor;
public int mTextShadowColor;
public int mHintLetterColor;
@@ -58,7 +57,7 @@ public final class KeyDrawParams {
mHintLabelSize = copyFrom.mHintLabelSize;
mPreviewTextSize = copyFrom.mPreviewTextSize;
- mTextColorStateList = copyFrom.mTextColorStateList;
+ mTextColor = copyFrom.mTextColor;
mTextInactivatedColor = copyFrom.mTextInactivatedColor;
mTextShadowColor = copyFrom.mTextShadowColor;
mHintLetterColor = copyFrom.mHintLetterColor;
@@ -90,8 +89,8 @@ public final class KeyDrawParams {
attr.mShiftedLetterHintRatio, mShiftedLetterHintSize);
mHintLabelSize = selectTextSize(keyHeight, attr.mHintLabelRatio, mHintLabelSize);
mPreviewTextSize = selectTextSize(keyHeight, attr.mPreviewTextRatio, mPreviewTextSize);
- mTextColorStateList =
- attr.mTextColorStateList != null ? attr.mTextColorStateList : mTextColorStateList;
+
+ mTextColor = selectColor(attr.mTextColor, mTextColor);
mTextInactivatedColor = selectColor(attr.mTextInactivatedColor, mTextInactivatedColor);
mTextShadowColor = selectColor(attr.mTextShadowColor, mTextShadowColor);
mHintLetterColor = selectColor(attr.mHintLetterColor, mHintLetterColor);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java b/java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java
index c3e0aa685..df386fce4 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java
@@ -16,7 +16,6 @@
package com.android.inputmethod.keyboard.internal;
-import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.util.SparseIntArray;
@@ -38,7 +37,7 @@ public final class KeyVisualAttributes {
public final float mHintLabelRatio;
public final float mPreviewTextRatio;
- public final ColorStateList mTextColorStateList;
+ public final int mTextColor;
public final int mTextInactivatedColor;
public final int mTextShadowColor;
public final int mHintLetterColor;
@@ -119,7 +118,7 @@ public final class KeyVisualAttributes {
mPreviewTextRatio = ResourceUtils.getFraction(keyAttr,
R.styleable.Keyboard_Key_keyPreviewTextRatio);
- mTextColorStateList = keyAttr.getColorStateList(R.styleable.Keyboard_Key_keyTextColor);
+ mTextColor = keyAttr.getColor(R.styleable.Keyboard_Key_keyTextColor, 0);
mTextInactivatedColor = keyAttr.getColor(
R.styleable.Keyboard_Key_keyTextInactivatedColor, 0);
mTextShadowColor = keyAttr.getColor(R.styleable.Keyboard_Key_keyTextShadowColor, 0);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
index da8bf7d69..79d088f2e 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
@@ -102,7 +102,7 @@ public final class KeyboardIconsSet {
return isValidIconId(iconId) ? ICON_NAMES[iconId] : "unknown<" + iconId + ">";
}
- static int getIconId(final String name) {
+ public static int getIconId(final String name) {
Integer iconId = sNameToIdsMap.get(name);
if (iconId != null) {
return iconId;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
index 89221ba24..976038c10 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
@@ -29,6 +29,8 @@ import java.util.Locale;
public final class KeyboardTextsSet {
public static final String PREFIX_TEXT = "!text/";
+ public static final String SWITCH_TO_ALPHA_KEY_LABEL = "label_to_alpha_key";
+
private static final char BACKSLASH = Constants.CODE_BACKSLASH;
private static final int MAX_STRING_REFERENCE_INDIRECTION = 10;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
index 96acb1551..ed2db07a8 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
@@ -90,7 +90,7 @@ public final class KeyboardTextsTable {
/* 8:20 */ "more_keys_for_s",
/* 9:20 */ "more_keys_for_n",
/* 10:20 */ "label_to_alpha_key",
- /* 11:15 */ "more_keys_for_y",
+ /* 11:14 */ "more_keys_for_y",
/* 12:13 */ "more_keys_for_d",
/* 13:12 */ "more_keys_for_z",
/* 14:10 */ "more_keys_for_t",
@@ -3585,7 +3585,7 @@ public final class KeyboardTextsTable {
private static final Object[] LANGUAGES_AND_TEXTS = {
// "locale", TEXT_ARRAY, /* numberOfNonNullText/lengthOf_TEXT_ARRAY localeName */
"DEFAULT", LANGUAGE_DEFAULT, /* 171/171 default */
- "af", LANGUAGE_af, /* 8/ 12 Afrikaans */
+ "af", LANGUAGE_af, /* 7/ 12 Afrikaans */
"ar", LANGUAGE_ar, /* 58/110 Arabic */
"az", LANGUAGE_az_AZ, /* 8/ 17 Azerbaijani (Azerbaijan) */
"be", LANGUAGE_be_BY, /* 10/ 33 Belarusian (Belarus) */
diff --git a/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java b/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java
deleted file mode 100644
index 1c6a14efe..000000000
--- a/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.latin;
-
-import android.util.Log;
-
-import com.android.inputmethod.latin.makedict.DictEncoder;
-import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
-import com.android.inputmethod.latin.makedict.Ver4DictEncoder;
-import com.android.inputmethod.latin.utils.FileUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Map;
-
-abstract public class AbstractDictionaryWriter {
- /** Used for Log actions from this class */
- private static final String TAG = AbstractDictionaryWriter.class.getSimpleName();
-
- public AbstractDictionaryWriter() {
- }
-
- abstract public void clear();
-
- /**
- * Add a unigram with an optional shortcut to the dictionary.
- * @param word The word to add.
- * @param shortcutTarget A shortcut target for this word, or null if none.
- * @param frequency The frequency for this unigram.
- * @param shortcutFreq The frequency of the shortcut (0~15, with 15 = whitelist). Ignored
- * if shortcutTarget is null.
- * @param isNotAWord true if this is not a word, i.e. shortcut only.
- */
- abstract public void addUnigramWord(final String word, final String shortcutTarget,
- final int frequency, final int shortcutFreq, final boolean isNotAWord);
-
- // TODO: Remove lastModifiedTime after making binary dictionary support forgetting curve.
- abstract public void addBigramWords(final String word0, final String word1,
- final int frequency, final boolean isValid, final long lastModifiedTime);
-
- abstract public void removeBigramWords(final String word0, final String word1);
-
- abstract protected void writeDictionary(final DictEncoder dictEncoder,
- final Map<String, String> attributeMap) throws IOException, UnsupportedFormatException;
-
- public void write(final File file, final Map<String, String> attributeMap) {
- try {
- FileUtils.deleteRecursively(file);
- file.mkdir();
- final DictEncoder dictEncoder = new Ver4DictEncoder(file);
- writeDictionary(dictEncoder, attributeMap);
- } catch (IOException e) {
- Log.e(TAG, "IO exception while writing file", e);
- } catch (UnsupportedFormatException e) {
- Log.e(TAG, "Unsupported format", e);
- }
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index c450a1d4f..851ecc042 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -28,9 +28,9 @@ import com.android.inputmethod.latin.makedict.FormatSpec;
import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
import com.android.inputmethod.latin.makedict.WordProperty;
+import com.android.inputmethod.latin.personalization.PersonalizationHelper;
import com.android.inputmethod.latin.settings.NativeSuggestOptions;
import com.android.inputmethod.latin.utils.CollectionUtils;
-import com.android.inputmethod.latin.utils.FileUtils;
import com.android.inputmethod.latin.utils.JniUtils;
import com.android.inputmethod.latin.utils.LanguageModelParam;
import com.android.inputmethod.latin.utils.StringUtils;
@@ -508,7 +508,9 @@ public final class BinaryDictionary extends Dictionary {
*/
@UsedForTesting
public static int setCurrentTimeForTest(final int currentTime) {
- return setCurrentTimeForTestNative(currentTime);
+ final int currentNativeTimestamp = setCurrentTimeForTestNative(currentTime);
+ PersonalizationHelper.currentTimeChangedForTesting(currentNativeTimestamp);
+ return currentNativeTimestamp;
}
@UsedForTesting
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index a7008379f..acbd919cd 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -229,7 +229,7 @@ final public class BinaryDictionaryGetter {
private static boolean hackCanUseDictionaryFile(final Locale locale, final File f) {
try {
// Read the version of the file
- final DictDecoder dictDecoder = FormatSpec.getDictDecoder(f);
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(f, 0, f.length());
final DictionaryHeader header = dictDecoder.readHeader();
final String version = header.mDictionaryOptions.mAttributes.get(VERSION_KEY);
diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
index ae9bdf3fc..c2941e424 100644
--- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
@@ -78,7 +78,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
public ContactsBinaryDictionary(final Context context, final Locale locale,
final File dictFile) {
super(context, getDictName(NAME, locale, dictFile), locale, Dictionary.TYPE_CONTACTS,
- false /* isUpdatable */, dictFile);
+ dictFile);
mLocale = locale;
mUseFirstLastBigrams = useFirstLastBigramsForLocale(locale);
registerObserver(context);
@@ -114,14 +114,14 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
}
@Override
- public void loadDictionaryAsync() {
- loadDeviceAccountsEmailAddresses();
- loadDictionaryAsyncForUri(ContactsContract.Profile.CONTENT_URI);
+ public void loadInitialContentsLocked() {
+ loadDeviceAccountsEmailAddressesLocked();
+ loadDictionaryForUriLocked(ContactsContract.Profile.CONTENT_URI);
// TODO: Switch this URL to the newer ContactsContract too
- loadDictionaryAsyncForUri(Contacts.CONTENT_URI);
+ loadDictionaryForUriLocked(Contacts.CONTENT_URI);
}
- private void loadDeviceAccountsEmailAddresses() {
+ private void loadDeviceAccountsEmailAddressesLocked() {
final List<String> accountVocabulary =
AccountUtils.getDeviceAccountsEmailAddresses(mContext);
if (accountVocabulary == null || accountVocabulary.isEmpty()) {
@@ -131,12 +131,14 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
if (DEBUG) {
Log.d(TAG, "loadAccountVocabulary: " + word);
}
- super.addWord(word, null /* shortcut */, FREQUENCY_FOR_CONTACTS, 0 /* shortcutFreq */,
- false /* isNotAWord */);
+ runGCIfRequiredLocked(true /* mindsBlockByGC */);
+ addWordDynamicallyLocked(word, FREQUENCY_FOR_CONTACTS, null /* shortcut */,
+ 0 /* shortcutFreq */, false /* isNotAWord */, false /* isBlacklisted */,
+ BinaryDictionary.NOT_A_VALID_TIMESTAMP);
}
}
- private void loadDictionaryAsyncForUri(final Uri uri) {
+ private void loadDictionaryForUriLocked(final Uri uri) {
Cursor cursor = null;
try {
cursor = mContext.getContentResolver().query(uri, PROJECTION, null, null, null);
@@ -145,7 +147,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
}
if (cursor.moveToFirst()) {
sContactCountAtLastRebuild = getContactCount();
- addWords(cursor);
+ addWordsLocked(cursor);
}
} catch (final SQLiteException e) {
Log.e(TAG, "SQLiteException in the remote Contacts process.", e);
@@ -166,12 +168,12 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
return false;
}
- private void addWords(final Cursor cursor) {
+ private void addWordsLocked(final Cursor cursor) {
int count = 0;
while (!cursor.isAfterLast() && count < MAX_CONTACT_COUNT) {
String name = cursor.getString(INDEX_NAME);
if (isValidName(name)) {
- addName(name);
+ addNameLocked(name);
++count;
} else {
if (DEBUG_DUMP) {
@@ -207,7 +209,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
* Adds the words in a name (e.g., firstname/lastname) to the binary dictionary along with their
* bigrams depending on locale.
*/
- private void addName(final String name) {
+ private void addNameLocked(final String name) {
int len = StringUtils.codePointCount(name);
String prevWord = null;
// TODO: Better tokenization for non-Latin writing systems
@@ -226,13 +228,15 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
if (DEBUG) {
Log.d(TAG, "addName " + name + ", " + word + ", " + prevWord);
}
- super.addWord(word, null /* shortcut */, FREQUENCY_FOR_CONTACTS,
- 0 /* shortcutFreq */, false /* isNotAWord */);
- if (!TextUtils.isEmpty(prevWord)) {
- if (mUseFirstLastBigrams) {
- super.addBigram(prevWord, word, FREQUENCY_FOR_CONTACTS_BIGRAM,
- 0 /* lastModifiedTime */);
- }
+ runGCIfRequiredLocked(true /* mindsBlockByGC */);
+ addWordDynamicallyLocked(word, FREQUENCY_FOR_CONTACTS,
+ null /* shortcut */, 0 /* shortcutFreq */, false /* isNotAWord */,
+ false /* isBlacklisted */, BinaryDictionary.NOT_A_VALID_TIMESTAMP);
+ if (!TextUtils.isEmpty(prevWord) && mUseFirstLastBigrams) {
+ runGCIfRequiredLocked(true /* mindsBlockByGC */);
+ addBigramDynamicallyLocked(prevWord, word,
+ FREQUENCY_FOR_CONTACTS_BIGRAM,
+ BinaryDictionary.NOT_A_VALID_TIMESTAMP);
}
prevWord = word;
}
@@ -258,12 +262,12 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
}
@Override
- protected boolean needsToReloadBeforeWriting() {
+ protected boolean needsToReloadAfterCreation() {
return true;
}
@Override
- protected boolean hasContentChanged() {
+ protected boolean haveContentsChanged() {
final long startTime = SystemClock.uptimeMillis();
final int contactCount = getContactCount();
if (contactCount > MAX_CONTACT_COUNT) {
@@ -291,7 +295,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
if (cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
String name = cursor.getString(INDEX_NAME);
- if (isValidName(name) && !isNameInDictionary(name)) {
+ if (isValidName(name) && !isNameInDictionaryLocked(name)) {
if (DEBUG) {
Log.d(TAG, "Contact name missing: " + name + " (runtime = "
+ (SystemClock.uptimeMillis() - startTime) + " ms)");
@@ -321,7 +325,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
/**
* Checks if the words in a name are in the current binary dictionary.
*/
- private boolean isNameInDictionary(final String name) {
+ private boolean isNameInDictionaryLocked(final String name) {
int len = StringUtils.codePointCount(name);
String prevWord = null;
for (int i = 0; i < len; i++) {
@@ -332,11 +336,11 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
final int wordLen = StringUtils.codePointCount(word);
if (wordLen < MAX_WORD_LENGTH && wordLen > 1) {
if (!TextUtils.isEmpty(prevWord) && mUseFirstLastBigrams) {
- if (!super.isValidBigramLocked(prevWord, word)) {
+ if (!isValidBigramLocked(prevWord, word)) {
return false;
}
} else {
- if (!super.isValidWordLocked(word)) {
+ if (!isValidWordLocked(word)) {
return false;
}
}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
index 14e1baf41..d6178fcee 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
@@ -28,6 +28,7 @@ import com.android.inputmethod.latin.personalization.PersonalizationHelper;
import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
import com.android.inputmethod.latin.settings.SettingsValues;
import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.ExecutorUtils;
import com.android.inputmethod.latin.utils.LanguageModelParam;
import java.io.File;
@@ -35,6 +36,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
@@ -137,7 +139,8 @@ public class DictionaryFacilitatorForSuggest {
@UsedForTesting
public DictionaryFacilitatorForSuggest(final Context context, final Locale locale,
- final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles) {
+ final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles,
+ final Map<String, Map<String, String>> additionalDictAttributes) {
mContext = context;
mLocale = locale;
mLatchForWaitingLoadingMainDictionary = new CountDownLatch(0);
@@ -154,6 +157,10 @@ public class DictionaryFacilitatorForSuggest {
userHistoryDictionary.reloadDictionaryIfRequired();
userHistoryDictionary.waitAllTasksForTests();
setUserHistoryDictionary(userHistoryDictionary);
+ if (additionalDictAttributes.containsKey(dictType)) {
+ userHistoryDictionary.clearAndFlushDictionaryWithAdditionalAttributes(
+ additionalDictAttributes.get(dictType));
+ }
} else if (dictType.equals(Dictionary.TYPE_PERSONALIZATION)) {
final PersonalizationDictionary personalizationDictionary =
PersonalizationHelper.getPersonalizationDictionary(context, locale);
@@ -162,6 +169,10 @@ public class DictionaryFacilitatorForSuggest {
personalizationDictionary.reloadDictionaryIfRequired();
personalizationDictionary.waitAllTasksForTests();
setPersonalizationDictionary(personalizationDictionary);
+ if (additionalDictAttributes.containsKey(dictType)) {
+ personalizationDictionary.clearAndFlushDictionaryWithAdditionalAttributes(
+ additionalDictAttributes.get(dictType));
+ }
} else if (dictType.equals(Dictionary.TYPE_USER)) {
final File file = dictionaryFiles.get(dictType);
final UserBinaryDictionary userDictionary = new UserBinaryDictionary(
@@ -204,8 +215,7 @@ public class DictionaryFacilitatorForSuggest {
if (listener != null) {
listener.onUpdateMainDictionaryAvailability(hasMainDictionary());
}
- new Thread("InitializeBinaryDictionary") {
- @Override
+ ExecutorUtils.getExecutor("InitializeBinaryDictionary").execute(new Runnable() {
public void run() {
final DictionaryCollection newMainDict =
DictionaryFactory.createMainDictionaryFromManager(context, locale);
@@ -215,7 +225,7 @@ public class DictionaryFacilitatorForSuggest {
}
mLatchForWaitingLoadingMainDictionary.countDown();
}
- }.start();
+ });
}
// The main dictionary could have been loaded asynchronously. Don't cache the return value
diff --git a/java/src/com/android/inputmethod/latin/DictionaryWriter.java b/java/src/com/android/inputmethod/latin/DictionaryWriter.java
deleted file mode 100644
index b931c66d1..000000000
--- a/java/src/com/android/inputmethod/latin/DictionaryWriter.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.latin;
-
-import com.android.inputmethod.latin.makedict.DictEncoder;
-import com.android.inputmethod.latin.makedict.FormatSpec;
-import com.android.inputmethod.latin.makedict.FusionDictionary;
-import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
-import com.android.inputmethod.latin.makedict.ProbabilityInfo;
-import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
-import com.android.inputmethod.latin.utils.CollectionUtils;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * An in memory dictionary for memorizing entries and writing a binary dictionary.
- */
-public class DictionaryWriter extends AbstractDictionaryWriter {
- private static final int BINARY_DICT_VERSION = FormatSpec.VERSION4;
- private static final FormatSpec.FormatOptions FORMAT_OPTIONS =
- new FormatSpec.FormatOptions(BINARY_DICT_VERSION, false /* hasTimestamp */);
-
- private FusionDictionary mFusionDictionary;
-
- public DictionaryWriter() {
- clear();
- }
-
- @Override
- public void clear() {
- final HashMap<String, String> attributes = CollectionUtils.newHashMap();
- mFusionDictionary = new FusionDictionary(new PtNodeArray(),
- new FusionDictionary.DictionaryOptions(attributes));
- }
-
- /**
- * Adds a word unigram to the fusion dictionary.
- */
- // TODO: Create "cache dictionary" to cache fresh words for frequently updated dictionaries,
- // considering performance regression.
- @Override
- public void addUnigramWord(final String word, final String shortcutTarget,
- final int probability, final int shortcutProbability, final boolean isNotAWord) {
- if (shortcutTarget == null) {
- mFusionDictionary.add(word, new ProbabilityInfo(probability), null, isNotAWord);
- } else {
- // TODO: Do this in the subclass, with this class taking an arraylist.
- final ArrayList<WeightedString> shortcutTargets = CollectionUtils.newArrayList();
- shortcutTargets.add(new WeightedString(shortcutTarget, shortcutProbability));
- mFusionDictionary.add(word, new ProbabilityInfo(probability), shortcutTargets,
- isNotAWord);
- }
- }
-
- @Override
- public void addBigramWords(final String word0, final String word1, final int probability,
- final boolean isValid, final long lastModifiedTime) {
- mFusionDictionary.setBigram(word0, word1, new ProbabilityInfo(probability));
- }
-
- @Override
- public void removeBigramWords(final String word0, final String word1) {
- // This class don't support removing bigram words.
- }
-
- @Override
- protected void writeDictionary(final DictEncoder dictEncoder,
- final Map<String, String> attributeMap) throws IOException, UnsupportedFormatException {
- for (final Map.Entry<String, String> entry : attributeMap.entrySet()) {
- mFusionDictionary.addOptionAttribute(entry.getKey(), entry.getValue());
- }
- dictEncoder.writeDictionary(mFusionDictionary, FORMAT_OPTIONS);
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index f9ab9419b..26545acbd 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -29,9 +29,9 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.utils.AsyncResultHolder;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.CombinedFormatUtils;
+import com.android.inputmethod.latin.utils.ExecutorUtils;
import com.android.inputmethod.latin.utils.FileUtils;
import com.android.inputmethod.latin.utils.LanguageModelParam;
-import com.android.inputmethod.latin.utils.PrioritizedSerialExecutor;
import java.io.File;
import java.util.ArrayList;
@@ -64,6 +64,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
private static final int TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS = 100;
private static final int TIMEOUT_FOR_READ_OPS_FOR_TESTS_IN_MILLISECONDS = 10000;
+ private static final int DEFAULT_MAX_UNIGRAM_COUNT = 10000;
+ private static final int DEFAULT_MAX_BIGRAM_COUNT = 10000;
+
/**
* The maximum length of a word in this dictionary.
*/
@@ -80,9 +83,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
private static final ConcurrentHashMap<String, DictionaryUpdateController>
sDictNameDictionaryUpdateControllerMap = CollectionUtils.newConcurrentHashMap();
- private static final ConcurrentHashMap<String, PrioritizedSerialExecutor>
- sDictNameExecutorMap = CollectionUtils.newConcurrentHashMap();
-
/** The application context. */
protected final Context mContext;
@@ -92,10 +92,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
*/
private BinaryDictionary mBinaryDictionary;
- // TODO: Remove and handle dictionaries in native code.
- /** The in-memory dictionary used to generate the binary dictionary. */
- protected AbstractDictionaryWriter mDictionaryWriter;
-
/**
* The name of this dictionary, used as a part of the filename for storing the binary
* dictionary. Multiple dictionary instances with the same name is supported, with access
@@ -106,9 +102,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
/** Dictionary locale */
private final Locale mLocale;
- /** Whether to support dynamically updating the dictionary */
- private final boolean mIsUpdatable;
-
/** Dictionary file */
private final File mDictFile;
@@ -128,23 +121,22 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
new AtomicReference<Runnable>();
/**
- * Abstract method for loading the unigrams and bigrams of a given dictionary in a background
- * thread.
+ * Abstract method for loading initial contents of a given dictionary.
*/
- protected abstract void loadDictionaryAsync();
+ protected abstract void loadInitialContentsLocked();
/**
- * Indicates that the source dictionary content has changed and a rebuild of the binary file is
- * required. If it returns false, the next reload will only read the current binary dictionary
- * from file. Note that the shared binary dictionary is locked when this is called.
+ * Indicates that the source dictionary contents have changed and a rebuild of the binary file
+ * is required. If it returns false, the next reload will only read the current binary
+ * dictionary from file. Note that the shared binary dictionary is locked when this is called.
*/
- protected abstract boolean hasContentChanged();
+ protected abstract boolean haveContentsChanged();
private boolean matchesExpectedBinaryDictFormatVersionForThisType(final int formatVersion) {
return formatVersion == FormatSpec.VERSION4;
}
- public boolean isValidDictionary() {
+ public boolean isValidDictionaryLocked() {
return mBinaryDictionary.isValidDictionary();
}
@@ -164,42 +156,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
/**
- * Gets the executor for the given dictionary name.
- */
- private static PrioritizedSerialExecutor getExecutor(final String dictName) {
- PrioritizedSerialExecutor executor = sDictNameExecutorMap.get(dictName);
- if (executor == null) {
- synchronized(sDictNameExecutorMap) {
- executor = new PrioritizedSerialExecutor();
- sDictNameExecutorMap.put(dictName, executor);
- }
- }
- return executor;
- }
-
- /**
- * Shutdowns all executors and removes all executors from the executor map for testing.
- */
- @UsedForTesting
- public static void shutdownAllExecutors() {
- synchronized(sDictNameExecutorMap) {
- for (final PrioritizedSerialExecutor executor : sDictNameExecutorMap.values()) {
- executor.shutdown();
- sDictNameExecutorMap.remove(executor);
- }
- }
- }
-
- private static AbstractDictionaryWriter getDictionaryWriter(
- final boolean isDynamicPersonalizationDictionary) {
- if (isDynamicPersonalizationDictionary) {
- return null;
- } else {
- return new DictionaryWriter();
- }
- }
-
- /**
* Creates a new expandable binary dictionary.
*
* @param context The application context of the parent.
@@ -207,24 +163,18 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
* name is supported.
* @param locale the dictionary locale.
* @param dictType the dictionary type, as a human-readable string
- * @param isUpdatable whether to support dynamically updating the dictionary. Please note that
- * dynamic dictionary has negative effects on memory space and computation time.
* @param dictFile dictionary file path. if null, use default dictionary path based on
* dictionary type.
*/
public ExpandableBinaryDictionary(final Context context, final String dictName,
- final Locale locale, final String dictType, final boolean isUpdatable,
- final File dictFile) {
+ final Locale locale, final String dictType, final File dictFile) {
super(dictType);
mDictName = dictName;
mContext = context;
mLocale = locale;
- mIsUpdatable = isUpdatable;
mDictFile = getDictFile(context, dictName, dictFile);
mBinaryDictionary = null;
mDictNameDictionaryUpdateController = getDictionaryUpdateController(dictName);
- // Currently, only dynamic personalization dictionary is updatable.
- mDictionaryWriter = getDictionaryWriter(isUpdatable);
}
public static File getDictFile(final Context context, final String dictName,
@@ -243,20 +193,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
*/
@Override
public void close() {
- getExecutor(mDictName).execute(new Runnable() {
- @Override
- public void run() {
- if (mBinaryDictionary!= null) {
- mBinaryDictionary.close();
- mBinaryDictionary = null;
- }
- }
- });
- }
-
- protected void closeBinaryDictionary() {
- // Ensure that no other threads are accessing the local binary dictionary.
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
if (mBinaryDictionary != null) {
@@ -273,6 +210,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
attributeMap.put(DictionaryHeader.DICTIONARY_LOCALE_KEY, mLocale.toString());
attributeMap.put(DictionaryHeader.DICTIONARY_VERSION_KEY,
String.valueOf(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())));
+ attributeMap.put(DictionaryHeader.MAX_UNIGRAM_COUNT_KEY,
+ String.valueOf(DEFAULT_MAX_UNIGRAM_COUNT));
+ attributeMap.put(DictionaryHeader.MAX_BIGRAM_COUNT_KEY,
+ String.valueOf(DEFAULT_MAX_BIGRAM_COUNT));
return attributeMap;
}
@@ -286,65 +227,52 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
mBinaryDictionary = null;
}
+ private void createBinaryDictionaryLocked() {
+ BinaryDictionary.createEmptyDictFile(mDictFile.getAbsolutePath(),
+ DICTIONARY_FORMAT_VERSION, mLocale, getHeaderAttributeMap());
+ }
+
+ private void openBinaryDictionaryLocked() {
+ mBinaryDictionary = new BinaryDictionary(
+ mDictFile.getAbsolutePath(), 0 /* offset */, mDictFile.length(),
+ true /* useFullEditDistance */, mLocale, mDictType, true /* isUpdatable */);
+ }
+
protected void clear() {
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
- if (mDictionaryWriter == null) {
- removeBinaryDictionaryLocked();
- BinaryDictionary.createEmptyDictFile(mDictFile.getAbsolutePath(),
- DICTIONARY_FORMAT_VERSION, mLocale, getHeaderAttributeMap());
- mBinaryDictionary = new BinaryDictionary(
- mDictFile.getAbsolutePath(), 0 /* offset */, mDictFile.length(),
- true /* useFullEditDistance */, mLocale, mDictType, mIsUpdatable);
- } else {
- mDictionaryWriter.clear();
- }
+ removeBinaryDictionaryLocked();
+ createBinaryDictionaryLocked();
+ openBinaryDictionaryLocked();
}
});
}
/**
- * Adds a word unigram to the dictionary. Used for loading a dictionary.
- * @param word The word to add.
- * @param shortcutTarget A shortcut target for this word, or null if none.
- * @param frequency The frequency for this unigram.
- * @param shortcutFreq The frequency of the shortcut (0~15, with 15 = whitelist). Ignored
- * if shortcutTarget is null.
- * @param isNotAWord true if this is not a word, i.e. shortcut only.
- */
- protected void addWord(final String word, final String shortcutTarget,
- final int frequency, final int shortcutFreq, final boolean isNotAWord) {
- mDictionaryWriter.addUnigramWord(word, shortcutTarget, frequency, shortcutFreq, isNotAWord);
- }
-
- /**
- * Adds a word bigram in the dictionary. Used for loading a dictionary.
- */
- protected void addBigram(final String prevWord, final String word, final int frequency,
- final long lastModifiedTime) {
- mDictionaryWriter.addBigramWords(prevWord, word, frequency, true /* isValid */,
- lastModifiedTime);
- }
-
- /**
* Check whether GC is needed and run GC if required.
*/
protected void runGCIfRequired(final boolean mindsBlockByGC) {
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
- runGCIfRequiredInternalLocked(mindsBlockByGC);
+ runGCAfterAllPrioritizedTasksIfRequiredLocked(mindsBlockByGC);
}
});
}
- private void runGCIfRequiredInternalLocked(final boolean mindsBlockByGC) {
- // Calls to needsToRunGC() need to be serialized.
+ protected void runGCIfRequiredLocked(final boolean mindsBlockByGC) {
+ if (mBinaryDictionary.needsToRunGC(mindsBlockByGC)) {
+ mBinaryDictionary.flushWithGC();
+ }
+ }
+
+ private void runGCAfterAllPrioritizedTasksIfRequiredLocked(final boolean mindsBlockByGC) {
+ // needsToRunGC() have to be called with lock.
if (mBinaryDictionary.needsToRunGC(mindsBlockByGC)) {
if (setProcessingLargeTaskIfNot()) {
// Run GC after currently existing time sensitive operations.
- getExecutor(mDictName).executePrioritized(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).executePrioritized(new Runnable() {
@Override
public void run() {
try {
@@ -364,52 +292,50 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
protected void addWordDynamically(final String word, final int frequency,
final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord,
final boolean isBlacklisted, final int timestamp) {
- if (!mIsUpdatable) {
- Log.w(TAG, "addWordDynamically is called for non-updatable dictionary: " + mDictName);
- return;
- }
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
- runGCIfRequiredInternalLocked(true /* mindsBlockByGC */);
- mBinaryDictionary.addUnigramWord(word, frequency, shortcutTarget, shortcutFreq,
+ runGCAfterAllPrioritizedTasksIfRequiredLocked(true /* mindsBlockByGC */);
+ addWordDynamicallyLocked(word, frequency, shortcutTarget, shortcutFreq,
isNotAWord, isBlacklisted, timestamp);
}
});
}
+ protected void addWordDynamicallyLocked(final String word, final int frequency,
+ final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord,
+ final boolean isBlacklisted, final int timestamp) {
+ mBinaryDictionary.addUnigramWord(word, frequency, shortcutTarget, shortcutFreq,
+ isNotAWord, isBlacklisted, timestamp);
+ }
+
/**
* Dynamically adds a word bigram in the dictionary. May overwrite an existing entry.
*/
protected void addBigramDynamically(final String word0, final String word1,
final int frequency, final int timestamp) {
- if (!mIsUpdatable) {
- Log.w(TAG, "addBigramDynamically is called for non-updatable dictionary: "
- + mDictName);
- return;
- }
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
- runGCIfRequiredInternalLocked(true /* mindsBlockByGC */);
- mBinaryDictionary.addBigramWords(word0, word1, frequency, timestamp);
+ runGCAfterAllPrioritizedTasksIfRequiredLocked(true /* mindsBlockByGC */);
+ addBigramDynamicallyLocked(word0, word1, frequency, timestamp);
}
});
}
+ protected void addBigramDynamicallyLocked(final String word0, final String word1,
+ final int frequency, final int timestamp) {
+ mBinaryDictionary.addBigramWords(word0, word1, frequency, timestamp);
+ }
+
/**
* Dynamically remove a word bigram in the dictionary.
*/
protected void removeBigramDynamically(final String word0, final String word1) {
- if (!mIsUpdatable) {
- Log.w(TAG, "removeBigramDynamically is called for non-updatable dictionary: "
- + mDictName);
- return;
- }
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
- runGCIfRequiredInternalLocked(true /* mindsBlockByGC */);
+ runGCAfterAllPrioritizedTasksIfRequiredLocked(true /* mindsBlockByGC */);
mBinaryDictionary.removeBigramWords(word0, word1);
}
});
@@ -425,12 +351,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
protected void addMultipleDictionaryEntriesDynamically(
final ArrayList<LanguageModelParam> languageModelParams,
final AddMultipleDictionaryEntriesCallback callback) {
- if (!mIsUpdatable) {
- Log.w(TAG, "addMultipleDictionaryEntriesDynamically is called for non-updatable " +
- "dictionary: " + mDictName);
- return;
- }
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
final boolean locked = setProcessingLargeTaskIfNot();
@@ -461,7 +382,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
final AsyncResultHolder<ArrayList<SuggestedWordInfo>> holder =
new AsyncResultHolder<ArrayList<SuggestedWordInfo>>();
- getExecutor(mDictName).executePrioritized(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).executePrioritized(new Runnable() {
@Override
public void run() {
if (mBinaryDictionary == null) {
@@ -492,15 +413,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@Override
public boolean isValidWord(final String word) {
reloadDictionaryIfRequired();
- return isValidWordInner(word);
- }
-
- protected boolean isValidWordInner(final String word) {
if (processingLargeTask()) {
return false;
}
final AsyncResultHolder<Boolean> holder = new AsyncResultHolder<Boolean>();
- getExecutor(mDictName).executePrioritized(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).executePrioritized(new Runnable() {
@Override
public void run() {
holder.set(isValidWordLocked(word));
@@ -532,7 +449,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
* Loads the current binary dictionary from internal storage. Assumes the dictionary file
* exists.
*/
- private void loadBinaryDictionary() {
+ private void loadBinaryDictionaryLocked() {
if (DEBUG) {
Log.d(TAG, "Loading binary dictionary: " + mDictName + " request="
+ mDictNameDictionaryUpdateController.mLastUpdateRequestTime + " update="
@@ -548,65 +465,40 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
} catch (InterruptedException e) {
}
}
-
- final String filename = mDictFile.getAbsolutePath();
- final long length = mDictFile.length();
-
- // Build the new binary dictionary
- final BinaryDictionary newBinaryDictionary = new BinaryDictionary(filename, 0 /* offset */,
- length, true /* useFullEditDistance */, null, mDictType, mIsUpdatable);
-
- // Ensure all threads accessing the current dictionary have finished before
- // swapping in the new one.
- // TODO: Ensure multi-thread assignment of mBinaryDictionary.
final BinaryDictionary oldBinaryDictionary = mBinaryDictionary;
- getExecutor(mDictName).executePrioritized(new Runnable() {
- @Override
- public void run() {
- mBinaryDictionary = newBinaryDictionary;
- if (oldBinaryDictionary != null) {
- oldBinaryDictionary.close();
- }
- }
- });
+ openBinaryDictionaryLocked();
+ if (oldBinaryDictionary != null) {
+ oldBinaryDictionary.close();
+ }
}
/**
* Abstract method for checking if it is required to reload the dictionary before writing
* a binary dictionary.
*/
- abstract protected boolean needsToReloadBeforeWriting();
+ abstract protected boolean needsToReloadAfterCreation();
/**
- * Writes a new binary dictionary based on the contents of the fusion dictionary.
+ * Create a new binary dictionary and load initial contents.
*/
- private void writeBinaryDictionary() {
+ private void createNewDictionaryLocked() {
if (DEBUG) {
Log.d(TAG, "Generating binary dictionary: " + mDictName + " request="
+ mDictNameDictionaryUpdateController.mLastUpdateRequestTime + " update="
+ mDictNameDictionaryUpdateController.mLastUpdateTime);
}
- if (needsToReloadBeforeWriting()) {
- mDictionaryWriter.clear();
- loadDictionaryAsync();
- mDictionaryWriter.write(mDictFile, getHeaderAttributeMap());
+ removeBinaryDictionaryLocked();
+ createBinaryDictionaryLocked();
+ openBinaryDictionaryLocked();
+ loadInitialContentsLocked();
+ mBinaryDictionary.flushWithGC();
+ }
+
+ private void flushDictionaryLocked() {
+ if (mBinaryDictionary.needsToRunGC(false /* mindsBlockByGC */)) {
+ mBinaryDictionary.flushWithGC();
} else {
- if (mBinaryDictionary == null || !isValidDictionary()
- // TODO: remove the check below
- || !matchesExpectedBinaryDictFormatVersionForThisType(
- mBinaryDictionary.getFormatVersion())) {
- if (mDictFile.exists() && !FileUtils.deleteRecursively(mDictFile)) {
- Log.e(TAG, "Can't remove a file: " + mDictFile.getName());
- }
- BinaryDictionary.createEmptyDictFile(mDictFile.getAbsolutePath(),
- DICTIONARY_FORMAT_VERSION, mLocale, getHeaderAttributeMap());
- } else {
- if (mBinaryDictionary.needsToRunGC(false /* mindsBlockByGC */)) {
- mBinaryDictionary.flushWithGC();
- } else {
- mBinaryDictionary.flush();
- }
- }
+ mBinaryDictionary.flush();
}
}
@@ -662,57 +554,43 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
private final void reloadDictionary() {
// Ensure that only one thread attempts to read or write to the shared binary dictionary
// file at the same time.
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
try {
final long time = System.currentTimeMillis();
- final boolean dictionaryFileExists = dictionaryFileExists();
- if (mDictNameDictionaryUpdateController.isOutOfDate()
- || !dictionaryFileExists) {
- // If the shared dictionary file does not exist or is out of date, the
- // first instance that acquires the lock will generate a new one.
- if (hasContentChanged() || !dictionaryFileExists) {
- // If the source content has changed or the dictionary does not exist,
- // rebuild the binary dictionary. Empty dictionaries are supported (in
- // the case where loadDictionaryAsync() adds nothing) in order to
- // provide a uniform framework.
- mDictNameDictionaryUpdateController.mLastUpdateTime = time;
- writeBinaryDictionary();
- loadBinaryDictionary();
- } else {
- // If not, the reload request was unnecessary so revert
- // LastUpdateRequestTime to LastUpdateTime.
- mDictNameDictionaryUpdateController.mLastUpdateRequestTime =
- mDictNameDictionaryUpdateController.mLastUpdateTime;
- }
+ final boolean openedDictIsOutOfDate =
+ mDictNameDictionaryUpdateController.isOutOfDate();
+ if (!dictionaryFileExists()
+ || (openedDictIsOutOfDate && haveContentsChanged())) {
+ // If the shared dictionary file does not exist or is out of date and
+ // contents have been updated, the first instance that acquires the lock
+ // will generate a new one
+ mDictNameDictionaryUpdateController.mLastUpdateTime = time;
+ createNewDictionaryLocked();
+ } else if (openedDictIsOutOfDate) {
+ // If not, the reload request was unnecessary so revert
+ // LastUpdateRequestTime to LastUpdateTime.
+ mDictNameDictionaryUpdateController.mLastUpdateRequestTime =
+ mDictNameDictionaryUpdateController.mLastUpdateTime;
} else if (mBinaryDictionary == null ||
mPerInstanceDictionaryUpdateController.mLastUpdateTime
< mDictNameDictionaryUpdateController.mLastUpdateTime) {
// Otherwise, if the local dictionary is older than the shared dictionary,
// load the shared dictionary.
- loadBinaryDictionary();
+ loadBinaryDictionaryLocked();
}
- // If we just loaded the binary dictionary, then mBinaryDictionary is not
- // up-to-date yet so it's useless to test it right away. Schedule the check
- // for right after it's loaded instead.
- getExecutor(mDictName).executePrioritized(new Runnable() {
- @Override
- public void run() {
- if (mBinaryDictionary != null && !(isValidDictionary()
- // TODO: remove the check below
- && matchesExpectedBinaryDictFormatVersionForThisType(
- mBinaryDictionary.getFormatVersion()))) {
- // Binary dictionary or its format version is not valid. Regenerate
- // the dictionary file. writeBinaryDictionary will remove the
- // existing files if appropriate.
- mDictNameDictionaryUpdateController.mLastUpdateTime = time;
- writeBinaryDictionary();
- loadBinaryDictionary();
- }
- mPerInstanceDictionaryUpdateController.mLastUpdateTime = time;
- }
- });
+ if (mBinaryDictionary != null && !(isValidDictionaryLocked()
+ // TODO: remove the check below
+ && matchesExpectedBinaryDictFormatVersionForThisType(
+ mBinaryDictionary.getFormatVersion()))) {
+ // Binary dictionary or its format version is not valid. Regenerate
+ // the dictionary file. writeBinaryDictionary will remove the
+ // existing files if appropriate.
+ mDictNameDictionaryUpdateController.mLastUpdateTime = time;
+ createNewDictionaryLocked();
+ }
+ mPerInstanceDictionaryUpdateController.mLastUpdateTime = time;
} finally {
mDictNameDictionaryUpdateController.mProcessingLargeTask.set(false);
}
@@ -726,17 +604,17 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
/**
- * Generate binary dictionary using DictionaryWriter.
+ * Flush binary dictionary to dictionary file.
*/
protected void asyncFlushBinaryDictionary() {
final Runnable newTask = new Runnable() {
@Override
public void run() {
- writeBinaryDictionary();
+ flushDictionaryLocked();
}
};
final Runnable oldTask = mUnfinishedFlushingTask.getAndSet(newTask);
- getExecutor(mDictName).replaceAndExecute(oldTask, newTask);
+ ExecutorUtils.getExecutor(mDictName).replaceAndExecute(oldTask, newTask);
}
/**
@@ -757,7 +635,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@UsedForTesting
public boolean isInUnderlyingBinaryDictionaryForTests(final String word) {
final AsyncResultHolder<Boolean> holder = new AsyncResultHolder<Boolean>();
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
if (mDictType == Dictionary.TYPE_USER_HISTORY) {
@@ -771,7 +649,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@UsedForTesting
public void waitAllTasksForTests() {
final CountDownLatch countDownLatch = new CountDownLatch(1);
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
countDownLatch.countDown();
@@ -787,7 +665,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@UsedForTesting
public void dumpAllWordsForDebug() {
reloadDictionaryIfRequired();
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
Log.d(TAG, "Dump dictionary: " + mDictName);
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 793c1c4ac..4c2454c32 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -172,7 +172,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
public void onCreate() {
- final Resources res = getOwnerInstance().getResources();
+ final LatinIME latinIme = getOwnerInstance();
+ if (latinIme == null) {
+ return;
+ }
+ final Resources res = latinIme.getResources();
mDelayUpdateSuggestions = res.getInteger(R.integer.config_delay_update_suggestions);
mDelayUpdateShiftState = res.getInteger(R.integer.config_delay_update_shift_state);
mDoubleSpacePeriodTimeout =
@@ -182,6 +186,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void handleMessage(final Message msg) {
final LatinIME latinIme = getOwnerInstance();
+ if (latinIme == null) {
+ return;
+ }
final KeyboardSwitcher switcher = latinIme.mKeyboardSwitcher;
switch (msg.what) {
case MSG_UPDATE_SUGGESTION_STRIP:
@@ -239,7 +246,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
public void postResumeSuggestions() {
- if (!getOwnerInstance().mSettings.getCurrent().isSuggestionStripVisible()) {
+ final LatinIME latinIme = getOwnerInstance();
+ if (latinIme == null) {
+ return;
+ }
+ if (!latinIme.mSettings.getCurrent().isSuggestionStripVisible()) {
return;
}
removeMessages(MSG_RESUME_SUGGESTIONS);
@@ -326,6 +337,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
resetPendingImsCallback();
mIsOrientationChanging = true;
final LatinIME latinIme = getOwnerInstance();
+ if (latinIme == null) {
+ return;
+ }
if (latinIme.isInputViewShown()) {
latinIme.mKeyboardSwitcher.saveKeyboardState();
}
@@ -362,8 +376,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mPendingSuccessiveImsCallback = true;
}
final LatinIME latinIme = getOwnerInstance();
- executePendingImsCallback(latinIme, editorInfo, restarting);
- latinIme.onStartInputInternal(editorInfo, restarting);
+ if (latinIme != null) {
+ executePendingImsCallback(latinIme, editorInfo, restarting);
+ latinIme.onStartInputInternal(editorInfo, restarting);
+ }
}
}
@@ -381,9 +397,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
PENDING_IMS_CALLBACK_DURATION);
}
final LatinIME latinIme = getOwnerInstance();
- executePendingImsCallback(latinIme, editorInfo, restarting);
- latinIme.onStartInputViewInternal(editorInfo, restarting);
- mAppliedEditorInfo = editorInfo;
+ if (latinIme != null) {
+ executePendingImsCallback(latinIme, editorInfo, restarting);
+ latinIme.onStartInputViewInternal(editorInfo, restarting);
+ mAppliedEditorInfo = editorInfo;
+ }
}
}
@@ -393,8 +411,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mHasPendingFinishInputView = true;
} else {
final LatinIME latinIme = getOwnerInstance();
- latinIme.onFinishInputViewInternal(finishingInput);
- mAppliedEditorInfo = null;
+ if (latinIme != null) {
+ latinIme.onFinishInputViewInternal(finishingInput);
+ mAppliedEditorInfo = null;
+ }
}
}
@@ -404,8 +424,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mHasPendingFinishInput = true;
} else {
final LatinIME latinIme = getOwnerInstance();
- executePendingImsCallback(latinIme, null, false);
- latinIme.onFinishInputInternal();
+ if (latinIme != null) {
+ executePendingImsCallback(latinIme, null, false);
+ latinIme.onFinishInputInternal();
+ }
}
}
}
@@ -857,7 +879,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
// This will set the punctuation suggestions if next word suggestion is off;
// otherwise it will clear the suggestion strip.
- setNeutralSuggestionStripInternal(false /* needsInputViewShown */);
+ setNeutralSuggestionStripInternal();
mHandler.cancelUpdateSuggestionStrip();
mHandler.cancelDoubleSpacePeriodTimer();
@@ -1022,23 +1044,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
null /* rawSuggestions */, false /* typedWordValid */, false /* willAutoCorrect */,
false /* isObsoleteSuggestions */, false /* isPrediction */);
// When in fullscreen mode, show completions generated by the application forcibly
- setSuggestedWords(suggestedWords, true /* isSuggestionStripVisible */,
- true /* needsInputViewShown */);
+ setSuggestedWords(suggestedWords, true /* isSuggestionStripVisible */);
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.latinIME_onDisplayCompletions(applicationSpecifiedCompletions);
}
}
- private void setSuggestionStripShownInternal(final boolean isSuggestionStripVisible,
- final boolean needsInputViewShown) {
+ private void setSuggestionStripShownInternal(final boolean isSuggestionStripVisible) {
// TODO: Modify this if we support suggestions with hard keyboard
if (!onEvaluateInputViewShown() || !hasSuggestionStripView()) {
return;
}
- final boolean inputViewShown = mKeyboardSwitcher.isShowingMainKeyboardOrEmojiPalettes();
- final boolean shouldShowSuggestions = isSuggestionStripVisible
- && (needsInputViewShown ? inputViewShown : true);
- if (shouldShowSuggestions) {
+ if (isSuggestionStripVisible) {
mSuggestionStripView.setVisibility(View.VISIBLE);
} else {
mSuggestionStripView.setVisibility(isFullscreenMode() ? View.GONE : View.INVISIBLE);
@@ -1325,8 +1342,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Nothing to do so far.
}
- // TODO[IL]: Define a clear interface for this
- public boolean isSuggestionStripVisible() {
+ private boolean isSuggestionStripVisible() {
if (!hasSuggestionStripView()) {
return false;
}
@@ -1350,7 +1366,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return currentSettings.isSuggestionsRequested();
}
- @Override
public boolean hasSuggestionStripView() {
return null != mSuggestionStripView;
}
@@ -1370,7 +1385,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// TODO[IL]: Define a clear interface for this
public void setSuggestedWords(final SuggestedWords suggestedWords,
- final boolean isSuggestionStripVisible, final boolean needsInputViewShown) {
+ final boolean isSuggestionStripVisible) {
mInputLogic.setSuggestedWords(suggestedWords);
if (!hasSuggestionStripView()) {
return;
@@ -1390,7 +1405,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
SubtypeLocaleUtils.isRtlLanguage(mSubtypeSwitcher.getCurrentSubtype()));
}
mKeyboardSwitcher.onAutoCorrectionStateChanged(suggestedWords.mWillAutoCorrect);
- setSuggestionStripShownInternal(isSuggestionStripVisible, needsInputViewShown);
+ setSuggestionStripShownInternal(isSuggestionStripVisible);
}
// TODO[IL]: Move this out of LatinIME.
@@ -1476,8 +1491,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
setNeutralSuggestionStrip();
} else {
mInputLogic.mWordComposer.setAutoCorrection(autoCorrection);
- setSuggestedWords(
- suggestedWords, isSuggestionStripVisible(), true /* needsInputViewShown */);
+ setSuggestedWords(suggestedWords, isSuggestionStripVisible());
}
// Cache the auto-correction in accessibility code so we can speak it if the user
// touches a key that will insert it.
@@ -1506,14 +1520,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// punctuation suggestions (if it's disabled).
@Override
public void setNeutralSuggestionStrip() {
- setNeutralSuggestionStripInternal(true /* needsInputViewShown */);
+ setNeutralSuggestionStripInternal();
}
- private void setNeutralSuggestionStripInternal(final boolean needsInputViewShown) {
+ private void setNeutralSuggestionStripInternal() {
final SettingsValues currentSettings = mSettings.getCurrent();
final SuggestedWords neutralSuggestions = currentSettings.mBigramPredictionEnabled
? SuggestedWords.EMPTY : currentSettings.mSpacingAndPunctuations.mSuggestPuncList;
- setSuggestedWords(neutralSuggestions, isSuggestionStripVisible(), needsInputViewShown);
+ setSuggestedWords(neutralSuggestions, isSuggestionStripVisible());
}
// TODO: Make this private
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index 30b20a335..323256d1c 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -483,12 +483,16 @@ public final class RichInputConnection {
*
* @param start the character index where the selection should start.
* @param end the character index where the selection should end.
- * @return Returns true on success, false if the input connection is no longer valid either when
- * setting the selection or when retrieving the text cache at that point.
+ * @return Returns true on success, false on failure: either the input connection is no longer
+ * valid when setting the selection or when retrieving the text cache at that point, or
+ * invalid arguments were passed.
*/
public boolean setSelection(final int start, final int end) {
if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
+ if (start < 0 || end < 0) {
+ return false;
+ }
mExpectedSelStart = start;
mExpectedSelEnd = end;
if (null != mIC) {
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 499a98d65..1747eeeda 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -134,12 +134,17 @@ public final class Suggest {
mDictionaryFacilitator.getSuggestions(wordComposerForLookup, prevWordForBigram,
proximityInfo, blockOffensiveWords, additionalFeaturesOptions, SESSION_TYPING,
suggestionsSet, rawSuggestions);
+
+ final boolean isFirstCharCapitalized = wordComposer.isFirstCharCapitalized();
+ final boolean isAllUpperCase = wordComposer.isAllUpperCase();
final String firstSuggestion;
final String whitelistedWord;
if (suggestionsSet.isEmpty()) {
whitelistedWord = firstSuggestion = null;
} else {
- final SuggestedWordInfo firstSuggestedWordInfo = suggestionsSet.first();
+ final SuggestedWordInfo firstSuggestedWordInfo = getTransformedSuggestedWordInfo(
+ suggestionsSet.first(), mLocale, isAllUpperCase, isFirstCharCapitalized,
+ trailingSingleQuotesCount);
firstSuggestion = firstSuggestedWordInfo.mWord;
if (SuggestedWordInfo.KIND_WHITELIST != firstSuggestedWordInfo.mKind) {
whitelistedWord = null;
@@ -148,6 +153,8 @@ public final class Suggest {
}
}
+ final boolean isPrediction = !wordComposer.isComposingWord();
+
// We allow auto-correction if we have a whitelisted word, or if the word is not a valid
// word of more than 1 char, except if the first suggestion is the same as the typed string
// because in this case if it's strong enough to auto-correct that will mistakenly designate
@@ -155,10 +162,10 @@ public final class Suggest {
// TODO: stop relying on indices to find where is the auto-correction in the suggested
// words, and correct this test.
final boolean allowsToBeAutoCorrected = (null != whitelistedWord
- && !whitelistedWord.equals(consideredWord))
+ && !whitelistedWord.equals(typedWord))
|| (consideredWord.length() > 1 && !mDictionaryFacilitator.isValidWord(
consideredWord, wordComposer.isFirstCharCapitalized())
- && !consideredWord.equals(firstSuggestion));
+ && !typedWord.equals(firstSuggestion));
final boolean hasAutoCorrection;
// TODO: using isCorrectionEnabled here is not very good. It's probably useless, because
@@ -166,7 +173,7 @@ public final class Suggest {
// same time, it feels wrong that the SuggestedWord object includes information about
// the current settings. It may also be useful to know, when the setting is off, whether
// the word *would* have been auto-corrected.
- if (!isCorrectionEnabled || !allowsToBeAutoCorrected || !wordComposer.isComposingWord()
+ if (!isCorrectionEnabled || !allowsToBeAutoCorrected || isPrediction
|| suggestionsSet.isEmpty() || wordComposer.hasDigits()
|| wordComposer.isMostlyCaps() || wordComposer.isResumed()
|| !mDictionaryFacilitator.hasMainDictionary()
@@ -188,8 +195,6 @@ public final class Suggest {
final ArrayList<SuggestedWordInfo> suggestionsContainer =
CollectionUtils.newArrayList(suggestionsSet);
final int suggestionsCount = suggestionsContainer.size();
- final boolean isFirstCharCapitalized = wordComposer.isFirstCharCapitalized();
- final boolean isAllUpperCase = wordComposer.isAllUpperCase();
if (isFirstCharCapitalized || isAllUpperCase || 0 != trailingSingleQuotesCount) {
for (int i = 0; i < suggestionsCount; ++i) {
final SuggestedWordInfo wordInfo = suggestionsContainer.get(i);
@@ -226,10 +231,9 @@ public final class Suggest {
// TODO: this first argument is lying. If this is a whitelisted word which is an
// actual word, it says typedWordValid = false, which looks wrong. We should either
// rename the attribute or change the value.
- !allowsToBeAutoCorrected /* typedWordValid */,
+ !isPrediction && !allowsToBeAutoCorrected /* typedWordValid */,
hasAutoCorrection, /* willAutoCorrect */
- false /* isObsoleteSuggestions */,
- !wordComposer.isComposingWord() /* isPrediction */, sequenceNumber));
+ false /* isObsoleteSuggestions */, isPrediction, sequenceNumber));
}
// Retrieves suggestions for the batch input
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 46df3e88c..06bc90c97 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -69,7 +69,7 @@ public class SuggestedWords {
final boolean isPrediction,
final int sequenceNumber) {
this(suggestedWordInfoList, rawSuggestions,
- suggestedWordInfoList.isEmpty() ? null
+ (suggestedWordInfoList.isEmpty() || isPrediction) ? null
: suggestedWordInfoList.get(INDEX_OF_TYPED_WORD).mWord,
typedWordValid, willAutoCorrect, isObsoleteSuggestions, isPrediction,
sequenceNumber);
diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
index 3e3cbf063..8078ab541 100644
--- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
@@ -86,8 +86,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
public UserBinaryDictionary(final Context context, final Locale locale,
final boolean alsoUseMoreRestrictiveLocales, final File dictFile) {
- super(context, getDictName(NAME, locale, dictFile), locale, Dictionary.TYPE_USER,
- false /* isUpdatable */, dictFile);
+ super(context, getDictName(NAME, locale, dictFile), locale, Dictionary.TYPE_USER, dictFile);
if (null == locale) throw new NullPointerException(); // Catch the error earlier
final String localeStr = locale.toString();
if (SubtypeLocaleUtils.NO_LANGUAGE.equals(localeStr)) {
@@ -130,7 +129,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
}
@Override
- public void loadDictionaryAsync() {
+ public void loadInitialContentsLocked() {
// Split the locale. For example "en" => ["en"], "de_DE" => ["de", "DE"],
// "en_US_foo_bar_qux" => ["en", "US", "foo_bar_qux"] because of the limit of 3.
// This is correct for locale processing.
@@ -182,7 +181,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
try {
cursor = mContext.getContentResolver().query(
Words.CONTENT_URI, PROJECTION_QUERY, request.toString(), requestArguments, null);
- addWords(cursor);
+ addWordsLocked(cursor);
} catch (final SQLiteException e) {
Log.e(TAG, "SQLiteException in the remote User dictionary process.", e);
} finally {
@@ -236,7 +235,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
}
}
- private void addWords(final Cursor cursor) {
+ private void addWordsLocked(final Cursor cursor) {
final boolean hasShortcutColumn = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
if (cursor == null) return;
if (cursor.moveToFirst()) {
@@ -250,12 +249,16 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
final int adjustedFrequency = scaleFrequencyFromDefaultToLatinIme(frequency);
// Safeguard against adding really long words.
if (word.length() < MAX_WORD_LENGTH) {
- super.addWord(word, null, adjustedFrequency, 0 /* shortcutFreq */,
- false /* isNotAWord */);
- }
- if (null != shortcut && shortcut.length() < MAX_WORD_LENGTH) {
- super.addWord(shortcut, word, adjustedFrequency, USER_DICT_SHORTCUT_FREQUENCY,
- true /* isNotAWord */);
+ runGCIfRequiredLocked(true /* mindsBlockByGC */);
+ addWordDynamicallyLocked(word, adjustedFrequency, null /* shortcutTarget */,
+ 0 /* shortcutFreq */, false /* isNotAWord */,
+ false /* isBlacklisted */, BinaryDictionary.NOT_A_VALID_TIMESTAMP);
+ if (null != shortcut && shortcut.length() < MAX_WORD_LENGTH) {
+ runGCIfRequiredLocked(true /* mindsBlockByGC */);
+ addWordDynamicallyLocked(shortcut, adjustedFrequency, word,
+ USER_DICT_SHORTCUT_FREQUENCY, true /* isNotAWord */,
+ false /* isBlacklisted */, BinaryDictionary.NOT_A_VALID_TIMESTAMP);
+ }
}
cursor.moveToNext();
}
@@ -263,12 +266,12 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
}
@Override
- protected boolean hasContentChanged() {
+ protected boolean haveContentsChanged() {
return true;
}
@Override
- protected boolean needsToReloadBeforeWriting() {
+ protected boolean needsToReloadAfterCreation() {
return true;
}
}
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 045d06f0e..f2f9f1e68 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -1360,10 +1360,12 @@ public final class InputLogic {
}});
} else {
// We found suggestion spans in the word. We'll create the SuggestedWords out of
- // them, and make willAutoCorrect false.
+ // them, and make willAutoCorrect false. We make typedWordValid false, because the
+ // color of the word in the suggestion strip changes according to this parameter,
+ // and false gives the correct color.
final SuggestedWords suggestedWords = new SuggestedWords(suggestions,
null /* rawSuggestions */, typedWord,
- true /* typedWordValid */, false /* willAutoCorrect */,
+ false /* typedWordValid */, false /* willAutoCorrect */,
false /* isObsoleteSuggestions */, false /* isPrediction */,
SuggestedWords.NOT_A_SEQUENCE_NUMBER);
mIsAutoCorrectionIndicatorOn = false;
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java
index b09e20591..db96de305 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java
@@ -139,7 +139,7 @@ class InputLogicHandler implements Handler.Callback {
forEnd /* dismissGestureFloatingPreviewText */);
if (forEnd) {
mInBatchInput = false;
- // The following call schedules onEndBatchInputAsyncInternal
+ // The following call schedules onEndBatchInputInternal
// to be called on the UI thread.
mLatinIME.mHandler.onEndBatchInput(suggestedWords);
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
index b534ebeff..25e1bcd25 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
@@ -357,7 +357,7 @@ public final class BinaryDictDecoderUtils {
* @return true if it's a binary dictionary, false otherwise
*/
public static boolean isBinaryDictionary(final File file) {
- final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file);
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, 0, file.length());
if (dictDecoder == null) {
return false;
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 989ca4b2f..90e7400fb 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -237,7 +237,7 @@ public final class BinaryDictIOUtils {
final File file, final long offset, final long length)
throws FileNotFoundException, IOException, UnsupportedFormatException {
final byte[] buffer = new byte[HEADER_READING_BUFFER_SIZE];
- final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file,
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, offset, length,
new DictDecoder.DictionaryBufferFactory() {
@Override
public DictBuffer getDictionaryBuffer(File file)
@@ -251,8 +251,7 @@ public final class BinaryDictIOUtils {
inStream.close();
}
}
- }
- );
+ });
if (dictDecoder == null) {
return null;
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/DictEncoder.java b/java/src/com/android/inputmethod/latin/makedict/DictEncoder.java
index a5dc45691..678c5ca6b 100644
--- a/java/src/com/android/inputmethod/latin/makedict/DictEncoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/DictEncoder.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.latin.makedict;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
@@ -25,6 +26,7 @@ import java.io.IOException;
* An interface of binary dictionary encoder.
*/
public interface DictEncoder {
+ @UsedForTesting
public void writeDictionary(final FusionDictionary dict, final FormatOptions formatOptions)
throws IOException, UnsupportedFormatException;
diff --git a/java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java b/java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java
index b99e281da..b32eb9195 100644
--- a/java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java
+++ b/java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java
@@ -38,6 +38,14 @@ public final class DictionaryHeader {
public static final String DICTIONARY_DATE_KEY = "date";
public static final String HAS_HISTORICAL_INFO_KEY = "HAS_HISTORICAL_INFO";
public static final String USES_FORGETTING_CURVE_KEY = "USES_FORGETTING_CURVE";
+ public static final String FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP_KEY =
+ "FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP";
+ public static final String FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID_KEY =
+ "FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID";
+ public static final String FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS_KEY =
+ "FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS";
+ public static final String MAX_UNIGRAM_COUNT_KEY = "MAX_UNIGRAM_COUNT";
+ public static final String MAX_BIGRAM_COUNT_KEY = "MAX_BIGRAM_COUNT";
public static final String ATTRIBUTE_VALUE_TRUE = "1";
public DictionaryHeader(final int headerSize, final DictionaryOptions dictionaryOptions,
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index c7635eff9..9abecbfec 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -326,30 +326,34 @@ public final class FormatSpec {
* Returns new dictionary decoder.
*
* @param dictFile the dictionary file.
+ * @param offset the offset in the file.
+ * @param length the length of the file, in bytes.
* @param bufferType The type of buffer, as one of USE_* in DictDecoder.
* @return new dictionary decoder if the dictionary file exists, otherwise null.
*/
- public static DictDecoder getDictDecoder(final File dictFile, final int bufferType) {
+ public static DictDecoder getDictDecoder(final File dictFile, final long offset,
+ final long length, final int bufferType) {
if (dictFile.isDirectory()) {
return new Ver4DictDecoder(dictFile, bufferType);
} else if (dictFile.isFile()) {
- return new Ver2DictDecoder(dictFile, bufferType);
+ return new Ver2DictDecoder(dictFile, offset, length, bufferType);
}
return null;
}
- public static DictDecoder getDictDecoder(final File dictFile,
- final DictionaryBufferFactory factory) {
+ public static DictDecoder getDictDecoder(final File dictFile, final long offset,
+ final long length, final DictionaryBufferFactory factory) {
if (dictFile.isDirectory()) {
return new Ver4DictDecoder(dictFile, factory);
} else if (dictFile.isFile()) {
- return new Ver2DictDecoder(dictFile, factory);
+ return new Ver2DictDecoder(dictFile, offset, length, factory);
}
return null;
}
- public static DictDecoder getDictDecoder(final File dictFile) {
- return getDictDecoder(dictFile, DictDecoder.USE_READONLY_BYTEBUFFER);
+ public static DictDecoder getDictDecoder(final File dictFile, final long offset,
+ final long length) {
+ return getDictDecoder(dictFile, offset, length, DictDecoder.USE_READONLY_BYTEBUFFER);
}
private FormatSpec() {
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
index bf776cfc5..ae1e443c5 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
@@ -116,13 +116,18 @@ public class Ver2DictDecoder extends AbstractDictDecoder {
}
protected final File mDictionaryBinaryFile;
+ protected final long mOffset;
+ protected final long mLength;
// TODO: Remove mBufferFactory and mDictBuffer from this class members because they are now
// used only for testing.
private final DictionaryBufferFactory mBufferFactory;
protected DictBuffer mDictBuffer;
- /* package */ Ver2DictDecoder(final File file, final int factoryFlag) {
+ /* package */ Ver2DictDecoder(final File file, final long offset, final long length,
+ final int factoryFlag) {
mDictionaryBinaryFile = file;
+ mOffset = offset;
+ mLength = length;
mDictBuffer = null;
if ((factoryFlag & MASK_DICTBUFFER) == USE_READONLY_BYTEBUFFER) {
mBufferFactory = new DictionaryBufferFromReadOnlyByteBufferFactory();
@@ -135,8 +140,11 @@ public class Ver2DictDecoder extends AbstractDictDecoder {
}
}
- /* package */ Ver2DictDecoder(final File file, final DictionaryBufferFactory factory) {
+ /* package */ Ver2DictDecoder(final File file, final long offset, final long length,
+ final DictionaryBufferFactory factory) {
mDictionaryBinaryFile = file;
+ mOffset = offset;
+ mLength = length;
mBufferFactory = factory;
}
@@ -164,9 +172,9 @@ public class Ver2DictDecoder extends AbstractDictDecoder {
public DictionaryHeader readHeader() throws IOException, UnsupportedFormatException {
// dictType is not being used in dicttool. Passing an empty string.
final BinaryDictionary binaryDictionary = new BinaryDictionary(
- mDictionaryBinaryFile.getAbsolutePath(), 0 /* offset */,
- mDictionaryBinaryFile.length() /* length */, true /* useFullEditDistance */,
- null /* locale */, "" /* dictType */, false /* isUpdatable */);
+ mDictionaryBinaryFile.getAbsolutePath(), mOffset, mLength,
+ true /* useFullEditDistance */, null /* locale */, "" /* dictType */,
+ false /* isUpdatable */);
final DictionaryHeader header = binaryDictionary.getHeader();
binaryDictionary.close();
if (header == null) {
diff --git a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
index d3734d693..074ec4074 100644
--- a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
+++ b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
@@ -27,10 +27,8 @@ import com.android.inputmethod.latin.utils.LanguageModelParam;
import java.io.File;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
-import java.util.concurrent.TimeUnit;
/**
* This class is a base class of a dictionary that supports decaying for the personalized language
@@ -49,14 +47,13 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
/** The locale for this dictionary. */
public final Locale mLocale;
- private final String mDictName;
+ private Map<String, String> mAdditionalAttributeMap = null;
protected DecayingExpandableBinaryDictionaryBase(final Context context,
final String dictName, final Locale locale, final String dictionaryType,
final File dictFile) {
- super(context, dictName, locale, dictionaryType, true /* isUpdatable */, dictFile);
+ super(context, dictName, locale, dictionaryType, dictFile);
mLocale = locale;
- mDictName = dictName;
if (mLocale != null && mLocale.toString().length() > 1) {
reloadDictionaryIfRequired();
}
@@ -78,25 +75,24 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
@Override
protected Map<String, String> getHeaderAttributeMap() {
- HashMap<String, String> attributeMap = new HashMap<String, String>();
+ final Map<String, String> attributeMap = super.getHeaderAttributeMap();
+ if (mAdditionalAttributeMap != null) {
+ attributeMap.putAll(mAdditionalAttributeMap);
+ }
attributeMap.put(DictionaryHeader.USES_FORGETTING_CURVE_KEY,
DictionaryHeader.ATTRIBUTE_VALUE_TRUE);
attributeMap.put(DictionaryHeader.HAS_HISTORICAL_INFO_KEY,
DictionaryHeader.ATTRIBUTE_VALUE_TRUE);
- attributeMap.put(DictionaryHeader.DICTIONARY_ID_KEY, mDictName);
- attributeMap.put(DictionaryHeader.DICTIONARY_LOCALE_KEY, mLocale.toString());
- attributeMap.put(DictionaryHeader.DICTIONARY_VERSION_KEY,
- String.valueOf(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())));
return attributeMap;
}
@Override
- protected boolean hasContentChanged() {
+ protected boolean haveContentsChanged() {
return false;
}
@Override
- protected boolean needsToReloadBeforeWriting() {
+ protected boolean needsToReloadAfterCreation() {
return false;
}
@@ -140,8 +136,8 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
}
@Override
- protected void loadDictionaryAsync() {
- // Never loaded to memory in Java side.
+ protected void loadInitialContentsLocked() {
+ // No initial contents.
}
@UsedForTesting
@@ -152,7 +148,14 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
asyncFlushBinaryDictionary();
}
- /* package */ void decayIfNeeded() {
+ @UsedForTesting
+ public void clearAndFlushDictionaryWithAdditionalAttributes(
+ final Map<String, String> attributeMap) {
+ mAdditionalAttributeMap = attributeMap;
+ clearAndFlushDictionary();
+ }
+
+ /* package */ void runGCIfRequired() {
runGCIfRequired(false /* mindsBlockByGC */);
}
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java b/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java
index e9ca662e7..de2744f29 100644
--- a/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java
+++ b/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java
@@ -43,7 +43,7 @@ public class DictionaryDecayBroadcastReciever extends BroadcastReceiver {
/**
* Interval to update for decaying dictionaries.
*/
- private static final long DICTIONARY_DECAY_INTERVAL = TimeUnit.MINUTES.toMillis(60);
+ /* package */ static final long DICTIONARY_DECAY_INTERVAL = TimeUnit.MINUTES.toMillis(60);
public static void setUpIntervalAlarmForDictionaryDecaying(Context context) {
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
@@ -60,7 +60,7 @@ public class DictionaryDecayBroadcastReciever extends BroadcastReceiver {
public void onReceive(final Context context, final Intent intent) {
final String action = intent.getAction();
if (action.equals(DICTIONARY_DECAY_INTENT_ACTION)) {
- PersonalizationHelper.tryDecayingAllOpeningUserHistoryDictionary();
+ PersonalizationHelper.runGCOnAllOpenedUserHistoryDictionaries();
}
}
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
index 5ae2fb6f8..385b525b6 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.latin.personalization;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.FileUtils;
@@ -27,6 +28,7 @@ import java.io.FilenameFilter;
import java.lang.ref.SoftReference;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
public class PersonalizationHelper {
private static final String TAG = PersonalizationHelper.class.getSimpleName();
@@ -59,14 +61,35 @@ public class PersonalizationHelper {
}
}
- public static void tryDecayingAllOpeningUserHistoryDictionary() {
- for (final ConcurrentHashMap.Entry<String, SoftReference<UserHistoryDictionary>> entry
- : sLangUserHistoryDictCache.entrySet()) {
- if (entry.getValue() != null) {
- final UserHistoryDictionary dict = entry.getValue().get();
- if (dict != null) {
- dict.decayIfNeeded();
- }
+ private static int sCurrentTimestampForTesting = 0;
+ public static void currentTimeChangedForTesting(final int currentTimestamp) {
+ if (TimeUnit.MILLISECONDS.toSeconds(
+ DictionaryDecayBroadcastReciever.DICTIONARY_DECAY_INTERVAL)
+ < currentTimestamp - sCurrentTimestampForTesting) {
+ // TODO: Run GC for both PersonalizationDictionary and UserHistoryDictionary.
+ runGCOnAllOpenedUserHistoryDictionaries();
+ }
+ }
+
+ public static void runGCOnAllOpenedUserHistoryDictionaries() {
+ runGCOnAllDictionariesIfRequired(sLangUserHistoryDictCache);
+ }
+
+ @UsedForTesting
+ public static void runGCOnAllOpenedPersonalizationDictionaries() {
+ runGCOnAllDictionariesIfRequired(sLangPersonalizationDictCache);
+ }
+
+ private static <T extends DecayingExpandableBinaryDictionaryBase>
+ void runGCOnAllDictionariesIfRequired(
+ final ConcurrentHashMap<String, SoftReference<T>> dictionaryMap) {
+ for (final ConcurrentHashMap.Entry<String, SoftReference<T>> entry
+ : dictionaryMap.entrySet()) {
+ final DecayingExpandableBinaryDictionaryBase dict = entry.getValue().get();
+ if (dict != null) {
+ dict.runGCIfRequired();
+ } else {
+ dictionaryMap.remove(entry.getKey());
}
}
}
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index 8ea712835..afa8fe3a8 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -95,9 +95,9 @@ final class SuggestionStripLayoutHelper {
private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD);
private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan();
- private final int mSuggestionStripOption;
+ private final int mSuggestionStripOptions;
// These constants are the flag values of
- // {@link R.styleable#SuggestionStripView_suggestionStripOption} attribute.
+ // {@link R.styleable#SuggestionStripView_suggestionStripOptions} attribute.
private static final int AUTO_CORRECT_BOLD = 0x01;
private static final int AUTO_CORRECT_UNDERLINE = 0x02;
private static final int VALID_TYPED_WORD_BOLD = 0x04;
@@ -122,8 +122,8 @@ final class SuggestionStripLayoutHelper {
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.SuggestionStripView, defStyle, R.style.SuggestionStripView);
- mSuggestionStripOption = a.getInt(
- R.styleable.SuggestionStripView_suggestionStripOption, 0);
+ mSuggestionStripOptions = a.getInt(
+ R.styleable.SuggestionStripView_suggestionStripOptions, 0);
mAlphaObsoleted = ResourceUtils.getFraction(a,
R.styleable.SuggestionStripView_alphaObsoleted, 1.0f);
mColorValidTypedWord = a.getColor(R.styleable.SuggestionStripView_colorValidTypedWord, 0);
@@ -200,22 +200,24 @@ final class SuggestionStripLayoutHelper {
return null;
}
final String word = suggestedWords.getLabel(indexInSuggestedWords);
- final boolean isAutoCorrect = indexInSuggestedWords == 1
- && suggestedWords.mWillAutoCorrect;
- final boolean isTypedWordValid = indexInSuggestedWords == 0
- && suggestedWords.mTypedWordValid;
- if (!isAutoCorrect && !isTypedWordValid) {
+ // TODO: don't use the index to decide whether this is the auto-correction/typed word, as
+ // this is brittle
+ final boolean isAutoCorrection = suggestedWords.mWillAutoCorrect
+ && indexInSuggestedWords == SuggestedWords.INDEX_OF_AUTO_CORRECTION;
+ final boolean isTypedWordValid = suggestedWords.mTypedWordValid
+ && indexInSuggestedWords == SuggestedWords.INDEX_OF_TYPED_WORD;
+ if (!isAutoCorrection && !isTypedWordValid) {
return word;
}
final int len = word.length();
final Spannable spannedWord = new SpannableString(word);
- final int option = mSuggestionStripOption;
- if ((isAutoCorrect && (option & AUTO_CORRECT_BOLD) != 0)
- || (isTypedWordValid && (option & VALID_TYPED_WORD_BOLD) != 0)) {
+ final int options = mSuggestionStripOptions;
+ if ((isAutoCorrection && (options & AUTO_CORRECT_BOLD) != 0)
+ || (isTypedWordValid && (options & VALID_TYPED_WORD_BOLD) != 0)) {
spannedWord.setSpan(BOLD_SPAN, 0, len, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
- if (isAutoCorrect && (option & AUTO_CORRECT_UNDERLINE) != 0) {
+ if (isAutoCorrection && (options & AUTO_CORRECT_UNDERLINE) != 0) {
spannedWord.setSpan(UNDERLINE_SPAN, 0, len, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
return spannedWord;
@@ -242,22 +244,23 @@ final class SuggestionStripLayoutHelper {
return indexInSuggestedWords;
}
- private int getSuggestionTextColor(final int indexInSuggestedWords,
- final SuggestedWords suggestedWords) {
+ private int getSuggestionTextColor(final SuggestedWords suggestedWords,
+ final int indexInSuggestedWords) {
final int positionInStrip =
getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords);
- // TODO: Need to revisit this logic with bigram suggestions
- final boolean isSuggested = (indexInSuggestedWords != SuggestedWords.INDEX_OF_TYPED_WORD);
+ // Use identity for strings, not #equals : it's the typed word if it's the same object
+ final boolean isTypedWord =
+ suggestedWords.getWord(indexInSuggestedWords) == suggestedWords.mTypedWord;
final int color;
if (positionInStrip == mCenterPositionInStrip && suggestedWords.mWillAutoCorrect) {
color = mColorAutoCorrect;
- } else if (positionInStrip == mCenterPositionInStrip && suggestedWords.mTypedWordValid) {
+ } else if (isTypedWord && suggestedWords.mTypedWordValid) {
color = mColorValidTypedWord;
- } else if (isSuggested) {
- color = mColorSuggested;
- } else {
+ } else if (isTypedWord) {
color = mColorTypedWord;
+ } else {
+ color = mColorSuggested;
}
if (LatinImeLogger.sDBG && suggestedWords.size() > 1) {
// If we auto-correct, then the autocorrection is in slot 0 and the typed word
@@ -270,7 +273,7 @@ final class SuggestionStripLayoutHelper {
}
}
- if (suggestedWords.mIsObsoleteSuggestions && isSuggested) {
+ if (suggestedWords.mIsObsoleteSuggestions && !isTypedWord) {
return applyAlpha(color, mAlphaObsoleted);
}
return color;
@@ -438,7 +441,7 @@ final class SuggestionStripLayoutHelper {
// {@link SuggestionStripView#onClick(View)}.
wordView.setTag(indexInSuggestedWords);
wordView.setText(getStyledSuggestedWord(suggestedWords, indexInSuggestedWords));
- wordView.setTextColor(getSuggestionTextColor(positionInStrip, suggestedWords));
+ wordView.setTextColor(getSuggestionTextColor(suggestedWords, indexInSuggestedWords));
if (SuggestionStripView.DBG) {
mDebugInfoViews.get(positionInStrip).setText(
suggestedWords.getDebugString(indexInSuggestedWords));
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java
index 60f1c7a4e..52708455e 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java
@@ -22,7 +22,6 @@ import com.android.inputmethod.latin.SuggestedWords;
* An object that gives basic control of a suggestion strip and some info on it.
*/
public interface SuggestionStripViewAccessor {
- public boolean hasSuggestionStripView();
public void showAddToDictionaryHint(final String word);
public boolean isShowingAddToDictionaryHint();
public void dismissAddToDictionaryHint();
diff --git a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java
new file mode 100644
index 000000000..ee9718ad3
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java
@@ -0,0 +1,55 @@
+/*
+ * 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.utils;
+
+import com.android.inputmethod.annotations.UsedForTesting;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Utilities to manage executors.
+ */
+public class ExecutorUtils {
+ private static final ConcurrentHashMap<String, PrioritizedSerialExecutor>
+ sExecutorMap = CollectionUtils.newConcurrentHashMap();
+ /**
+ * Gets the executor for the given dictionary name.
+ */
+ public static PrioritizedSerialExecutor getExecutor(final String dictName) {
+ PrioritizedSerialExecutor executor = sExecutorMap.get(dictName);
+ if (executor == null) {
+ synchronized(sExecutorMap) {
+ executor = new PrioritizedSerialExecutor();
+ sExecutorMap.put(dictName, executor);
+ }
+ }
+ return executor;
+ }
+
+ /**
+ * Shutdowns all executors and removes all executors from the executor map for testing.
+ */
+ @UsedForTesting
+ public static void shutdownAllExecutors() {
+ synchronized(sExecutorMap) {
+ for (final PrioritizedSerialExecutor executor : sExecutorMap.values()) {
+ executor.shutdown();
+ sExecutorMap.remove(executor);
+ }
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java
index a1d641508..562ff9e8d 100644
--- a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java
+++ b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java
@@ -37,9 +37,9 @@ public final class LanguageModelParam {
// non-0. Thus, it's not meaningful to compare 10, 100, and so on.
// TODO: Revise the logic in ForgettingCurveUtils in native code.
private static final int UNIGRAM_PROBABILITY_FOR_VALID_WORD = 100;
- private static final int UNIGRAM_PROBABILITY_FOR_OOV_WORD = 10;
- private static final int BIGRAM_PROBABILITY_FOR_VALID_WORD = 0;
- private static final int BIGRAM_PROBABILITY_FOR_OOV_WORD = 0;
+ private static final int UNIGRAM_PROBABILITY_FOR_OOV_WORD = Dictionary.NOT_A_PROBABILITY;
+ private static final int BIGRAM_PROBABILITY_FOR_VALID_WORD = 10;
+ private static final int BIGRAM_PROBABILITY_FOR_OOV_WORD = Dictionary.NOT_A_PROBABILITY;
public final String mTargetWord;
public final int[] mWord0;
diff --git a/native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp b/native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp
index e1b35340b..bc4ca8e9e 100644
--- a/native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp
+++ b/native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp
@@ -992,7 +992,16 @@ namespace latinime {
}
}
if (character != NOT_AN_INDEX) {
- codePointBuf[index] = proximityInfo->getCodePointOf(character);
+ const int codePoint = proximityInfo->getCodePointOf(character);
+ if (codePoint == NOT_A_CODE_POINT) {
+ AKLOGE("Key index(%d) is not found. Cannot construct most probable string",
+ character);
+ ASSERT(false);
+ // Make the length zero, which means most probable string won't be used.
+ index = 0;
+ break;
+ }
+ codePointBuf[index] = codePoint;
index++;
}
sumLogProbability += minLogProbability;
diff --git a/native/jni/src/suggest/core/policy/dictionary_header_structure_policy.h b/native/jni/src/suggest/core/policy/dictionary_header_structure_policy.h
index 59748c80d..a8dab9fcd 100644
--- a/native/jni/src/suggest/core/policy/dictionary_header_structure_policy.h
+++ b/native/jni/src/suggest/core/policy/dictionary_header_structure_policy.h
@@ -44,8 +44,6 @@ class DictionaryHeaderStructurePolicy {
virtual float getMultiWordCostMultiplier() const = 0;
- virtual int getLastDecayedTime() const = 0;
-
virtual void readHeaderValueOrQuestionMark(const char *const key, int *outValue,
int outValueSize) const = 0;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/bigram/ver4_bigram_list_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/bigram/ver4_bigram_list_policy.cpp
index cd2243025..5df2096a4 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/bigram/ver4_bigram_list_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/bigram/ver4_bigram_list_policy.cpp
@@ -37,7 +37,8 @@ void Ver4BigramListPolicy::getNextBigram(int *const outBigramPos, int *const out
if (outProbability) {
if (bigramEntry.hasHistoricalInfo()) {
*outProbability =
- ForgettingCurveUtils::decodeProbability(bigramEntry.getHistoricalInfo());
+ ForgettingCurveUtils::decodeProbability(bigramEntry.getHistoricalInfo(),
+ mHeaderPolicy);
} else {
*outProbability = bigramEntry.getProbability();
}
@@ -160,8 +161,8 @@ bool Ver4BigramListPolicy::updateAllBigramEntriesAndDeleteUselessEntries(const i
}
} else if (bigramEntry.hasHistoricalInfo()) {
const HistoricalInfo historicalInfo = ForgettingCurveUtils::createHistoricalInfoToSave(
- bigramEntry.getHistoricalInfo());
- if (ForgettingCurveUtils::needsToKeep(&historicalInfo)) {
+ bigramEntry.getHistoricalInfo(), mHeaderPolicy);
+ if (ForgettingCurveUtils::needsToKeep(&historicalInfo, mHeaderPolicy)) {
const BigramEntry updatedBigramEntry =
bigramEntry.updateHistoricalInfoAndGetEntry(&historicalInfo);
if (!mBigramDictContent->writeBigramEntry(&updatedBigramEntry, entryPos)) {
@@ -230,7 +231,8 @@ const BigramEntry Ver4BigramListPolicy::createUpdatedBigramEntryFrom(
if (mHeaderPolicy->hasHistoricalInfoOfWords()) {
const HistoricalInfo updatedHistoricalInfo =
ForgettingCurveUtils::createUpdatedHistoricalInfo(
- originalBigramEntry->getHistoricalInfo(), newProbability, timestamp);
+ originalBigramEntry->getHistoricalInfo(), newProbability, timestamp,
+ mHeaderPolicy);
return originalBigramEntry->updateHistoricalInfoAndGetEntry(&updatedHistoricalInfo);
} else {
return originalBigramEntry->updateProbabilityAndGetEntry(newProbability);
diff --git a/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp
index 3ce57d910..7c7b05ca8 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp
@@ -18,7 +18,7 @@
namespace latinime {
-// Note that these are corresponding definitions in Java side in FormatSpec.FileHeader.
+// Note that these are corresponding definitions in Java side in DictionaryHeader.
const char *const HeaderPolicy::MULTIPLE_WORDS_DEMOTION_RATE_KEY = "MULTIPLE_WORDS_DEMOTION_RATE";
const char *const HeaderPolicy::REQUIRES_GERMAN_UMLAUT_PROCESSING_KEY =
"REQUIRES_GERMAN_UMLAUT_PROCESSING";
@@ -33,8 +33,26 @@ const char *const HeaderPolicy::EXTENDED_REGION_SIZE_KEY = "EXTENDED_REGION_SIZE
// count.
const char *const HeaderPolicy::HAS_HISTORICAL_INFO_KEY = "HAS_HISTORICAL_INFO";
const char *const HeaderPolicy::LOCALE_KEY = "locale"; // match Java declaration
+const char *const HeaderPolicy::FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP_KEY =
+ "FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP";
+const char *const HeaderPolicy::FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID_KEY =
+ "FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID";
+const char *const HeaderPolicy::FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS_KEY =
+ "FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS";
+
+const char *const HeaderPolicy::MAX_UNIGRAM_COUNT_KEY = "MAX_UNIGRAM_COUNT";
+const char *const HeaderPolicy::MAX_BIGRAM_COUNT_KEY = "MAX_BIGRAM_COUNT";
+
const int HeaderPolicy::DEFAULT_MULTIPLE_WORDS_DEMOTION_RATE = 100;
const float HeaderPolicy::MULTIPLE_WORD_COST_MULTIPLIER_SCALE = 100.0f;
+const int HeaderPolicy::DEFAULT_FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP = 4;
+const int HeaderPolicy::DEFAULT_FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID = 0;
+// 4 days
+const int HeaderPolicy::DEFAULT_FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS =
+ 4 * 24 * 60 * 60;
+
+const int HeaderPolicy::DEFAULT_MAX_UNIGRAM_COUNT = 10000;
+const int HeaderPolicy::DEFAULT_MAX_BIGRAM_COUNT = 10000;
// Used for logging. Question mark is used to indicate that the key is not found.
void HeaderPolicy::readHeaderValueOrQuestionMark(const char *const key, int *outValue,
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 fc347618c..66824245e 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h
@@ -52,7 +52,20 @@ class HeaderPolicy : public DictionaryHeaderStructurePolicy {
mExtendedRegionSize(HeaderReadWriteUtils::readIntAttributeValue(&mAttributeMap,
EXTENDED_REGION_SIZE_KEY, 0 /* defaultValue */)),
mHasHistoricalInfoOfWords(HeaderReadWriteUtils::readBoolAttributeValue(
- &mAttributeMap, HAS_HISTORICAL_INFO_KEY, false /* defaultValue */)) {}
+ &mAttributeMap, HAS_HISTORICAL_INFO_KEY, false /* defaultValue */)),
+ mForgettingCurveOccurrencesToLevelUp(HeaderReadWriteUtils::readIntAttributeValue(
+ &mAttributeMap, FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP_KEY,
+ DEFAULT_FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP)),
+ mForgettingCurveProbabilityValuesTableId(HeaderReadWriteUtils::readIntAttributeValue(
+ &mAttributeMap, FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID_KEY,
+ DEFAULT_FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID)),
+ mForgettingCurveDurationToLevelDown(HeaderReadWriteUtils::readIntAttributeValue(
+ &mAttributeMap, FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS_KEY,
+ DEFAULT_FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS)),
+ mMaxUnigramCount(HeaderReadWriteUtils::readIntAttributeValue(
+ &mAttributeMap, MAX_UNIGRAM_COUNT_KEY, DEFAULT_MAX_UNIGRAM_COUNT)),
+ mMaxBigramCount(HeaderReadWriteUtils::readIntAttributeValue(
+ &mAttributeMap, MAX_BIGRAM_COUNT_KEY, DEFAULT_MAX_BIGRAM_COUNT)) {}
// Constructs header information using an attribute map.
HeaderPolicy(const FormatUtils::FORMAT_VERSION dictFormatVersion,
@@ -71,8 +84,20 @@ class HeaderPolicy : public DictionaryHeaderStructurePolicy {
DATE_KEY, TimeKeeper::peekCurrentTime() /* defaultValue */)),
mUnigramCount(0), mBigramCount(0), mExtendedRegionSize(0),
mHasHistoricalInfoOfWords(HeaderReadWriteUtils::readBoolAttributeValue(
- &mAttributeMap, HAS_HISTORICAL_INFO_KEY, false /* defaultValue */)) {
- }
+ &mAttributeMap, HAS_HISTORICAL_INFO_KEY, false /* defaultValue */)),
+ mForgettingCurveOccurrencesToLevelUp(HeaderReadWriteUtils::readIntAttributeValue(
+ &mAttributeMap, FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP_KEY,
+ DEFAULT_FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP)),
+ mForgettingCurveProbabilityValuesTableId(HeaderReadWriteUtils::readIntAttributeValue(
+ &mAttributeMap, FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID_KEY,
+ DEFAULT_FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID)),
+ mForgettingCurveDurationToLevelDown(HeaderReadWriteUtils::readIntAttributeValue(
+ &mAttributeMap, FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS_KEY,
+ DEFAULT_FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS)),
+ mMaxUnigramCount(HeaderReadWriteUtils::readIntAttributeValue(
+ &mAttributeMap, MAX_UNIGRAM_COUNT_KEY, DEFAULT_MAX_UNIGRAM_COUNT)),
+ mMaxBigramCount(HeaderReadWriteUtils::readIntAttributeValue(
+ &mAttributeMap, MAX_BIGRAM_COUNT_KEY, DEFAULT_MAX_BIGRAM_COUNT)) {}
// Temporary dummy header.
HeaderPolicy()
@@ -80,7 +105,9 @@ class HeaderPolicy : public DictionaryHeaderStructurePolicy {
mAttributeMap(), mLocale(CharUtils::EMPTY_STRING), mMultiWordCostMultiplier(0.0f),
mRequiresGermanUmlautProcessing(false), mIsDecayingDict(false),
mDate(0), mLastDecayedTime(0), mUnigramCount(0), mBigramCount(0),
- mExtendedRegionSize(0), mHasHistoricalInfoOfWords(false) {}
+ mExtendedRegionSize(0), mHasHistoricalInfoOfWords(false),
+ mForgettingCurveOccurrencesToLevelUp(0), mForgettingCurveProbabilityValuesTableId(0),
+ mForgettingCurveDurationToLevelDown(0), mMaxUnigramCount(0), mMaxBigramCount(0) {}
~HeaderPolicy() {}
@@ -159,6 +186,26 @@ class HeaderPolicy : public DictionaryHeaderStructurePolicy {
return &mAttributeMap;
}
+ AK_FORCE_INLINE int getForgettingCurveOccurrencesToLevelUp() const {
+ return mForgettingCurveOccurrencesToLevelUp;
+ }
+
+ AK_FORCE_INLINE int getForgettingCurveProbabilityValuesTableId() const {
+ return mForgettingCurveProbabilityValuesTableId;
+ }
+
+ AK_FORCE_INLINE int getForgettingCurveDurationToLevelDown() const {
+ return mForgettingCurveDurationToLevelDown;
+ }
+
+ AK_FORCE_INLINE int getMaxUnigramCount() const {
+ return mMaxUnigramCount;
+ }
+
+ AK_FORCE_INLINE int getMaxBigramCount() const {
+ return mMaxBigramCount;
+ }
+
void readHeaderValueOrQuestionMark(const char *const key,
int *outValue, int outValueSize) const;
@@ -183,8 +230,18 @@ class HeaderPolicy : public DictionaryHeaderStructurePolicy {
static const char *const EXTENDED_REGION_SIZE_KEY;
static const char *const HAS_HISTORICAL_INFO_KEY;
static const char *const LOCALE_KEY;
+ static const char *const FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP_KEY;
+ static const char *const FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID_KEY;
+ static const char *const FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS_KEY;
+ static const char *const MAX_UNIGRAM_COUNT_KEY;
+ static const char *const MAX_BIGRAM_COUNT_KEY;
static const int DEFAULT_MULTIPLE_WORDS_DEMOTION_RATE;
static const float MULTIPLE_WORD_COST_MULTIPLIER_SCALE;
+ static const int DEFAULT_FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP;
+ static const int DEFAULT_FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID;
+ static const int DEFAULT_FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS;
+ static const int DEFAULT_MAX_UNIGRAM_COUNT;
+ static const int DEFAULT_MAX_BIGRAM_COUNT;
const FormatUtils::FORMAT_VERSION mDictFormatVersion;
const HeaderReadWriteUtils::DictionaryFlags mDictionaryFlags;
@@ -200,6 +257,11 @@ class HeaderPolicy : public DictionaryHeaderStructurePolicy {
const int mBigramCount;
const int mExtendedRegionSize;
const bool mHasHistoricalInfoOfWords;
+ const int mForgettingCurveOccurrencesToLevelUp;
+ const int mForgettingCurveProbabilityValuesTableId;
+ const int mForgettingCurveDurationToLevelDown;
+ const int mMaxUnigramCount;
+ const int mMaxBigramCount;
const std::vector<int> readLocale() const;
float readMultipleWordCostMultiplier() const;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.cpp
index cb9d450ec..279f5b33a 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.cpp
@@ -23,6 +23,13 @@ namespace latinime {
const BigramEntry BigramDictContent::getBigramEntryAndAdvancePosition(
int *const bigramEntryPos) const {
const BufferWithExtendableBuffer *const bigramListBuffer = getContentBuffer();
+ if (*bigramEntryPos < 0 || *bigramEntryPos >= bigramListBuffer->getTailPosition()) {
+ AKLOGE("Invalid bigram entry position. bigramEntryPos: %d, bufSize: %d",
+ *bigramEntryPos, bigramListBuffer->getTailPosition());
+ ASSERT(false);
+ return BigramEntry(false /* hasNext */, NOT_A_PROBABILITY,
+ Ver4DictConstants::NOT_A_TERMINAL_ID);
+ }
const int bigramFlags = bigramListBuffer->readUintAndAdvancePosition(
Ver4DictConstants::BIGRAM_FLAGS_FIELD_SIZE, bigramEntryPos);
const bool hasNext = (bigramFlags & Ver4DictConstants::BIGRAM_HAS_NEXT_MASK) != 0;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.cpp
index 29972a4e8..64d7bc0a5 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/shortcut_dict_content.cpp
@@ -24,6 +24,19 @@ void ShortcutDictContent::getShortcutEntryAndAdvancePosition(const int maxCodePo
int *const outCodePoint, int *const outCodePointCount, int *const outProbability,
bool *const outhasNext, int *const shortcutEntryPos) const {
const BufferWithExtendableBuffer *const shortcutListBuffer = getContentBuffer();
+ if (*shortcutEntryPos < 0 || *shortcutEntryPos >= shortcutListBuffer->getTailPosition()) {
+ AKLOGE("Invalid shortcut entry position. shortcutEntryPos: %d, bufSize: %d",
+ *shortcutEntryPos, shortcutListBuffer->getTailPosition());
+ ASSERT(false);
+ if (outhasNext) {
+ *outhasNext = false;
+ }
+ if (outCodePointCount) {
+ *outCodePointCount = 0;
+ }
+ return;
+ }
+
const int shortcutFlags = shortcutListBuffer->readUintAndAdvancePosition(
Ver4DictConstants::SHORTCUT_FLAGS_FIELD_SIZE, shortcutEntryPos);
if (outProbability) {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.cpp
index 17fc9483b..f149781f4 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.cpp
@@ -65,7 +65,7 @@ const PtNodeParams Ver4PatriciaTrieNodeReader::fetchPtNodeInfoFromBufferAndProce
mProbabilityDictContent->getProbabilityEntry(terminalId);
if (probabilityEntry.hasHistoricalInfo()) {
probability = ForgettingCurveUtils::decodeProbability(
- probabilityEntry.getHistoricalInfo());
+ probabilityEntry.getHistoricalInfo(), mHeaderPolicy);
} else {
probability = probabilityEntry.getProbability();
}
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.h
index 9d932457c..1db9ea026 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.h
@@ -26,6 +26,7 @@
namespace latinime {
class BufferWithExtendableBuffer;
+class HeaderPolicy;
class ProbabilityDictContent;
/*
@@ -35,8 +36,10 @@ class ProbabilityDictContent;
class Ver4PatriciaTrieNodeReader : public PtNodeReader {
public:
Ver4PatriciaTrieNodeReader(const BufferWithExtendableBuffer *const buffer,
- const ProbabilityDictContent *const probabilityDictContent)
- : mBuffer(buffer), mProbabilityDictContent(probabilityDictContent) {}
+ const ProbabilityDictContent *const probabilityDictContent,
+ const HeaderPolicy *const headerPolicy)
+ : mBuffer(buffer), mProbabilityDictContent(probabilityDictContent),
+ mHeaderPolicy(headerPolicy) {}
~Ver4PatriciaTrieNodeReader() {}
@@ -50,6 +53,7 @@ class Ver4PatriciaTrieNodeReader : public PtNodeReader {
const BufferWithExtendableBuffer *const mBuffer;
const ProbabilityDictContent *const mProbabilityDictContent;
+ const HeaderPolicy *const mHeaderPolicy;
const PtNodeParams fetchPtNodeInfoFromBufferAndProcessMovedPtNode(const int ptNodePos,
const int siblingNodePos) const;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp
index 32576cf0a..f24c2e1af 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp
@@ -159,7 +159,7 @@ bool Ver4PatriciaTrieNodeWriter::updatePtNodeProbabilityAndGetNeedsToKeepPtNodeA
toBeUpdatedPtNodeParams->getTerminalId());
if (originalProbabilityEntry.hasHistoricalInfo()) {
const HistoricalInfo historicalInfo = ForgettingCurveUtils::createHistoricalInfoToSave(
- originalProbabilityEntry.getHistoricalInfo());
+ originalProbabilityEntry.getHistoricalInfo(), mHeaderPolicy);
const ProbabilityEntry probabilityEntry =
originalProbabilityEntry.createEntryWithUpdatedHistoricalInfo(&historicalInfo);
if (!mBuffers->getMutableProbabilityDictContent()->setProbabilityEntry(
@@ -168,7 +168,7 @@ bool Ver4PatriciaTrieNodeWriter::updatePtNodeProbabilityAndGetNeedsToKeepPtNodeA
toBeUpdatedPtNodeParams->getTerminalId());
return false;
}
- const bool isValid = ForgettingCurveUtils::needsToKeep(&historicalInfo);
+ const bool isValid = ForgettingCurveUtils::needsToKeep(&historicalInfo, mHeaderPolicy);
if (!isValid) {
if (!markPtNodeAsWillBecomeNonTerminal(toBeUpdatedPtNodeParams)) {
AKLOGE("Cannot mark PtNode as willBecomeNonTerminal.");
@@ -382,10 +382,11 @@ const ProbabilityEntry Ver4PatriciaTrieNodeWriter::createUpdatedEntryFrom(
const ProbabilityEntry *const originalProbabilityEntry, const int newProbability,
const int timestamp) const {
// TODO: Consolidate historical info and probability.
- if (mBuffers->getHeaderPolicy()->hasHistoricalInfoOfWords()) {
+ if (mHeaderPolicy->hasHistoricalInfoOfWords()) {
const HistoricalInfo updatedHistoricalInfo =
ForgettingCurveUtils::createUpdatedHistoricalInfo(
- originalProbabilityEntry->getHistoricalInfo(), newProbability, timestamp);
+ originalProbabilityEntry->getHistoricalInfo(), newProbability, timestamp,
+ mHeaderPolicy);
return originalProbabilityEntry->createEntryWithUpdatedHistoricalInfo(
&updatedHistoricalInfo);
} else {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h
index 66845bbd6..f01b3af0e 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h
@@ -28,6 +28,7 @@
namespace latinime {
class BufferWithExtendableBuffer;
+class HeaderPolicy;
class Ver4BigramListPolicy;
class Ver4DictBuffers;
class Ver4PatriciaTrieNodeReader;
@@ -40,10 +41,11 @@ class Ver4ShortcutListPolicy;
class Ver4PatriciaTrieNodeWriter : public PtNodeWriter {
public:
Ver4PatriciaTrieNodeWriter(BufferWithExtendableBuffer *const trieBuffer,
- Ver4DictBuffers *const buffers, const PtNodeReader *const ptNodeReader,
+ Ver4DictBuffers *const buffers, const HeaderPolicy *const headerPolicy,
+ const PtNodeReader *const ptNodeReader,
const PtNodeArrayReader *const ptNodeArrayReader,
Ver4BigramListPolicy *const bigramPolicy, Ver4ShortcutListPolicy *const shortcutPolicy)
- : mTrieBuffer(trieBuffer), mBuffers(buffers),
+ : mTrieBuffer(trieBuffer), mBuffers(buffers), mHeaderPolicy(headerPolicy),
mReadingHelper(ptNodeReader, ptNodeArrayReader), mBigramPolicy(bigramPolicy),
mShortcutPolicy(shortcutPolicy) {}
@@ -116,6 +118,7 @@ class Ver4PatriciaTrieNodeWriter : public PtNodeWriter {
BufferWithExtendableBuffer *const mTrieBuffer;
Ver4DictBuffers *const mBuffers;
+ const HeaderPolicy *const mHeaderPolicy;
DynamicPtReadingHelper mReadingHelper;
Ver4BigramListPolicy *const mBigramPolicy;
Ver4ShortcutListPolicy *const mShortcutPolicy;
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 b5d80be1d..4d1b0dadb 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
@@ -329,11 +329,15 @@ void Ver4PatriciaTriePolicy::getProperty(const char *const query, const int quer
snprintf(outResult, maxResultLength, "%d", mBigramCount);
} else if (strncmp(query, MAX_UNIGRAM_COUNT_QUERY, compareLength) == 0) {
snprintf(outResult, maxResultLength, "%d",
- mHeaderPolicy->isDecayingDict() ? ForgettingCurveUtils::MAX_UNIGRAM_COUNT :
+ mHeaderPolicy->isDecayingDict() ?
+ ForgettingCurveUtils::getUnigramCountHardLimit(
+ mHeaderPolicy->getMaxUnigramCount()) :
static_cast<int>(Ver4DictConstants::MAX_DICTIONARY_SIZE));
} else if (strncmp(query, MAX_BIGRAM_COUNT_QUERY, compareLength) == 0) {
snprintf(outResult, maxResultLength, "%d",
- mHeaderPolicy->isDecayingDict() ? ForgettingCurveUtils::MAX_BIGRAM_COUNT :
+ mHeaderPolicy->isDecayingDict() ?
+ ForgettingCurveUtils::getBigramCountHardLimit(
+ mHeaderPolicy->getMaxBigramCount()) :
static_cast<int>(Ver4DictConstants::MAX_DICTIONARY_SIZE));
}
}
@@ -382,7 +386,8 @@ const WordProperty Ver4PatriciaTriePolicy::getWordProperty(const int *const code
bigramWord1CodePoints + codePointCount);
const HistoricalInfo *const historicalInfo = bigramEntry.getHistoricalInfo();
const int probability = bigramEntry.hasHistoricalInfo() ?
- ForgettingCurveUtils::decodeProbability(bigramEntry.getHistoricalInfo()) :
+ ForgettingCurveUtils::decodeProbability(
+ bigramEntry.getHistoricalInfo(), mHeaderPolicy) :
bigramEntry.getProbability();
bigrams.push_back(WordProperty::BigramProperty(&word1, probability,
historicalInfo->getTimeStamp(), historicalInfo->getLevel(),
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h
index 7796e2ddc..639c153a1 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h
@@ -47,10 +47,10 @@ class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
mBuffers.get()->getTerminalPositionLookupTable(), mHeaderPolicy),
mShortcutPolicy(mBuffers.get()->getMutableShortcutDictContent(),
mBuffers.get()->getTerminalPositionLookupTable()),
- mNodeReader(mDictBuffer, mBuffers.get()->getProbabilityDictContent()),
+ mNodeReader(mDictBuffer, mBuffers.get()->getProbabilityDictContent(), mHeaderPolicy),
mPtNodeArrayReader(mDictBuffer),
- mNodeWriter(mDictBuffer, mBuffers.get(), &mNodeReader, &mPtNodeArrayReader,
- &mBigramPolicy, &mShortcutPolicy),
+ mNodeWriter(mDictBuffer, mBuffers.get(), mHeaderPolicy, &mNodeReader,
+ &mPtNodeArrayReader, &mBigramPolicy, &mShortcutPolicy),
mUpdatingHelper(mDictBuffer, &mNodeReader, &mNodeWriter),
mWritingHelper(mBuffers.get()),
mUnigramCount(mHeaderPolicy->getUnigramCount()),
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp
index 93053c38d..3907c84a0 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp
@@ -74,14 +74,15 @@ bool Ver4PatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos,
const HeaderPolicy *const headerPolicy, Ver4DictBuffers *const buffersToWrite,
int *const outUnigramCount, int *const outBigramCount) {
Ver4PatriciaTrieNodeReader ptNodeReader(mBuffers->getTrieBuffer(),
- mBuffers->getProbabilityDictContent());
+ mBuffers->getProbabilityDictContent(), headerPolicy);
Ver4PtNodeArrayReader ptNodeArrayReader(mBuffers->getTrieBuffer());
Ver4BigramListPolicy bigramPolicy(mBuffers->getMutableBigramDictContent(),
mBuffers->getTerminalPositionLookupTable(), headerPolicy);
Ver4ShortcutListPolicy shortcutPolicy(mBuffers->getMutableShortcutDictContent(),
mBuffers->getTerminalPositionLookupTable());
Ver4PatriciaTrieNodeWriter ptNodeWriter(mBuffers->getWritableTrieBuffer(),
- mBuffers, &ptNodeReader, &ptNodeArrayReader, &bigramPolicy, &shortcutPolicy);
+ mBuffers, headerPolicy, &ptNodeReader, &ptNodeArrayReader, &bigramPolicy,
+ &shortcutPolicy);
DynamicPtReadingHelper readingHelper(&ptNodeReader, &ptNodeArrayReader);
readingHelper.initWithPtNodeArrayPos(rootPtNodeArrayPos);
@@ -95,12 +96,11 @@ bool Ver4PatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos,
}
const int unigramCount = traversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted
.getValidUnigramCount();
- if (headerPolicy->isDecayingDict()
- && unigramCount > ForgettingCurveUtils::MAX_UNIGRAM_COUNT_AFTER_GC) {
- if (!truncateUnigrams(&ptNodeReader, &ptNodeWriter,
- ForgettingCurveUtils::MAX_UNIGRAM_COUNT_AFTER_GC)) {
+ const int maxUnigramCount = headerPolicy->getMaxUnigramCount();
+ if (headerPolicy->isDecayingDict() && unigramCount > maxUnigramCount) {
+ if (!truncateUnigrams(&ptNodeReader, &ptNodeWriter, maxUnigramCount)) {
AKLOGE("Cannot remove unigrams. current: %d, max: %d", unigramCount,
- ForgettingCurveUtils::MAX_UNIGRAM_COUNT_AFTER_GC);
+ maxUnigramCount);
return false;
}
}
@@ -113,11 +113,10 @@ bool Ver4PatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos,
return false;
}
const int bigramCount = traversePolicyToUpdateBigramProbability.getValidBigramEntryCount();
- if (headerPolicy->isDecayingDict()
- && bigramCount > ForgettingCurveUtils::MAX_BIGRAM_COUNT_AFTER_GC) {
- if (!truncateBigrams(ForgettingCurveUtils::MAX_BIGRAM_COUNT_AFTER_GC)) {
- AKLOGE("Cannot remove bigrams. current: %d, max: %d", bigramCount,
- ForgettingCurveUtils::MAX_BIGRAM_COUNT_AFTER_GC);
+ const int maxBigramCount = headerPolicy->getMaxBigramCount();
+ if (headerPolicy->isDecayingDict() && bigramCount > maxBigramCount) {
+ if (!truncateBigrams(maxBigramCount)) {
+ AKLOGE("Cannot remove bigrams. current: %d, max: %d", bigramCount, maxBigramCount);
return false;
}
}
@@ -126,7 +125,8 @@ bool Ver4PatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos,
PtNodeWriter::DictPositionRelocationMap dictPositionRelocationMap;
readingHelper.initWithPtNodeArrayPos(rootPtNodeArrayPos);
Ver4PatriciaTrieNodeWriter ptNodeWriterForNewBuffers(buffersToWrite->getWritableTrieBuffer(),
- buffersToWrite, &ptNodeReader, &ptNodeArrayReader, &bigramPolicy, &shortcutPolicy);
+ buffersToWrite, headerPolicy, &ptNodeReader, &ptNodeArrayReader, &bigramPolicy,
+ &shortcutPolicy);
DynamicPtGcEventListeners::TraversePolicyToPlaceAndWriteValidPtNodesToBuffer
traversePolicyToPlaceAndWriteValidPtNodesToBuffer(&ptNodeWriterForNewBuffers,
buffersToWrite->getWritableTrieBuffer(), &dictPositionRelocationMap);
@@ -137,14 +137,14 @@ bool Ver4PatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos,
// Create policy instances for the GCed dictionary.
Ver4PatriciaTrieNodeReader newPtNodeReader(buffersToWrite->getTrieBuffer(),
- buffersToWrite->getProbabilityDictContent());
+ buffersToWrite->getProbabilityDictContent(), headerPolicy);
Ver4PtNodeArrayReader newPtNodeArrayreader(buffersToWrite->getTrieBuffer());
Ver4BigramListPolicy newBigramPolicy(buffersToWrite->getMutableBigramDictContent(),
buffersToWrite->getTerminalPositionLookupTable(), headerPolicy);
Ver4ShortcutListPolicy newShortcutPolicy(buffersToWrite->getMutableShortcutDictContent(),
buffersToWrite->getTerminalPositionLookupTable());
Ver4PatriciaTrieNodeWriter newPtNodeWriter(buffersToWrite->getWritableTrieBuffer(),
- buffersToWrite, &newPtNodeReader, &newPtNodeArrayreader, &newBigramPolicy,
+ buffersToWrite, headerPolicy, &newPtNodeReader, &newPtNodeArrayreader, &newBigramPolicy,
&newShortcutPolicy);
// Re-assign terminal IDs for valid terminal PtNodes.
TerminalPositionLookupTable::TerminalIdMap terminalIdMap;
@@ -202,8 +202,9 @@ bool Ver4PatriciaTrieWritingHelper::truncateUnigrams(
const ProbabilityEntry probabilityEntry =
mBuffers->getProbabilityDictContent()->getProbabilityEntry(i);
const int probability = probabilityEntry.hasHistoricalInfo() ?
- ForgettingCurveUtils::decodeProbability(probabilityEntry.getHistoricalInfo()) :
- probabilityEntry.getProbability();
+ ForgettingCurveUtils::decodeProbability(
+ probabilityEntry.getHistoricalInfo(), mBuffers->getHeaderPolicy()) :
+ probabilityEntry.getProbability();
priorityQueue.push(DictProbability(terminalPos, probability,
probabilityEntry.getHistoricalInfo()->getTimeStamp()));
}
@@ -245,8 +246,9 @@ bool Ver4PatriciaTrieWritingHelper::truncateBigrams(const int maxBigramCount) {
continue;
}
const int probability = bigramEntry.hasHistoricalInfo() ?
- ForgettingCurveUtils::decodeProbability(bigramEntry.getHistoricalInfo()) :
- bigramEntry.getProbability();
+ ForgettingCurveUtils::decodeProbability(
+ bigramEntry.getHistoricalInfo(), mBuffers->getHeaderPolicy()) :
+ bigramEntry.getProbability();
priorityQueue.push(DictProbability(entryPos, probability,
bigramEntry.getHistoricalInfo()->getTimeStamp()));
}
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.cpp
index d58d25989..35e05d77a 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.cpp
@@ -19,33 +19,29 @@
#include <cmath>
#include <stdlib.h>
-#include "suggest/core/policy/dictionary_header_structure_policy.h"
+#include "suggest/policyimpl/dictionary/header/header_policy.h"
#include "suggest/policyimpl/dictionary/utils/probability_utils.h"
#include "utils/time_keeper.h"
namespace latinime {
-const int ForgettingCurveUtils::MAX_UNIGRAM_COUNT = 12000;
-const int ForgettingCurveUtils::MAX_UNIGRAM_COUNT_AFTER_GC = 10000;
-const int ForgettingCurveUtils::MAX_BIGRAM_COUNT = 12000;
-const int ForgettingCurveUtils::MAX_BIGRAM_COUNT_AFTER_GC = 10000;
-
-const int ForgettingCurveUtils::MAX_COMPUTED_PROBABILITY = 127;
+const int ForgettingCurveUtils::MULTIPLIER_TWO_IN_PROBABILITY_SCALE = 8;
const int ForgettingCurveUtils::DECAY_INTERVAL_SECONDS = 2 * 60 * 60;
const int ForgettingCurveUtils::MAX_LEVEL = 3;
-const int ForgettingCurveUtils::MAX_COUNT = 3;
const int ForgettingCurveUtils::MIN_VALID_LEVEL = 1;
-const int ForgettingCurveUtils::TIME_STEP_DURATION_IN_SECONDS = 6 * 60 * 60;
const int ForgettingCurveUtils::MAX_ELAPSED_TIME_STEP_COUNT = 15;
const int ForgettingCurveUtils::DISCARD_LEVEL_ZERO_ENTRY_TIME_STEP_COUNT_THRESHOLD = 14;
+const float ForgettingCurveUtils::UNIGRAM_COUNT_HARD_LIMIT_WEIGHT = 1.2;
+const float ForgettingCurveUtils::BIGRAM_COUNT_HARD_LIMIT_WEIGHT = 1.2;
+
const ForgettingCurveUtils::ProbabilityTable ForgettingCurveUtils::sProbabilityTable;
// TODO: Revise the logic to decide the initial probability depending on the given probability.
/* static */ const HistoricalInfo ForgettingCurveUtils::createUpdatedHistoricalInfo(
const HistoricalInfo *const originalHistoricalInfo,
- const int newProbability, const int timestamp) {
+ const int newProbability, const int timestamp, const HeaderPolicy *const headerPolicy) {
if (newProbability != NOT_A_PROBABILITY && originalHistoricalInfo->getLevel() == 0) {
return HistoricalInfo(timestamp, MIN_VALID_LEVEL /* level */, 0 /* count */);
} else if (!originalHistoricalInfo->isValid()) {
@@ -53,7 +49,7 @@ const ForgettingCurveUtils::ProbabilityTable ForgettingCurveUtils::sProbabilityT
return HistoricalInfo(timestamp, 0 /* level */, 1 /* count */);
} else {
const int updatedCount = originalHistoricalInfo->getCount() + 1;
- if (updatedCount > MAX_COUNT) {
+ if (updatedCount >= headerPolicy->getForgettingCurveOccurrencesToLevelUp()) {
// The count exceeds the max value the level can be incremented.
if (originalHistoricalInfo->getLevel() >= MAX_LEVEL) {
// The level is already max.
@@ -71,9 +67,11 @@ const ForgettingCurveUtils::ProbabilityTable ForgettingCurveUtils::sProbabilityT
}
/* static */ int ForgettingCurveUtils::decodeProbability(
- const HistoricalInfo *const historicalInfo) {
- const int elapsedTimeStepCount = getElapsedTimeStepCount(historicalInfo->getTimeStamp());
- return sProbabilityTable.getProbability(historicalInfo->getLevel(),
+ const HistoricalInfo *const historicalInfo, const HeaderPolicy *const headerPolicy) {
+ const int elapsedTimeStepCount = getElapsedTimeStepCount(historicalInfo->getTimeStamp(),
+ headerPolicy->getForgettingCurveDurationToLevelDown());
+ return sProbabilityTable.getProbability(
+ headerPolicy->getForgettingCurveProbabilityValuesTableId(), historicalInfo->getLevel(),
min(max(elapsedTimeStepCount, 0), MAX_ELAPSED_TIME_STEP_COUNT));
}
@@ -82,24 +80,31 @@ const ForgettingCurveUtils::ProbabilityTable ForgettingCurveUtils::sProbabilityT
if (unigramProbability == NOT_A_PROBABILITY) {
return NOT_A_PROBABILITY;
} else if (bigramProbability == NOT_A_PROBABILITY) {
- return min(backoff(unigramProbability), MAX_COMPUTED_PROBABILITY);
+ return min(backoff(unigramProbability), MAX_PROBABILITY);
} else {
- return min(max(unigramProbability, bigramProbability), MAX_COMPUTED_PROBABILITY);
+ // TODO: Investigate better way to handle bigram probability.
+ return min(max(unigramProbability, bigramProbability + MULTIPLIER_TWO_IN_PROBABILITY_SCALE),
+ MAX_PROBABILITY);
}
}
-/* static */ bool ForgettingCurveUtils::needsToKeep(const HistoricalInfo *const historicalInfo) {
+/* static */ bool ForgettingCurveUtils::needsToKeep(const HistoricalInfo *const historicalInfo,
+ const HeaderPolicy *const headerPolicy) {
return historicalInfo->getLevel() > 0
- || getElapsedTimeStepCount(historicalInfo->getTimeStamp())
- < DISCARD_LEVEL_ZERO_ENTRY_TIME_STEP_COUNT_THRESHOLD;
+ || getElapsedTimeStepCount(historicalInfo->getTimeStamp(),
+ headerPolicy->getForgettingCurveDurationToLevelDown())
+ < DISCARD_LEVEL_ZERO_ENTRY_TIME_STEP_COUNT_THRESHOLD;
}
/* static */ const HistoricalInfo ForgettingCurveUtils::createHistoricalInfoToSave(
- const HistoricalInfo *const originalHistoricalInfo) {
+ const HistoricalInfo *const originalHistoricalInfo,
+ const HeaderPolicy *const headerPolicy) {
if (originalHistoricalInfo->getTimeStamp() == NOT_A_TIMESTAMP) {
return HistoricalInfo();
}
- const int elapsedTimeStep = getElapsedTimeStepCount(originalHistoricalInfo->getTimeStamp());
+ const int durationToLevelDownInSeconds = headerPolicy->getForgettingCurveDurationToLevelDown();
+ const int elapsedTimeStep = getElapsedTimeStepCount(
+ originalHistoricalInfo->getTimeStamp(), durationToLevelDownInSeconds);
if (elapsedTimeStep <= MAX_ELAPSED_TIME_STEP_COUNT) {
// No need to update historical info.
return *originalHistoricalInfo;
@@ -108,19 +113,18 @@ const ForgettingCurveUtils::ProbabilityTable ForgettingCurveUtils::sProbabilityT
const int maxLevelDownAmonut = elapsedTimeStep / (MAX_ELAPSED_TIME_STEP_COUNT + 1);
const int levelDownAmount = (maxLevelDownAmonut >= originalHistoricalInfo->getLevel()) ?
originalHistoricalInfo->getLevel() : maxLevelDownAmonut;
- const int adjustedTimestamp = originalHistoricalInfo->getTimeStamp() +
- levelDownAmount * (MAX_ELAPSED_TIME_STEP_COUNT + 1) * TIME_STEP_DURATION_IN_SECONDS;
- return HistoricalInfo(adjustedTimestamp,
+ const int adjustedTimestampInSeconds = originalHistoricalInfo->getTimeStamp() +
+ levelDownAmount * durationToLevelDownInSeconds;
+ return HistoricalInfo(adjustedTimestampInSeconds,
originalHistoricalInfo->getLevel() - levelDownAmount, 0 /* count */);
}
/* static */ bool ForgettingCurveUtils::needsToDecay(const bool mindsBlockByDecay,
- const int unigramCount, const int bigramCount,
- const DictionaryHeaderStructurePolicy *const headerPolicy) {
- if (unigramCount >= ForgettingCurveUtils::MAX_UNIGRAM_COUNT) {
+ const int unigramCount, const int bigramCount, const HeaderPolicy *const headerPolicy) {
+ if (unigramCount >= getUnigramCountHardLimit(headerPolicy->getMaxUnigramCount())) {
// Unigram count exceeds the limit.
return true;
- } else if (bigramCount >= ForgettingCurveUtils::MAX_BIGRAM_COUNT) {
+ } else if (bigramCount >= getBigramCountHardLimit(headerPolicy->getMaxBigramCount())) {
// Bigram count exceeds the limit.
return true;
}
@@ -137,37 +141,71 @@ const ForgettingCurveUtils::ProbabilityTable ForgettingCurveUtils::sProbabilityT
// See comments in ProbabilityUtils::backoff().
/* static */ int ForgettingCurveUtils::backoff(const int unigramProbability) {
- if (unigramProbability == NOT_A_PROBABILITY) {
- return NOT_A_PROBABILITY;
- } else {
- return max(unigramProbability - 8, 0);
- }
+ // See TODO comments in ForgettingCurveUtils::getProbability().
+ return unigramProbability;
}
-/* static */ int ForgettingCurveUtils::getElapsedTimeStepCount(const int timestamp) {
- return (TimeKeeper::peekCurrentTime() - timestamp) / TIME_STEP_DURATION_IN_SECONDS;
+/* static */ int ForgettingCurveUtils::getElapsedTimeStepCount(const int timestamp,
+ const int durationToLevelDownInSeconds) {
+ const int elapsedTimeInSeconds = TimeKeeper::peekCurrentTime() - timestamp;
+ const int timeStepDurationInSeconds =
+ durationToLevelDownInSeconds / (MAX_ELAPSED_TIME_STEP_COUNT + 1);
+ return elapsedTimeInSeconds / timeStepDurationInSeconds;
}
-ForgettingCurveUtils::ProbabilityTable::ProbabilityTable() : mTable() {
- mTable.resize(MAX_LEVEL + 1);
- for (int level = 0; level <= MAX_LEVEL; ++level) {
- mTable[level].resize(MAX_ELAPSED_TIME_STEP_COUNT + 1);
- const float initialProbability =
- static_cast<float>(MAX_COMPUTED_PROBABILITY / (1 << (MAX_LEVEL - level)));
- for (int timeStepCount = 0; timeStepCount <= MAX_ELAPSED_TIME_STEP_COUNT; ++timeStepCount) {
- if (level == 0) {
- mTable[level][timeStepCount] = NOT_A_PROBABILITY;
- continue;
+const int ForgettingCurveUtils::ProbabilityTable::PROBABILITY_TABLE_COUNT = 4;
+const int ForgettingCurveUtils::ProbabilityTable::WEAK_PROBABILITY_TABLE_ID = 0;
+const int ForgettingCurveUtils::ProbabilityTable::MODEST_PROBABILITY_TABLE_ID = 1;
+const int ForgettingCurveUtils::ProbabilityTable::STRONG_PROBABILITY_TABLE_ID = 2;
+const int ForgettingCurveUtils::ProbabilityTable::AGGRESSIVE_PROBABILITY_TABLE_ID = 3;
+const int ForgettingCurveUtils::ProbabilityTable::WEAK_MAX_PROBABILITY = 127;
+const int ForgettingCurveUtils::ProbabilityTable::MODEST_BASE_PROBABILITY = 32;
+const int ForgettingCurveUtils::ProbabilityTable::STRONG_BASE_PROBABILITY = 35;
+const int ForgettingCurveUtils::ProbabilityTable::AGGRESSIVE_BASE_PROBABILITY = 40;
+
+
+ForgettingCurveUtils::ProbabilityTable::ProbabilityTable() : mTables() {
+ mTables.resize(PROBABILITY_TABLE_COUNT);
+ for (int tableId = 0; tableId < PROBABILITY_TABLE_COUNT; ++tableId) {
+ mTables[tableId].resize(MAX_LEVEL + 1);
+ for (int level = 0; level <= MAX_LEVEL; ++level) {
+ mTables[tableId][level].resize(MAX_ELAPSED_TIME_STEP_COUNT + 1);
+ const float initialProbability = getBaseProbabilityForLevel(tableId, level);
+ const float endProbability = getBaseProbabilityForLevel(tableId, level - 1);
+ for (int timeStepCount = 0; timeStepCount <= MAX_ELAPSED_TIME_STEP_COUNT;
+ ++timeStepCount) {
+ if (level == 0) {
+ mTables[tableId][level][timeStepCount] = NOT_A_PROBABILITY;
+ continue;
+ }
+ const float probability = initialProbability
+ * powf(initialProbability / endProbability,
+ -1.0f * static_cast<float>(timeStepCount)
+ / static_cast<float>(MAX_ELAPSED_TIME_STEP_COUNT + 1));
+ mTables[tableId][level][timeStepCount] =
+ min(max(static_cast<int>(probability), 1), MAX_PROBABILITY);
}
- const int elapsedTime = timeStepCount * TIME_STEP_DURATION_IN_SECONDS;
- const float probability = initialProbability
- * powf(2.0f, -1.0f * static_cast<float>(elapsedTime)
- / static_cast<float>(TIME_STEP_DURATION_IN_SECONDS
- * (MAX_ELAPSED_TIME_STEP_COUNT + 1)));
- mTable[level][timeStepCount] =
- min(max(static_cast<int>(probability), 1), MAX_COMPUTED_PROBABILITY);
}
}
}
+/* static */ int ForgettingCurveUtils::ProbabilityTable::getBaseProbabilityForLevel(
+ const int tableId, const int level) {
+ if (tableId == WEAK_PROBABILITY_TABLE_ID) {
+ // Max probability is 127.
+ return static_cast<float>(WEAK_MAX_PROBABILITY / (1 << (MAX_LEVEL - level)));
+ } else if (tableId == MODEST_PROBABILITY_TABLE_ID) {
+ // Max probability is 128.
+ return static_cast<float>(MODEST_BASE_PROBABILITY * (level + 1));
+ } else if (tableId == STRONG_PROBABILITY_TABLE_ID) {
+ // Max probability is 140.
+ return static_cast<float>(STRONG_BASE_PROBABILITY * (level + 1));
+ } else if (tableId == AGGRESSIVE_PROBABILITY_TABLE_ID) {
+ // Max probability is 160.
+ return static_cast<float>(AGGRESSIVE_BASE_PROBABILITY * (level + 1));
+ } else {
+ return NOT_A_PROBABILITY;
+ }
+}
+
} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h b/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h
index b37353455..bb8690939 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h
@@ -24,31 +24,39 @@
namespace latinime {
-class DictionaryHeaderStructurePolicy;
+class HeaderPolicy;
class ForgettingCurveUtils {
public:
- static const int MAX_UNIGRAM_COUNT;
- static const int MAX_UNIGRAM_COUNT_AFTER_GC;
- static const int MAX_BIGRAM_COUNT;
- static const int MAX_BIGRAM_COUNT_AFTER_GC;
-
static const HistoricalInfo createUpdatedHistoricalInfo(
const HistoricalInfo *const originalHistoricalInfo, const int newProbability,
- const int timestamp);
+ const int timestamp, const HeaderPolicy *const headerPolicy);
static const HistoricalInfo createHistoricalInfoToSave(
- const HistoricalInfo *const originalHistoricalInfo);
+ const HistoricalInfo *const originalHistoricalInfo,
+ const HeaderPolicy *const headerPolicy);
- static int decodeProbability(const HistoricalInfo *const historicalInfo);
+ static int decodeProbability(const HistoricalInfo *const historicalInfo,
+ const HeaderPolicy *const headerPolicy);
static int getProbability(const int encodedUnigramProbability,
const int encodedBigramProbability);
- static bool needsToKeep(const HistoricalInfo *const historicalInfo);
+ static bool needsToKeep(const HistoricalInfo *const historicalInfo,
+ const HeaderPolicy *const headerPolicy);
static bool needsToDecay(const bool mindsBlockByDecay, const int unigramCount,
- const int bigramCount, const DictionaryHeaderStructurePolicy *const headerPolicy);
+ const int bigramCount, const HeaderPolicy *const headerPolicy);
+
+ AK_FORCE_INLINE static int getUnigramCountHardLimit(const int maxUnigramCount) {
+ return static_cast<int>(static_cast<float>(maxUnigramCount)
+ * UNIGRAM_COUNT_HARD_LIMIT_WEIGHT);
+ }
+
+ AK_FORCE_INLINE static int getBigramCountHardLimit(const int maxBigramCount) {
+ return static_cast<int>(static_cast<float>(maxBigramCount)
+ * BIGRAM_COUNT_HARD_LIMIT_WEIGHT);
+ }
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ForgettingCurveUtils);
@@ -57,32 +65,46 @@ class ForgettingCurveUtils {
public:
ProbabilityTable();
- int getProbability(const int level, const int elapsedTimeStepCount) const {
- return mTable[level][elapsedTimeStepCount];
+ int getProbability(const int tableId, const int level,
+ const int elapsedTimeStepCount) const {
+ return mTables[tableId][level][elapsedTimeStepCount];
}
private:
DISALLOW_COPY_AND_ASSIGN(ProbabilityTable);
- std::vector<std::vector<int> > mTable;
+ static const int PROBABILITY_TABLE_COUNT;
+ static const int WEAK_PROBABILITY_TABLE_ID;
+ static const int MODEST_PROBABILITY_TABLE_ID;
+ static const int STRONG_PROBABILITY_TABLE_ID;
+ static const int AGGRESSIVE_PROBABILITY_TABLE_ID;
+
+ static const int WEAK_MAX_PROBABILITY;
+ static const int MODEST_BASE_PROBABILITY;
+ static const int STRONG_BASE_PROBABILITY;
+ static const int AGGRESSIVE_BASE_PROBABILITY;
+
+ std::vector<std::vector<std::vector<int> > > mTables;
+
+ static int getBaseProbabilityForLevel(const int tableId, const int level);
};
- static const int MAX_COMPUTED_PROBABILITY;
+ static const int MULTIPLIER_TWO_IN_PROBABILITY_SCALE;
static const int DECAY_INTERVAL_SECONDS;
static const int MAX_LEVEL;
- static const int MAX_COUNT;
static const int MIN_VALID_LEVEL;
- static const int TIME_STEP_DURATION_IN_SECONDS;
static const int MAX_ELAPSED_TIME_STEP_COUNT;
static const int DISCARD_LEVEL_ZERO_ENTRY_TIME_STEP_COUNT_THRESHOLD;
- static const int HALF_LIFE_TIME_IN_SECONDS;
+
+ static const float UNIGRAM_COUNT_HARD_LIMIT_WEIGHT;
+ static const float BIGRAM_COUNT_HARD_LIMIT_WEIGHT;
static const ProbabilityTable sProbabilityTable;
static int backoff(const int unigramProbability);
- static int getElapsedTimeStepCount(const int timestamp);
+ static int getElapsedTimeStepCount(const int timestamp, const int durationToLevelDown);
};
} // namespace latinime
#endif /* LATINIME_FORGETTING_CURVE_UTILS_H */
diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetTestsBase.java b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetTestsBase.java
new file mode 100644
index 000000000..9939a4335
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetTestsBase.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.keyboard;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.ContextThemeWrapper;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodSubtype;
+
+import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils;
+import com.android.inputmethod.keyboard.KeyboardLayoutSet.Builder;
+import com.android.inputmethod.keyboard.KeyboardSwitcher.KeyboardTheme;
+import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.RichInputMethodManager;
+import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.ResourceUtils;
+import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
+
+import java.util.ArrayList;
+import java.util.Locale;
+
+@SmallTest
+public class KeyboardLayoutSetTestsBase extends AndroidTestCase {
+ private static final int NUMBER_OF_SUBTYPES = 63;
+ private static final int NUMBER_OF_ASCII_CAPABLE_SUBTYPES = 40;
+
+ private static final KeyboardTheme DEFAULT_KEYBOARD_THEME =
+ KeyboardSwitcher.KEYBOARD_THEMES[KeyboardSwitcher.THEME_INDEX_DEFAULT];
+
+ // All input method subtypes of LatinIME.
+ private final ArrayList<InputMethodSubtype> mAllSubtypesList = CollectionUtils.newArrayList();
+ private final ArrayList<InputMethodSubtype> mAsciiCapableSubtypesList =
+ CollectionUtils.newArrayList();
+
+ private Context mThemeContext;
+ private int mScreenMetrics;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mScreenMetrics = mContext.getResources().getInteger(R.integer.config_screen_metrics);
+
+ mThemeContext = new ContextThemeWrapper(mContext, DEFAULT_KEYBOARD_THEME.mStyleId);
+ RichInputMethodManager.init(mThemeContext);
+ final RichInputMethodManager richImm = RichInputMethodManager.getInstance();
+
+ final InputMethodInfo imi = richImm.getInputMethodInfoOfThisIme();
+ final int subtypeCount = imi.getSubtypeCount();
+ for (int index = 0; index < subtypeCount; index++) {
+ final InputMethodSubtype subtype = imi.getSubtypeAt(index);
+ mAllSubtypesList.add(subtype);
+ if (InputMethodSubtypeCompatUtils.isAsciiCapable(subtype)) {
+ mAsciiCapableSubtypesList.add(subtype);
+ }
+ }
+ }
+
+ protected final boolean isPhone() {
+ return mScreenMetrics == Constants.SCREEN_METRICS_SMALL_PHONE
+ || mScreenMetrics == Constants.SCREEN_METRICS_LARGE_PHONE;
+ }
+
+ private static String toString(final ArrayList<InputMethodSubtype> subtypeList) {
+ final StringBuilder sb = new StringBuilder();
+ for (int index = 0; index < subtypeList.size(); index++) {
+ final InputMethodSubtype subtype = subtypeList.get(index);
+ sb.append((index + 1) + ": ");
+ sb.append(SubtypeLocaleUtils.getSubtypeNameForLogging(subtype));
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+
+ public final void testAllSubtypesCount() {
+ assertEquals(toString(mAllSubtypesList),
+ NUMBER_OF_SUBTYPES, mAllSubtypesList.size());
+ }
+
+ public final void testAsciiCapableSubtypesCount() {
+ assertEquals(toString(mAsciiCapableSubtypesList),
+ NUMBER_OF_ASCII_CAPABLE_SUBTYPES, mAsciiCapableSubtypesList.size());
+ }
+
+ protected final InputMethodSubtype getSubtype(final Locale locale,
+ final String keyboardLayout) {
+ for (final InputMethodSubtype subtype : mAllSubtypesList) {
+ final Locale subtypeLocale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
+ final String subtypeLayout = SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype);
+ if (locale.equals(subtypeLocale) && keyboardLayout.equals(subtypeLayout)) {
+ // Found subtype that matches locale and keyboard layout.
+ return subtype;
+ }
+ }
+ for (final InputMethodSubtype subtype : mAsciiCapableSubtypesList) {
+ final Locale subtypeLocale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
+ if (locale.equals(subtypeLocale)) {
+ // Create additional subtype.
+ return AdditionalSubtypeUtils.createAdditionalSubtype(
+ locale.toString(), keyboardLayout, null /* extraValue */);
+ }
+ }
+ throw new RuntimeException(
+ "Unknown subtype: locale=" + locale + " keyboardLayout=" + keyboardLayout);
+ }
+
+ protected final KeyboardLayoutSet createKeyboardLayoutSet(final InputMethodSubtype subtype,
+ final EditorInfo editorInfo) {
+ return createKeyboardLayoutSet(subtype, editorInfo, false /* isShortcutImeEnabled */,
+ false /* showsVoiceInputKey */, false /* isLanguageSwitchKeyEnabled */);
+ }
+
+ protected final KeyboardLayoutSet createKeyboardLayoutSet(final InputMethodSubtype subtype,
+ final EditorInfo editorInfo, final boolean isShortcutImeEnabled,
+ final boolean showsVoiceInputKey, final boolean isLanguageSwitchKeyEnabled) {
+ final Context context = mThemeContext;
+ final Resources res = context.getResources();
+ final int keyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res);
+ final int keyboardHeight = ResourceUtils.getDefaultKeyboardHeight(res);
+ final Builder builder = new Builder(context, editorInfo);
+ builder.setKeyboardGeometry(keyboardWidth, keyboardHeight)
+ .setSubtype(subtype)
+ .setOptions(isShortcutImeEnabled, showsVoiceInputKey, isLanguageSwitchKeyEnabled);
+ return builder.build();
+ }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSetTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSetTests.java
new file mode 100644
index 000000000..17d768718
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSetTests.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.keyboard.internal;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodSubtype;
+
+import com.android.inputmethod.latin.RichInputMethodManager;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.RunInLocale;
+import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+
+@SmallTest
+public final class KeyboardTextsSetTests extends AndroidTestCase {
+ // All input method subtypes of LatinIME.
+ private List<InputMethodSubtype> mAllSubtypesList;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ RichInputMethodManager.init(getContext());
+ final RichInputMethodManager richImm = RichInputMethodManager.getInstance();
+
+ final ArrayList<InputMethodSubtype> allSubtypesList = CollectionUtils.newArrayList();
+ final InputMethodInfo imi = richImm.getInputMethodInfoOfThisIme();
+ final int subtypeCount = imi.getSubtypeCount();
+ for (int index = 0; index < subtypeCount; index++) {
+ final InputMethodSubtype subtype = imi.getSubtypeAt(index);
+ allSubtypesList.add(subtype);
+ }
+ mAllSubtypesList = Collections.unmodifiableList(allSubtypesList);
+ }
+
+ // Test that the text {@link KeyboardTextsSet#SWITCH_TO_ALPHA_KEY_LABEL} exists for all
+ // subtypes. The text is needed to implement Emoji Keyboard, see
+ // {@link KeyboardSwitcher#setEmojiKeyboard()}.
+ public void testSwitchToAlphaKeyLabel() {
+ final KeyboardTextsSet textsSet = new KeyboardTextsSet();
+ for (final InputMethodSubtype subtype : mAllSubtypesList) {
+ final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
+ textsSet.setLocale(locale);
+ final String switchToAlphaKeyLabel = textsSet.getText(
+ KeyboardTextsSet.SWITCH_TO_ALPHA_KEY_LABEL);
+ assertNotNull("Switch to alpha key label of " + locale, switchToAlphaKeyLabel);
+ assertFalse("Switch to alpha key label of " + locale, switchToAlphaKeyLabel.isEmpty());
+ }
+ }
+
+ private static final String[] TEXT_NAMES_FROM_RESOURCE = {
+ // Labels for action.
+ "label_go_key",
+ "label_send_key",
+ "label_next_key",
+ "label_done_key",
+ "label_previous_key",
+ // Other labels.
+ "label_pause_key",
+ "label_wait_key",
+ };
+
+ // Test that the text from resources are correctly loaded for all subtypes.
+ public void testTextFromResources() {
+ final Context context = getContext();
+ final KeyboardTextsSet textsSet = new KeyboardTextsSet();
+ for (final InputMethodSubtype subtype : mAllSubtypesList) {
+ final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
+ textsSet.setLocale(locale);
+ final RunInLocale<Void> job = new RunInLocale<Void>() {
+ @Override
+ protected Void job(final Resources res) {
+ textsSet.loadStringResources(context);
+ return null;
+ }
+ };
+ job.runInLocale(context.getResources(), locale);
+ for (final String name : TEXT_NAMES_FROM_RESOURCE) {
+ final String text = textsSet.getText(name);
+ assertNotNull(name + " of " + locale, text);
+ assertFalse(name + " of " + locale, text.isEmpty());
+ }
+ }
+ }
+}
diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
index f4b16a7e1..fa5123665 100644
--- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
+++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
@@ -150,7 +150,7 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
binaryDictionary.flushWithGC();
binaryDictionary.close();
- final DictDecoder dictDecoder = FormatSpec.getDictDecoder(dictFile);
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(dictFile, 0, dictFile.length());
try {
final FusionDictionary dict =
dictDecoder.readDictionaryBinary(false /* deleteDictIfBroken */);
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
index e21e340c2..0ee0fb577 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
@@ -251,7 +251,8 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
FusionDictionary dict = null;
try {
- final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, bufferType);
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, 0, file.length(),
+ bufferType);
now = System.currentTimeMillis();
dict = dictDecoder.readDictionaryBinary(false /* deleteDictIfBroken */);
diff = System.currentTimeMillis() - now;
@@ -413,7 +414,8 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
long now = -1, diff = -1;
try {
- final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, bufferType);
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, 0, file.length(),
+ bufferType);
now = System.currentTimeMillis();
dictDecoder.readUnigramsAndBigramsBinary(resultWords, resultFreqs, resultBigrams);
diff = System.currentTimeMillis() - now;
@@ -537,7 +539,8 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
addBigrams(dict, words, bigrams);
timeWritingDictToFile(file, dict, formatOptions);
- final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, DictDecoder.USE_BYTEARRAY);
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, 0, file.length(),
+ DictDecoder.USE_BYTEARRAY);
try {
dictDecoder.openDictBuffer();
} catch (IOException e) {
diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoderTests.java
index a85753e6b..9dc2b1058 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoderTests.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoderTests.java
@@ -68,7 +68,8 @@ public class Ver2DictDecoderTests extends AndroidTestCase {
}
assertNotNull(testFile);
- final Ver2DictDecoder dictDecoder = new Ver2DictDecoder(testFile, factory);
+ final Ver2DictDecoder dictDecoder = new Ver2DictDecoder(testFile, 0, testFile.length(),
+ factory);
try {
dictDecoder.openDictBuffer();
} catch (Exception e) {
@@ -110,7 +111,8 @@ public class Ver2DictDecoderTests extends AndroidTestCase {
Log.e(TAG, "IOException while the creating temporary file", e);
}
- final Ver2DictDecoder dictDecoder = new Ver2DictDecoder(testFile, factory);
+ final Ver2DictDecoder dictDecoder = new Ver2DictDecoder(testFile, 0, testFile.length(),
+ factory);
// the default return value of getBuffer() must be null.
assertNull("the default return value of getBuffer() is not null",
diff --git a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java
index b1239f0af..6ace2de4f 100644
--- a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java
@@ -267,13 +267,13 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
assertTrue(dict.isInUnderlyingBinaryDictionaryForTests(word));
}
forcePassingShortTime();
- dict.decayIfNeeded();
+ dict.runGCIfRequired();
dict.waitAllTasksForTests();
for (final String word : words) {
assertTrue(dict.isInUnderlyingBinaryDictionaryForTests(word));
}
forcePassingLongTime();
- dict.decayIfNeeded();
+ dict.runGCIfRequired();
dict.waitAllTasksForTests();
for (final String word : words) {
assertFalse(dict.isInUnderlyingBinaryDictionaryForTests(word));
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
index d1df81b52..e31ac2ab6 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
@@ -192,7 +192,7 @@ public final class BinaryDictOffdeviceUtils {
new BufferedInputStream(new FileInputStream(decodedSpec.mFile)));
} else {
final DictDecoder dictDecoder = FormatSpec.getDictDecoder(decodedSpec.mFile,
- DictDecoder.USE_BYTEARRAY);
+ 0, decodedSpec.mFile.length(), DictDecoder.USE_BYTEARRAY);
if (report) {
System.out.println("Format : Binary dictionary format");
System.out.println("Packaging : " + decodedSpec.describeChain());
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 80d71fc64..68d785044 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/DictionaryMaker.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/DictionaryMaker.java
@@ -264,7 +264,7 @@ public class DictionaryMaker {
private static FusionDictionary readBinaryFile(final String binaryFilename)
throws FileNotFoundException, IOException, UnsupportedFormatException {
final File file = new File(binaryFilename);
- final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file);
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, 0, file.length());
return dictDecoder.readDictionaryBinary(false /* deleteDictIfBroken */);
}
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java b/tools/dicttool/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
new file mode 100644
index 000000000..a4ad6b514
--- /dev/null
+++ b/tools/dicttool/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
@@ -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.
+ */
+
+package com.android.inputmethod.latin.personalization;
+
+public class PersonalizationHelper {
+ public static void currentTimeChangedForTesting(final int currentTimestamp) {
+ }
+}
diff --git a/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java b/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java
index 7a4f6f7c5..faf00b4a5 100644
--- a/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java
+++ b/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java
@@ -77,7 +77,8 @@ public class BinaryDictOffdeviceUtilsTests extends TestCase {
assertEquals("Wrong decode spec", BinaryDictOffdeviceUtils.COMPRESSION, step);
}
assertEquals("Wrong decode spec", 3, decodeSpec.mDecoderSpec.size());
- final DictDecoder dictDecoder = FormatSpec.getDictDecoder(decodeSpec.mFile);
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(decodeSpec.mFile, 0,
+ decodeSpec.mFile.length());
final FusionDictionary resultDict =
dictDecoder.readDictionaryBinary(false /* deleteDictIfBroken */);
assertEquals("Wrong version attribute", VERSION, resultDict.mOptions.mAttributes.get(
diff --git a/tools/make-keyboard-text/res/values-af/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-af/donottranslate-more-keys.xml
index ee96f442d..5a90e62bd 100644
--- a/tools/make-keyboard-text/res/values-af/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-af/donottranslate-more-keys.xml
@@ -62,7 +62,6 @@
<!-- U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE -->
<string name="more_keys_for_n">&#x00F1;,&#x0144;</string>
- <string name="more_keys_for_y">&#x00FD;,&#x0177;,&#x00FF;,&#x0133;</string>
<!-- U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
U+0133: "ij" LATIN SMALL LIGATURE IJ -->
<string name="more_keys_for_y">&#x00FD;,&#x0133;</string>