diff options
Diffstat (limited to 'java')
20 files changed, 425 insertions, 265 deletions
diff --git a/java/res/values-da/strings-talkback-descriptions.xml b/java/res/values-da/strings-talkback-descriptions.xml index 658f47651..2d613d6c7 100644 --- a/java/res/values-da/strings-talkback-descriptions.xml +++ b/java/res/values-da/strings-talkback-descriptions.xml @@ -26,7 +26,7 @@ <string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> retter <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> til <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string> <string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> udfører automatisk stavekontrol"</string> <string name="spoken_description_unknown" msgid="2382510329910793539">"Tastekode %d"</string> - <string name="spoken_description_shift" msgid="7209798151676638728">"Shift-tast"</string> + <string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string> <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift er aktiveret (tryk for at deaktivere)"</string> <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps lock er slået til (tryk for at deaktivere)"</string> <string name="spoken_description_delete" msgid="3878902286264983302">"Slet"</string> @@ -36,9 +36,9 @@ <string name="spoken_description_settings" msgid="7281251004003143204">"Indstillinger"</string> <string name="spoken_description_tab" msgid="8210782459446866716">"Fane"</string> <string name="spoken_description_space" msgid="5908716896642059145">"Mellemrum"</string> - <string name="spoken_description_mic" msgid="6153138783813452464">"Taleinput"</string> + <string name="spoken_description_mic" msgid="6153138783813452464">"Stemmeinput"</string> <string name="spoken_description_emoji" msgid="7990051553008088470">"Emoji"</string> - <string name="spoken_description_return" msgid="3183692287397645708">"Tilbage"</string> + <string name="spoken_description_return" msgid="3183692287397645708">"Return"</string> <string name="spoken_description_search" msgid="5099937658231911288">"Søgning"</string> <string name="spoken_description_dot" msgid="5644176501632325560">"Prik"</string> <string name="spoken_description_language_switch" msgid="6818666779313544553">"Skift sprog"</string> diff --git a/java/res/values-fi/strings-talkback-descriptions.xml b/java/res/values-fi/strings-talkback-descriptions.xml new file mode 100644 index 000000000..2d0d7a782 --- /dev/null +++ b/java/res/values-fi/strings-talkback-descriptions.xml @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2014, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="spoken_use_headphones" msgid="4313642710742229868">"Liitä kuulokkeet, niin kuulet mitä näppäimiä painat kirjoittaessasi salasanaa."</string> + <string name="spoken_current_text_is" msgid="4240549866156675799">"Nykyinen teksti on %s"</string> + <string name="spoken_no_text_entered" msgid="1711276837961785646">"Ei kirjoitettua tekstiä"</string> + <string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> korjaa sanan <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> sanaksi <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string> + <string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> suorittaa automaattisen korjauksen"</string> + <string name="spoken_description_unknown" msgid="2382510329910793539">"Näppäimen koodi %d"</string> + <string name="spoken_description_shift" msgid="7209798151676638728">"Vaihto"</string> + <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Vaihto päällä (poista käytöstä napauttamalla)"</string> + <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps Lock päällä (poista käytöstä napauttamalla)"</string> + <string name="spoken_description_delete" msgid="3878902286264983302">"Delete"</string> + <string name="spoken_description_to_symbol" msgid="8244903740201126590">"Symbolit"</string> + <string name="spoken_description_to_alpha" msgid="4081215210530031950">"Kirjaimet"</string> + <string name="spoken_description_to_numeric" msgid="4560261331530795682">"Numerot"</string> + <string name="spoken_description_settings" msgid="7281251004003143204">"Asetukset"</string> + <string name="spoken_description_tab" msgid="8210782459446866716">"Sarkain"</string> + <string name="spoken_description_space" msgid="5908716896642059145">"Välilyönti"</string> + <string name="spoken_description_mic" msgid="6153138783813452464">"Äänisyöte"</string> + <string name="spoken_description_emoji" msgid="7990051553008088470">"Emoji"</string> + <string name="spoken_description_return" msgid="3183692287397645708">"Enter"</string> + <string name="spoken_description_search" msgid="5099937658231911288">"Haku"</string> + <string name="spoken_description_dot" msgid="5644176501632325560">"Piste"</string> + <string name="spoken_description_language_switch" msgid="6818666779313544553">"Vaihda kieli"</string> + <string name="spoken_description_action_next" msgid="431761808119616962">"Seuraava"</string> + <string name="spoken_description_action_previous" msgid="2919072174697865110">"Edellinen"</string> + <string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Vaihto päällä"</string> + <string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps Lock päällä"</string> + <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Vaihto pois päältä"</string> + <string name="spoken_description_mode_symbol" msgid="111186851131446691">"Symbolit-tila"</string> + <string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Näppäimistötila"</string> + <string name="spoken_description_mode_phone" msgid="2061220553756692903">"Puhelintila"</string> + <string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Puhelinsymbolit-tila"</string> + <string name="announce_keyboard_hidden" msgid="2313574218950517779">"Näppäimistö on piilotettu"</string> + <string name="announce_keyboard_mode" msgid="6698257917367823205">"Näytetään näppäimistö <xliff:g id="KEYBOARD_MODE">%s</xliff:g>"</string> + <string name="keyboard_mode_date" msgid="6597407244976713364">"päivämäärä"</string> + <string name="keyboard_mode_date_time" msgid="3642804408726668808">"päivämäärä ja aika"</string> + <string name="keyboard_mode_email" msgid="1239682082047693644">"sähköposti"</string> + <string name="keyboard_mode_im" msgid="3812086215529493501">"viestit"</string> + <string name="keyboard_mode_number" msgid="5395042245837996809">"numero"</string> + <string name="keyboard_mode_phone" msgid="2486230278064523665">"puhelin"</string> + <string name="keyboard_mode_text" msgid="9138789594969187494">"teksti"</string> + <string name="keyboard_mode_time" msgid="8558297845514402675">"aika"</string> + <string name="keyboard_mode_url" msgid="8072011652949962550">"URL-osoite"</string> + <string name="spoken_descrption_emoji_category_recents" msgid="4185344945205590692">"Viimeisimmät"</string> + <string name="spoken_descrption_emoji_category_people" msgid="8414196269847492817">"Ihmiset"</string> + <string name="spoken_descrption_emoji_category_objects" msgid="6116297906606195278">"Esineet"</string> + <string name="spoken_descrption_emoji_category_nature" msgid="5018340512472354640">"Luonto"</string> + <string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Paikat"</string> + <string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Symbolit"</string> + <string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Hymiöt"</string> +</resources> diff --git a/java/res/values-ms-rMY/strings-talkback-descriptions.xml b/java/res/values-ms-rMY/strings-talkback-descriptions.xml new file mode 100644 index 000000000..29c5fd86a --- /dev/null +++ b/java/res/values-ms-rMY/strings-talkback-descriptions.xml @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2014, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="spoken_use_headphones" msgid="4313642710742229868">"Pasangkan set kepala untuk mendengar kekunci kata laluan disebut dengan kuat."</string> + <string name="spoken_current_text_is" msgid="4240549866156675799">"Teks semasa adalah %s"</string> + <string name="spoken_no_text_entered" msgid="1711276837961785646">"Tiada teks dimasukkan"</string> + <string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> membetulkan <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> menjadi <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string> + <string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> melakukan auto pembetulan"</string> + <string name="spoken_description_unknown" msgid="2382510329910793539">"Kod kunci %d"</string> + <string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string> + <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Kunci anjak dihidupkan (ketik untuk melumpuhkan)"</string> + <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Kunci huruf besar dihidupkan (ketik untuk melumpuhkan)"</string> + <string name="spoken_description_delete" msgid="3878902286264983302">"Padam"</string> + <string name="spoken_description_to_symbol" msgid="8244903740201126590">"Simbol"</string> + <string name="spoken_description_to_alpha" msgid="4081215210530031950">"Huruf"</string> + <string name="spoken_description_to_numeric" msgid="4560261331530795682">"Nombor"</string> + <string name="spoken_description_settings" msgid="7281251004003143204">"Tetapan"</string> + <string name="spoken_description_tab" msgid="8210782459446866716">"Tab"</string> + <string name="spoken_description_space" msgid="5908716896642059145">"{0}<td class=\"shortcuts\">{/0} Space"</string> + <string name="spoken_description_mic" msgid="6153138783813452464">"Input suara"</string> + <string name="spoken_description_emoji" msgid="7990051553008088470">"Emoji"</string> + <string name="spoken_description_return" msgid="3183692287397645708">"Kembali"</string> + <string name="spoken_description_search" msgid="5099937658231911288">"Carian"</string> + <string name="spoken_description_dot" msgid="5644176501632325560">"Titik"</string> + <string name="spoken_description_language_switch" msgid="6818666779313544553">"Tukar bahasa"</string> + <string name="spoken_description_action_next" msgid="431761808119616962">"Slps"</string> + <string name="spoken_description_action_previous" msgid="2919072174697865110">"Sebelumnya"</string> + <string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Kunci anjak didayakan"</string> + <string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Kunci huruf besar didayakan"</string> + <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Kunci anjak dilumpuhkan"</string> + <string name="spoken_description_mode_symbol" msgid="111186851131446691">"Mod simbol"</string> + <string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Mod huruf"</string> + <string name="spoken_description_mode_phone" msgid="2061220553756692903">"Mod telefon"</string> + <string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Mod simbol telefon"</string> + <string name="announce_keyboard_hidden" msgid="2313574218950517779">"Papan kekunci tersembunyi"</string> + <string name="announce_keyboard_mode" msgid="6698257917367823205">"Menunjukkan papan kekunci <xliff:g id="KEYBOARD_MODE">%s</xliff:g>"</string> + <string name="keyboard_mode_date" msgid="6597407244976713364">"tarikh"</string> + <string name="keyboard_mode_date_time" msgid="3642804408726668808">"tarikh dan masa"</string> + <string name="keyboard_mode_email" msgid="1239682082047693644">"e-mel"</string> + <string name="keyboard_mode_im" msgid="3812086215529493501">"pemesejan"</string> + <string name="keyboard_mode_number" msgid="5395042245837996809">"nombor"</string> + <string name="keyboard_mode_phone" msgid="2486230278064523665">"telefon"</string> + <string name="keyboard_mode_text" msgid="9138789594969187494">"teks"</string> + <string name="keyboard_mode_time" msgid="8558297845514402675">"masa"</string> + <string name="keyboard_mode_url" msgid="8072011652949962550">"URL"</string> + <string name="spoken_descrption_emoji_category_recents" msgid="4185344945205590692">"Terkini"</string> + <string name="spoken_descrption_emoji_category_people" msgid="8414196269847492817">"Orang"</string> + <string name="spoken_descrption_emoji_category_objects" msgid="6116297906606195278">"Objek"</string> + <string name="spoken_descrption_emoji_category_nature" msgid="5018340512472354640">"Alam Semula Jadi"</string> + <string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Tempat"</string> + <string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Simbol"</string> + <string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emotikon"</string> +</resources> diff --git a/java/res/values-nb/strings-talkback-descriptions.xml b/java/res/values-nb/strings-talkback-descriptions.xml index 5a29d802c..96edf38c8 100644 --- a/java/res/values-nb/strings-talkback-descriptions.xml +++ b/java/res/values-nb/strings-talkback-descriptions.xml @@ -60,7 +60,7 @@ <string name="keyboard_mode_number" msgid="5395042245837996809">"tall"</string> <string name="keyboard_mode_phone" msgid="2486230278064523665">"telefon"</string> <string name="keyboard_mode_text" msgid="9138789594969187494">"tekst"</string> - <string name="keyboard_mode_time" msgid="8558297845514402675">"tid"</string> + <string name="keyboard_mode_time" msgid="8558297845514402675">"klokkeslett"</string> <string name="keyboard_mode_url" msgid="8072011652949962550">"nettadresse"</string> <string name="spoken_descrption_emoji_category_recents" msgid="4185344945205590692">"Nylige"</string> <string name="spoken_descrption_emoji_category_people" msgid="8414196269847492817">"Personer"</string> diff --git a/java/res/values-sw/strings-talkback-descriptions.xml b/java/res/values-sw/strings-talkback-descriptions.xml index 120489ffd..e9ca282b9 100644 --- a/java/res/values-sw/strings-talkback-descriptions.xml +++ b/java/res/values-sw/strings-talkback-descriptions.xml @@ -20,13 +20,13 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="spoken_use_headphones" msgid="4313642710742229868">"Chomeka kifaa cha sauti ili usikie vitufe vya nenosiri vinayozungumwa kwa sauti."</string> + <string name="spoken_use_headphones" msgid="4313642710742229868">"Chomeka kifaa cha sauti ili usikie vitufe vya nenosiri vikitamkwa kwa sauti."</string> <string name="spoken_current_text_is" msgid="4240549866156675799">"Maandishi ya sasa ni %s"</string> <string name="spoken_no_text_entered" msgid="1711276837961785646">"Hakuna maandishi yaliyoingizwa"</string> <string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> hurekebisha <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> kuwa <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string> <string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> hufanya marekebisho otomatiki"</string> <string name="spoken_description_unknown" msgid="2382510329910793539">"Msimbo wa kitufe %d"</string> - <string name="spoken_description_shift" msgid="7209798151676638728">"Badilisha"</string> + <string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string> <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift imewashwa (gonga ili kuizima)"</string> <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps lock imewashwa (gonga ili kuizima)"</string> <string name="spoken_description_delete" msgid="3878902286264983302">"Futa"</string> @@ -40,15 +40,15 @@ <string name="spoken_description_emoji" msgid="7990051553008088470">"Emoji"</string> <string name="spoken_description_return" msgid="3183692287397645708">"Rudi"</string> <string name="spoken_description_search" msgid="5099937658231911288">"Utafutaji"</string> - <string name="spoken_description_dot" msgid="5644176501632325560">"Doa"</string> - <string name="spoken_description_language_switch" msgid="6818666779313544553">"Badili lugha"</string> + <string name="spoken_description_dot" msgid="5644176501632325560">"Nukta"</string> + <string name="spoken_description_language_switch" msgid="6818666779313544553">"Badilisha lugha"</string> <string name="spoken_description_action_next" msgid="431761808119616962">"Linalofuata"</string> - <string name="spoken_description_action_previous" msgid="2919072174697865110">"Iliyotangulia"</string> + <string name="spoken_description_action_previous" msgid="2919072174697865110">"Iililotangulia"</string> <string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift imewashwa"</string> - <string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Herufi kubwa zimewashwa"</string> + <string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps lock imewashwa"</string> <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift imezimwa"</string> <string name="spoken_description_mode_symbol" msgid="111186851131446691">"Hali ya alama"</string> - <string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Hali ya barua"</string> + <string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Hali ya herufi"</string> <string name="spoken_description_mode_phone" msgid="2061220553756692903">"Hali ya simu"</string> <string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Hali ya alama za simu"</string> <string name="announce_keyboard_hidden" msgid="2313574218950517779">"Kibodi imefichwa"</string> @@ -62,7 +62,7 @@ <string name="keyboard_mode_text" msgid="9138789594969187494">"maandishi"</string> <string name="keyboard_mode_time" msgid="8558297845514402675">"wakati"</string> <string name="keyboard_mode_url" msgid="8072011652949962550">"URL"</string> - <string name="spoken_descrption_emoji_category_recents" msgid="4185344945205590692">"Zilizotumika karibuni"</string> + <string name="spoken_descrption_emoji_category_recents" msgid="4185344945205590692">"Zilizotumika majuzi"</string> <string name="spoken_descrption_emoji_category_people" msgid="8414196269847492817">"Watu"</string> <string name="spoken_descrption_emoji_category_objects" msgid="6116297906606195278">"Vitu"</string> <string name="spoken_descrption_emoji_category_nature" msgid="5018340512472354640">"Maumbile"</string> diff --git a/java/res/values-th/strings-talkback-descriptions.xml b/java/res/values-th/strings-talkback-descriptions.xml index 4e4698741..eb712aeac 100644 --- a/java/res/values-th/strings-talkback-descriptions.xml +++ b/java/res/values-th/strings-talkback-descriptions.xml @@ -35,7 +35,7 @@ <string name="spoken_description_to_numeric" msgid="4560261331530795682">"หมายเลข"</string> <string name="spoken_description_settings" msgid="7281251004003143204">"การตั้งค่า"</string> <string name="spoken_description_tab" msgid="8210782459446866716">"แท็บ"</string> - <string name="spoken_description_space" msgid="5908716896642059145">"{0}<td{1} {/1}class=\"shortcuts\">{/0} Space"</string> + <string name="spoken_description_space" msgid="5908716896642059145">"วรรค"</string> <string name="spoken_description_mic" msgid="6153138783813452464">"การป้อนข้อมูลด้วยเสียง"</string> <string name="spoken_description_emoji" msgid="7990051553008088470">"อีโมจิ"</string> <string name="spoken_description_return" msgid="3183692287397645708">"ส่งคืน"</string> diff --git a/java/res/values-zh-rCN/strings-talkback-descriptions.xml b/java/res/values-zh-rCN/strings-talkback-descriptions.xml index 73594b2a8..93f89e091 100644 --- a/java/res/values-zh-rCN/strings-talkback-descriptions.xml +++ b/java/res/values-zh-rCN/strings-talkback-descriptions.xml @@ -27,8 +27,8 @@ <string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"按<xliff:g id="KEY_NAME">%1$s</xliff:g>键可进行自动更正"</string> <string name="spoken_description_unknown" msgid="2382510329910793539">"键码为%d"</string> <string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string> - <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift模式已启用(点按即可停用)"</string> - <string name="spoken_description_caps_lock" msgid="5020582161133170892">"大写锁定模式已启用(点按即可停用)"</string> + <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"已开启Shift模式(点按即可关闭)"</string> + <string name="spoken_description_caps_lock" msgid="5020582161133170892">"已锁定大写模式(点按即可关闭)"</string> <string name="spoken_description_delete" msgid="3878902286264983302">"删除"</string> <string name="spoken_description_to_symbol" msgid="8244903740201126590">"符号"</string> <string name="spoken_description_to_alpha" msgid="4081215210530031950">"字母"</string> @@ -38,15 +38,15 @@ <string name="spoken_description_space" msgid="5908716896642059145">"空格"</string> <string name="spoken_description_mic" msgid="6153138783813452464">"语音输入"</string> <string name="spoken_description_emoji" msgid="7990051553008088470">"表情符号"</string> - <string name="spoken_description_return" msgid="3183692287397645708">"返回"</string> + <string name="spoken_description_return" msgid="3183692287397645708">"回车"</string> <string name="spoken_description_search" msgid="5099937658231911288">"搜索"</string> <string name="spoken_description_dot" msgid="5644176501632325560">"点"</string> <string name="spoken_description_language_switch" msgid="6818666779313544553">"切换语言"</string> <string name="spoken_description_action_next" msgid="431761808119616962">"下一个"</string> <string name="spoken_description_action_previous" msgid="2919072174697865110">"上一个"</string> - <string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift模式已启用"</string> - <string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"大写锁定模式已启用"</string> - <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift模式已停用"</string> + <string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"已开启Shift模式"</string> + <string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"已锁定大写模式"</string> + <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"已关闭Shift模式"</string> <string name="spoken_description_mode_symbol" msgid="111186851131446691">"符号模式"</string> <string name="spoken_description_mode_alpha" msgid="4676004119618778911">"字母模式"</string> <string name="spoken_description_mode_phone" msgid="2061220553756692903">"电话模式"</string> @@ -62,9 +62,9 @@ <string name="keyboard_mode_text" msgid="9138789594969187494">"文字"</string> <string name="keyboard_mode_time" msgid="8558297845514402675">"时间"</string> <string name="keyboard_mode_url" msgid="8072011652949962550">"网址"</string> - <string name="spoken_descrption_emoji_category_recents" msgid="4185344945205590692">"最近使用"</string> + <string name="spoken_descrption_emoji_category_recents" msgid="4185344945205590692">"最近用过"</string> <string name="spoken_descrption_emoji_category_people" msgid="8414196269847492817">"人物"</string> - <string name="spoken_descrption_emoji_category_objects" msgid="6116297906606195278">"物体"</string> + <string name="spoken_descrption_emoji_category_objects" msgid="6116297906606195278">"物件"</string> <string name="spoken_descrption_emoji_category_nature" msgid="5018340512472354640">"自然"</string> <string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"地点"</string> <string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"符号"</string> diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java index 720cf6b2a..ec1ab3565 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java @@ -17,7 +17,6 @@ package com.android.inputmethod.accessibility; import android.graphics.Rect; -import android.inputmethodservice.InputMethodService; import android.os.Bundle; import android.support.v4.view.ViewCompat; import android.support.v4.view.accessibility.AccessibilityEventCompat; @@ -52,7 +51,6 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider private static final String TAG = AccessibilityEntityProvider.class.getSimpleName(); private static final int UNDEFINED = Integer.MIN_VALUE; - private final InputMethodService mInputMethodService; private final KeyCodeDescriptionMapper mKeyCodeDescriptionMapper; private final AccessibilityUtils mAccessibilityUtils; @@ -71,9 +69,7 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider /** The current keyboard. */ private Keyboard mKeyboard; - public AccessibilityEntityProvider(final KeyboardView keyboardView, - final InputMethodService inputMethod) { - mInputMethodService = inputMethod; + public AccessibilityEntityProvider(final KeyboardView keyboardView) { mKeyCodeDescriptionMapper = KeyCodeDescriptionMapper.getInstance(); mAccessibilityUtils = AccessibilityUtils.getInstance(); setView(keyboardView); @@ -295,7 +291,7 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider * @return The context-specific description of the key. */ private String getKeyDescription(final Key key) { - final EditorInfo editorInfo = mInputMethodService.getCurrentInputEditorInfo(); + final EditorInfo editorInfo = mKeyboard.mId.mEditorInfo; final boolean shouldObscure = mAccessibilityUtils.shouldObscureInput(editorInfo); final SettingsValues currentSettings = Settings.getInstance().getCurrent(); final String keyCodeDescription = mKeyCodeDescriptionMapper.getDescriptionForKey( diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java index 216a825e0..bc094b117 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java @@ -17,7 +17,6 @@ package com.android.inputmethod.accessibility; import android.content.Context; -import android.inputmethodservice.InputMethodService; import android.media.AudioManager; import android.os.Build; import android.os.SystemClock; @@ -63,13 +62,13 @@ public final class AccessibilityUtils { */ private static final boolean ENABLE_ACCESSIBILITY = true; - public static void init(final InputMethodService inputMethod) { + public static void init(final Context context) { if (!ENABLE_ACCESSIBILITY) return; // These only need to be initialized if the kill switch is off. - sInstance.initInternal(inputMethod); + sInstance.initInternal(context); KeyCodeDescriptionMapper.init(); - AccessibleKeyboardViewProxy.init(inputMethod); + AccessibleKeyboardViewProxy.init(context); } public static AccessibilityUtils getInstance() { diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java index e3455c1a1..322127a12 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java @@ -17,7 +17,6 @@ package com.android.inputmethod.accessibility; import android.content.Context; -import android.inputmethodservice.InputMethodService; import android.os.SystemClock; import android.support.v4.view.AccessibilityDelegateCompat; import android.support.v4.view.ViewCompat; @@ -35,6 +34,7 @@ import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardId; import com.android.inputmethod.keyboard.MainKeyboardView; import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat { private static final AccessibleKeyboardViewProxy sInstance = new AccessibleKeyboardViewProxy(); @@ -54,7 +54,6 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_URL, R.string.keyboard_mode_url); } - private InputMethodService mInputMethod; private MainKeyboardView mView; private Keyboard mKeyboard; private AccessibilityEntityProvider mAccessibilityNodeProvider; @@ -67,11 +66,11 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp private int mEdgeSlop; /** The most recently set keyboard mode. */ - private int mLastKeyboardMode; - private static final int NOT_A_KEYBOARD_MODE = -1; + private int mLastKeyboardMode = KEYBOARD_IS_HIDDEN; + private static final int KEYBOARD_IS_HIDDEN = -1; - public static void init(final InputMethodService inputMethod) { - sInstance.initInternal(inputMethod); + public static void init(final Context context) { + sInstance.initInternal(context); } public static AccessibleKeyboardViewProxy getInstance() { @@ -82,9 +81,8 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp // Not publicly instantiable. } - private void initInternal(final InputMethodService inputMethod) { - mInputMethod = inputMethod; - mEdgeSlop = inputMethod.getResources().getDimensionPixelSize( + private void initInternal(final Context context) { + mEdgeSlop = context.getResources().getDimensionPixelSize( R.dimen.config_accessibility_edge_slop); } @@ -124,20 +122,27 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp if (keyboard == null) { return; } - mKeyboard = keyboard; if (mAccessibilityNodeProvider != null) { mAccessibilityNodeProvider.setKeyboard(keyboard); } - final int keyboardMode = keyboard.mId.mMode; + final Keyboard lastKeyboard = mKeyboard; + final int lastKeyboardMode = mLastKeyboardMode; + mKeyboard = keyboard; + mLastKeyboardMode = keyboard.mId.mMode; // Since this method is called even when accessibility is off, make sure - // to check the state before announcing anything. Also, don't announce - // changes within the same mode. - if (AccessibilityUtils.getInstance().isAccessibilityEnabled() - && (mLastKeyboardMode != keyboardMode)) { - announceKeyboardMode(keyboardMode); + // to check the state before announcing anything. + if (!AccessibilityUtils.getInstance().isAccessibilityEnabled()) { + return; + } + // Announce the language name only when the language is changed. + if (lastKeyboard == null || !lastKeyboard.mId.mSubtype.equals(keyboard.mId.mSubtype)) { + announceKeyboardLanguage(keyboard); + } + // Announce the mode only when the mode is changed. + if (lastKeyboardMode != keyboard.mId.mMode) { + announceKeyboardMode(keyboard); } - mLastKeyboardMode = keyboardMode; } /** @@ -148,23 +153,35 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp return; } announceKeyboardHidden(); - mLastKeyboardMode = NOT_A_KEYBOARD_MODE; + mLastKeyboardMode = KEYBOARD_IS_HIDDEN; + } + + /** + * Announces which language of keyboard is being displayed. + * + * @param keyboard The new keyboard. + */ + private void announceKeyboardLanguage(final Keyboard keyboard) { + final String languageText = SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale( + keyboard.mId.mSubtype); + sendWindowStateChanged(languageText); } /** - * Announces which type of keyboard is being displayed. If the keyboard type - * is unknown, no announcement is made. + * Announces which type of keyboard is being displayed. + * If the keyboard type is unknown, no announcement is made. * - * @param mode The new keyboard mode. + * @param keyboard The new keyboard. */ - private void announceKeyboardMode(final int mode) { - final int resId = KEYBOARD_MODE_RES_IDS.get(mode); - if (resId == 0) { + private void announceKeyboardMode(final Keyboard keyboard) { + final int mode = keyboard.mId.mMode; + final Context context = mView.getContext(); + final int modeTextResId = KEYBOARD_MODE_RES_IDS.get(mode); + if (modeTextResId == 0) { return; } - final Context context = mView.getContext(); - final String keyboardMode = context.getString(resId); - final String text = context.getString(R.string.announce_keyboard_mode, keyboardMode); + final String modeText = context.getString(modeTextResId); + final String text = context.getString(R.string.announce_keyboard_mode, modeText); sendWindowStateChanged(text); } @@ -265,7 +282,7 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp // will call this method multiple times it is a good practice to // cache the provider instance. if (mAccessibilityNodeProvider == null) { - mAccessibilityNodeProvider = new AccessibilityEntityProvider(mView, mInputMethod); + mAccessibilityNodeProvider = new AccessibilityEntityProvider(mView); } return mAccessibilityNodeProvider; } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java index 02beb3f11..93a55fe6a 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java @@ -68,7 +68,7 @@ public final class KeyboardId { public final int mHeight; public final int mMode; public final int mElementId; - private final EditorInfo mEditorInfo; + public final EditorInfo mEditorInfo; public final boolean mClobberSettingsKey; public final boolean mSupportsSwitchingToShortcutIme; public final boolean mLanguageSwitchKeyEnabled; diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java index 331384fa5..5238395a4 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java @@ -69,78 +69,68 @@ public class DictionaryFacilitatorForSuggest { public final Locale mLocale; public final ConcurrentHashMap<String, Dictionary> mDictMap = CollectionUtils.newConcurrentHashMap(); - // Main dictionary will be asynchronously loaded. - public Dictionary mMainDictionary; - public final ContactsBinaryDictionary mContactsDictionary; + public final ConcurrentHashMap<String, ExpandableBinaryDictionary> mSubDictMap = + CollectionUtils.newConcurrentHashMap(); + // TODO: Remove sub dictionary members and use mSubDictMap. public final UserBinaryDictionary mUserDictionary; - public final UserHistoryDictionary mUserHistoryDictionary; - public final PersonalizationDictionary mPersonalizationDictionary; public Dictionaries() { mLocale = null; - mMainDictionary = null; - mContactsDictionary = null; mUserDictionary = null; - mUserHistoryDictionary = null; - mPersonalizationDictionary = null; } public Dictionaries(final Locale locale, final Dictionary mainDict, - final ContactsBinaryDictionary contactsDict, final UserBinaryDictionary userDict, - final UserHistoryDictionary userHistoryDict, - final PersonalizationDictionary personalizationDict) { + final ExpandableBinaryDictionary contactsDict, final UserBinaryDictionary userDict, + final ExpandableBinaryDictionary userHistoryDict, + final ExpandableBinaryDictionary personalizationDict) { mLocale = locale; + // Main dictionary can be asynchronously loaded. setMainDict(mainDict); - mContactsDictionary = contactsDict; - if (mContactsDictionary != null) { - mDictMap.put(Dictionary.TYPE_CONTACTS, mContactsDictionary); - } + setSubDict(Dictionary.TYPE_CONTACTS, contactsDict); mUserDictionary = userDict; - if (mUserDictionary != null) { - mDictMap.put(Dictionary.TYPE_USER, mUserDictionary); - } - mUserHistoryDictionary = userHistoryDict; - if (mUserHistoryDictionary != null) { - mDictMap.put(Dictionary.TYPE_USER_HISTORY, mUserHistoryDictionary); - } - mPersonalizationDictionary = personalizationDict; - if (mPersonalizationDictionary != null) { - mDictMap.put(Dictionary.TYPE_PERSONALIZATION, mPersonalizationDictionary); + setSubDict(Dictionary.TYPE_USER, mUserDictionary); + setSubDict(Dictionary.TYPE_USER_HISTORY, userHistoryDict); + setSubDict(Dictionary.TYPE_PERSONALIZATION, personalizationDict); + } + + private void setSubDict(final String dictType, final ExpandableBinaryDictionary dict) { + if (dict != null) { + mDictMap.put(dictType, dict); + mSubDictMap.put(dictType, dict); } } public void setMainDict(final Dictionary mainDict) { - mMainDictionary = mainDict; // Close old dictionary if exists. Main dictionary can be assigned multiple times. final Dictionary oldDict; - if (mMainDictionary != null) { - oldDict = mDictMap.put(Dictionary.TYPE_MAIN, mMainDictionary); + if (mainDict != null) { + oldDict = mDictMap.put(Dictionary.TYPE_MAIN, mainDict); } else { oldDict = mDictMap.remove(Dictionary.TYPE_MAIN); } - if (oldDict != null && mMainDictionary != oldDict) { + if (oldDict != null && mainDict != oldDict) { oldDict.close(); } } - public boolean hasMainDict() { - return mMainDictionary != null; + public Dictionary getMainDict() { + return mDictMap.get(Dictionary.TYPE_MAIN); } - public boolean hasContactsDict() { - return mContactsDictionary != null; + public ExpandableBinaryDictionary getSubDict(final String dictType) { + return mSubDictMap.get(dictType); } - public boolean hasUserDict() { - return mUserDictionary != null; + public boolean hasDict(final String dictType) { + return mDictMap.containsKey(dictType); } - public boolean hasUserHistoryDict() { - return mUserHistoryDictionary != null; - } - - public boolean hasPersonalizationDict() { - return mPersonalizationDictionary != null; + public void closeDict(final String dictType) { + final Dictionary dict = mDictMap.remove(dictType); + mSubDictMap.remove(dictType); + if (dict != null) { + dict.close(); + } } } @@ -172,13 +162,13 @@ public class DictionaryFacilitatorForSuggest { // The main dictionary will be asynchronously loaded. newMainDict = null; } else { - newMainDict = mDictionaries.mMainDictionary; + newMainDict = mDictionaries.getMainDict(); } // Open or move contacts dictionary. - final ContactsBinaryDictionary newContactsDict; - if (!closeContactsDictionary && mDictionaries.hasContactsDict()) { - newContactsDict = mDictionaries.mContactsDictionary; + final ExpandableBinaryDictionary newContactsDict; + if (!closeContactsDictionary && mDictionaries.hasDict(Dictionary.TYPE_CONTACTS)) { + newContactsDict = mDictionaries.getSubDict(Dictionary.TYPE_CONTACTS); } else if (useContactsDict) { newContactsDict = new ContactsBinaryDictionary(context, newLocale); } else { @@ -187,16 +177,16 @@ public class DictionaryFacilitatorForSuggest { // Open or move user dictionary. final UserBinaryDictionary newUserDictionary; - if (!closeUserDictionary && mDictionaries.hasUserDict()) { + if (!closeUserDictionary && mDictionaries.hasDict(Dictionary.TYPE_USER)) { newUserDictionary = mDictionaries.mUserDictionary; } else { newUserDictionary = new UserBinaryDictionary(context, newLocale); } // Open or move user history dictionary. - final UserHistoryDictionary newUserHistoryDict; - if (!closeUserHistoryDictionary && mDictionaries.hasUserHistoryDict()) { - newUserHistoryDict = mDictionaries.mUserHistoryDictionary; + final ExpandableBinaryDictionary newUserHistoryDict; + if (!closeUserHistoryDictionary && mDictionaries.hasDict(Dictionary.TYPE_USER_HISTORY)) { + newUserHistoryDict = mDictionaries.getSubDict(Dictionary.TYPE_USER_HISTORY); } else if (usePersonalizedDicts) { newUserHistoryDict = PersonalizationHelper.getUserHistoryDictionary(context, newLocale); } else { @@ -204,9 +194,10 @@ public class DictionaryFacilitatorForSuggest { } // Open or move personalization dictionary. - final PersonalizationDictionary newPersonalizationDict; - if (!closePersonalizationDictionary && mDictionaries.hasPersonalizationDict()) { - newPersonalizationDict = mDictionaries.mPersonalizationDictionary; + final ExpandableBinaryDictionary newPersonalizationDict; + if (!closePersonalizationDictionary + && mDictionaries.hasDict(Dictionary.TYPE_PERSONALIZATION)) { + newPersonalizationDict = mDictionaries.getSubDict(Dictionary.TYPE_PERSONALIZATION); } else if (usePersonalizedDicts) { newPersonalizationDict = PersonalizationHelper.getPersonalizationDictionary(context, newLocale); @@ -230,22 +221,23 @@ public class DictionaryFacilitatorForSuggest { } // Clean up old dictionaries. - oldDictionaries.mDictMap.clear(); - if (reloadMainDictionary && oldDictionaries.hasMainDict()) { - oldDictionaries.mMainDictionary.close(); + if (reloadMainDictionary) { + oldDictionaries.closeDict(Dictionary.TYPE_MAIN); } - if (closeContactsDictionary && oldDictionaries.hasContactsDict()) { - oldDictionaries.mContactsDictionary.close(); + if (closeContactsDictionary) { + oldDictionaries.closeDict(Dictionary.TYPE_CONTACTS); } - if (closeUserDictionary && oldDictionaries.hasUserDict()) { - oldDictionaries.mUserDictionary.close(); + if (closeUserDictionary) { + oldDictionaries.closeDict(Dictionary.TYPE_USER); } - if (closeUserHistoryDictionary && oldDictionaries.hasUserHistoryDict()) { - oldDictionaries.mUserHistoryDictionary.close(); + if (closeUserHistoryDictionary) { + oldDictionaries.closeDict(Dictionary.TYPE_USER_HISTORY); } - if (closePersonalizationDictionary && oldDictionaries.hasPersonalizationDict()) { - oldDictionaries.mPersonalizationDictionary.close(); + if (closePersonalizationDictionary) { + oldDictionaries.closeDict(Dictionary.TYPE_PERSONALIZATION); } + oldDictionaries.mDictMap.clear(); + oldDictionaries.mSubDictMap.clear(); } private void asyncReloadMainDictionary(final Context context, final Locale locale, @@ -332,39 +324,27 @@ public class DictionaryFacilitatorForSuggest { dictionaries = mDictionaries; mDictionaries = new Dictionaries(); } - if (dictionaries.hasMainDict()) { - dictionaries.mMainDictionary.close(); - } - if (dictionaries.hasContactsDict()) { - dictionaries.mContactsDictionary.close(); - } - if (dictionaries.hasUserDict()) { - dictionaries.mUserDictionary.close(); - } - if (dictionaries.hasUserHistoryDict()) { - dictionaries.mUserHistoryDictionary.close(); - } - if (dictionaries.hasPersonalizationDict()) { - dictionaries.mPersonalizationDictionary.close(); + for (final Dictionary dict : dictionaries.mDictMap.values()) { + dict.close(); } } // The main dictionary could have been loaded asynchronously. Don't cache the return value // of this method. public boolean hasInitializedMainDictionary() { - final Dictionaries dictionaries = mDictionaries; - return dictionaries.hasMainDict() && dictionaries.mMainDictionary.isInitialized(); + final Dictionary mainDict = mDictionaries.getMainDict(); + return mainDict != null && mainDict.isInitialized(); } public boolean hasPersonalizationDictionary() { - return mDictionaries.hasPersonalizationDict(); + return mDictionaries.hasDict(Dictionary.TYPE_PERSONALIZATION); } public void flushPersonalizationDictionary() { - final PersonalizationDictionary personalizationDict = - mDictionaries.mPersonalizationDictionary; + final ExpandableBinaryDictionary personalizationDict = + mDictionaries.getSubDict(Dictionary.TYPE_PERSONALIZATION); if (personalizationDict != null) { - personalizationDict.flush(); + personalizationDict.asyncFlushBinaryDictionary(); } } @@ -377,18 +357,9 @@ public class DictionaryFacilitatorForSuggest { public void waitForLoadingDictionariesForTesting(final long timeout, final TimeUnit unit) throws InterruptedException { waitForLoadingMainDictionary(timeout, unit); - final Dictionaries dictionaries = mDictionaries; - if (dictionaries.hasContactsDict()) { - dictionaries.mContactsDictionary.waitAllTasksForTests(); - } - if (dictionaries.hasUserDict()) { - dictionaries.mUserDictionary.waitAllTasksForTests(); - } - if (dictionaries.hasUserHistoryDict()) { - dictionaries.mUserHistoryDictionary.waitAllTasksForTests(); - } - if (dictionaries.hasPersonalizationDict()) { - dictionaries.mPersonalizationDictionary.waitAllTasksForTests(); + final Map<String, ExpandableBinaryDictionary> dictMap = mDictionaries.mSubDictMap; + for (final ExpandableBinaryDictionary dict : dictMap.values()) { + dict.waitAllTasksForTests(); } } @@ -411,7 +382,9 @@ public class DictionaryFacilitatorForSuggest { public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized, final String previousWord, final int timeStampInSeconds) { final Dictionaries dictionaries = mDictionaries; - if (!dictionaries.hasUserHistoryDict()) { + final ExpandableBinaryDictionary userHistoryDictionary = + dictionaries.getSubDict(Dictionary.TYPE_USER_HISTORY); + if (userHistoryDictionary == null) { return; } final int maxFreq = getMaxFrequency(suggestion); @@ -439,8 +412,8 @@ public class DictionaryFacilitatorForSuggest { // History dictionary in order to avoid suggesting them until the dictionary // consolidation is done. // TODO: Remove this hack when ready. - final int lowerCaseFreqInMainDict = dictionaries.hasMainDict() ? - dictionaries.mMainDictionary.getFrequency(suggestionLowerCase) : + final int lowerCaseFreqInMainDict = dictionaries.hasDict(Dictionary.TYPE_MAIN) ? + dictionaries.getMainDict().getFrequency(suggestionLowerCase) : Dictionary.NOT_A_PROBABILITY; if (maxFreq < lowerCaseFreqInMainDict && lowerCaseFreqInMainDict >= CAPITALIZED_FORM_MAX_PROBABILITY_FOR_INSERT) { @@ -453,14 +426,15 @@ public class DictionaryFacilitatorForSuggest { // We demote unrecognized words (frequency < 0, below) by specifying them as "invalid". // We don't add words with 0-frequency (assuming they would be profanity etc.). final boolean isValid = maxFreq > 0; - dictionaries.mUserHistoryDictionary.addToDictionary( - previousWord, secondWord, isValid, timeStampInSeconds); + UserHistoryDictionary.addToDictionary(userHistoryDictionary, previousWord, secondWord, + isValid, timeStampInSeconds); } public void cancelAddingUserHistory(final String previousWord, final String committedWord) { - final UserHistoryDictionary userHistoryDictionary = mDictionaries.mUserHistoryDictionary; + final ExpandableBinaryDictionary userHistoryDictionary = + mDictionaries.getSubDict(Dictionary.TYPE_USER_HISTORY); if (userHistoryDictionary != null) { - userHistoryDictionary.cancelAddingUserHistory(previousWord, committedWord); + userHistoryDictionary.removeBigramDynamically(previousWord, committedWord); } } @@ -492,10 +466,10 @@ public class DictionaryFacilitatorForSuggest { public boolean isValidMainDictWord(final String word) { final Dictionaries dictionaries = mDictionaries; - if (TextUtils.isEmpty(word) || !dictionaries.hasMainDict()) { + if (TextUtils.isEmpty(word) || !dictionaries.hasDict(Dictionary.TYPE_MAIN)) { return false; } - return dictionaries.mMainDictionary.isValidWord(word); + return dictionaries.getMainDict().isValidWord(word); } public boolean isValidWord(final String word, final boolean ignoreCase) { @@ -536,53 +510,43 @@ public class DictionaryFacilitatorForSuggest { return maxFreq; } - public void clearUserHistoryDictionary() { - final UserHistoryDictionary userHistoryDict = mDictionaries.mUserHistoryDictionary; + final ExpandableBinaryDictionary userHistoryDict = + mDictionaries.getSubDict(Dictionary.TYPE_USER_HISTORY); if (userHistoryDict == null) { return; } - userHistoryDict.clearAndFlushDictionary(); + userHistoryDict.clear(); } // This method gets called only when the IME receives a notification to remove the // personalization dictionary. public void clearPersonalizationDictionary() { - final PersonalizationDictionary personalizationDict = - mDictionaries.mPersonalizationDictionary; + final ExpandableBinaryDictionary personalizationDict = + mDictionaries.getSubDict(Dictionary.TYPE_PERSONALIZATION); if (personalizationDict == null) { return; } - personalizationDict.clearAndFlushDictionary(); + personalizationDict.clear(); } public void addMultipleDictionaryEntriesToPersonalizationDictionary( final ArrayList<LanguageModelParam> languageModelParams, final ExpandableBinaryDictionary.AddMultipleDictionaryEntriesCallback callback) { - final PersonalizationDictionary personalizationDict = - mDictionaries.mPersonalizationDictionary; - if (personalizationDict == null) { + final ExpandableBinaryDictionary personalizationDict = + mDictionaries.getSubDict(Dictionary.TYPE_PERSONALIZATION); + if (personalizationDict == null || languageModelParams == null + || languageModelParams.isEmpty()) { if (callback != null) { callback.onFinished(); } return; } - personalizationDict.addMultipleDictionaryEntriesToDictionary(languageModelParams, callback); + personalizationDict.addMultipleDictionaryEntriesDynamically(languageModelParams, callback); } public void dumpDictionaryForDebug(final String dictName) { - final ExpandableBinaryDictionary dictToDump; - if (dictName.equals(Dictionary.TYPE_CONTACTS)) { - dictToDump = mDictionaries.mContactsDictionary; - } else if (dictName.equals(Dictionary.TYPE_USER)) { - dictToDump = mDictionaries.mUserDictionary; - } else if (dictName.equals(Dictionary.TYPE_USER_HISTORY)) { - dictToDump = mDictionaries.mUserHistoryDictionary; - } else if (dictName.equals(Dictionary.TYPE_PERSONALIZATION)) { - dictToDump = mDictionaries.mPersonalizationDictionary; - } else { - dictToDump = null; - } + final ExpandableBinaryDictionary dictToDump = mDictionaries.getSubDict(dictName); if (dictToDump == null) { Log.e(TAG, "Cannot dump " + dictName + ". " + "The dictionary is not being used for suggestion or cannot be dumped."); diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index a6a735414..837fe4f1a 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -27,7 +27,6 @@ import com.android.inputmethod.latin.makedict.UnsupportedFormatException; import com.android.inputmethod.latin.makedict.WordProperty; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.utils.AsyncResultHolder; -import com.android.inputmethod.latin.utils.BinaryDictionaryUtils; import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CombinedFormatUtils; import com.android.inputmethod.latin.utils.ExecutorUtils; @@ -233,24 +232,24 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { mBinaryDictionary = null; } - private void createBinaryDictionaryLocked() { - BinaryDictionaryUtils.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() { + private void createOnMemoryBinaryDictionaryLocked() { + mBinaryDictionary = new BinaryDictionary( + mDictFile.getAbsolutePath(), true /* useFullEditDistance */, mLocale, mDictType, + DICTIONARY_FORMAT_VERSION, getHeaderAttributeMap()); + } + + public void clear() { ExecutorUtils.getExecutor(mDictName).execute(new Runnable() { @Override public void run() { removeBinaryDictionaryLocked(); - createBinaryDictionaryLocked(); - openBinaryDictionaryLocked(); + createOnMemoryBinaryDictionaryLocked(); } }); } @@ -298,7 +297,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { /** * Dynamically adds a word unigram to the dictionary. May overwrite an existing entry. */ - protected void addWordDynamically(final String word, final int frequency, + public void addWordDynamically(final String word, final int frequency, final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord, final boolean isBlacklisted, final int timestamp) { reloadDictionaryIfRequired(); @@ -325,7 +324,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { /** * Dynamically adds a word bigram in the dictionary. May overwrite an existing entry. */ - protected void addBigramDynamically(final String word0, final String word1, + public void addBigramDynamically(final String word0, final String word1, final int frequency, final int timestamp) { reloadDictionaryIfRequired(); ExecutorUtils.getExecutor(mDictName).execute(new Runnable() { @@ -348,7 +347,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { /** * Dynamically remove a word bigram in the dictionary. */ - protected void removeBigramDynamically(final String word0, final String word1) { + public void removeBigramDynamically(final String word0, final String word1) { reloadDictionaryIfRequired(); ExecutorUtils.getExecutor(mDictName).execute(new Runnable() { @Override @@ -369,7 +368,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { /** * Dynamically add multiple entries to the dictionary. */ - protected void addMultipleDictionaryEntriesDynamically( + public void addMultipleDictionaryEntriesDynamically( final ArrayList<LanguageModelParam> languageModelParams, final AddMultipleDictionaryEntriesCallback callback) { reloadDictionaryIfRequired(); @@ -512,8 +511,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { + mDictNameDictionaryUpdateController.mLastUpdateTime); } removeBinaryDictionaryLocked(); - createBinaryDictionaryLocked(); - openBinaryDictionaryLocked(); + createOnMemoryBinaryDictionaryLocked(); loadInitialContentsLocked(); // Run GC and flush to file when initial contents have been loaded. mBinaryDictionary.flushWithGCIfHasUpdated(); @@ -634,7 +632,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { /** * Flush binary dictionary to dictionary file. */ - protected void asyncFlushBinaryDictionary() { + public void asyncFlushBinaryDictionary() { final Runnable newTask = new Runnable() { @Override public void run() { diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 81b02c396..a77cedc48 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -84,6 +84,7 @@ import com.android.inputmethod.latin.utils.ApplicationUtils; import com.android.inputmethod.latin.utils.CapsModeUtils; import com.android.inputmethod.latin.utils.CoordinateUtils; import com.android.inputmethod.latin.utils.DialogUtils; +import com.android.inputmethod.latin.utils.DistracterFilter; import com.android.inputmethod.latin.utils.ImportantNoticeUtils; import com.android.inputmethod.latin.utils.IntentUtils; import com.android.inputmethod.latin.utils.JniUtils; @@ -540,6 +541,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen refreshPersonalizationDictionarySession(); } + private DistracterFilter createDistracterFilter() { + final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); + // TODO: Create Keyboard when mainKeyboardView is null. + // TODO: Figure out the most reasonable keyboard for the filter. Refer to the + // spellchecker's logic. + final Keyboard keyboard = (mainKeyboardView != null) ? + mainKeyboardView.getKeyboard() : null; + final DistracterFilter distracterFilter = new DistracterFilter(mInputLogic.mSuggest, + keyboard); + return distracterFilter; + } + private void refreshPersonalizationDictionarySession() { final DictionaryFacilitatorForSuggest dictionaryFacilitator = mInputLogic.mSuggest.mDictionaryFacilitator; @@ -564,7 +577,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen PersonalizationHelper.removeAllPersonalizationDictionaries(this); PersonalizationDictionarySessionRegistrar.resetAll(this); } else { - PersonalizationDictionarySessionRegistrar.init(this, dictionaryFacilitator); + final DistracterFilter distracterFilter = createDistracterFilter(); + PersonalizationDictionarySessionRegistrar.init( + this, dictionaryFacilitator, distracterFilter); } } @@ -662,8 +677,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mInputLogic.mConnection.finishComposingText(); mInputLogic.mConnection.endBatchEdit(); } + final DistracterFilter distracterFilter = createDistracterFilter(); PersonalizationDictionarySessionRegistrar.onConfigurationChanged(this, conf, - mInputLogic.mSuggest.mDictionaryFacilitator); + mInputLogic.mSuggest.mDictionaryFacilitator, distracterFilter); super.onConfigurationChanged(conf); } diff --git a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java index 712e314a8..352288f8b 100644 --- a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java +++ b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java @@ -65,12 +65,8 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB dumpAllWordsForDebug(); } // Flush pending writes. - flush(); - super.close(); - } - - public void flush() { asyncFlushBinaryDictionary(); + super.close(); } @Override @@ -91,63 +87,16 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB return false; } - public void addMultipleDictionaryEntriesToDictionary( - final ArrayList<LanguageModelParam> languageModelParams, - final ExpandableBinaryDictionary.AddMultipleDictionaryEntriesCallback callback) { - if (languageModelParams == null || languageModelParams.isEmpty()) { - if (callback != null) { - callback.onFinished(); - } - return; - } - addMultipleDictionaryEntriesDynamically(languageModelParams, callback); - } - - /** - * Pair will be added to the decaying dictionary. - * - * The first word may be null. That means we don't know the context, in other words, - * it's only a unigram. The first word may also be an empty string : this means start - * context, as in beginning of a sentence for example. - * The second word may not be null (a NullPointerException would be thrown). - */ - public void addToDictionary(final String word0, final String word1, final boolean isValid, - final int timestamp) { - if (word1.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH || - (word0 != null && word0.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH)) { - return; - } - final int frequency = isValid ? - FREQUENCY_FOR_WORDS_IN_DICTS : FREQUENCY_FOR_WORDS_NOT_IN_DICTS; - addWordDynamically(word1, frequency, null /* shortcutTarget */, 0 /* shortcutFreq */, - false /* isNotAWord */, false /* isBlacklisted */, timestamp); - // Do not insert a word as a bigram of itself - if (word1.equals(word0)) { - return; - } - if (null != word0) { - addBigramDynamically(word0, word1, frequency, timestamp); - } - } - @Override protected void loadInitialContentsLocked() { // No initial contents. } @UsedForTesting - public void clearAndFlushDictionary() { - // Clear the node structure on memory - clear(); - // Then flush the cleared state of the dictionary on disk. - asyncFlushBinaryDictionary(); - } - - @UsedForTesting public void clearAndFlushDictionaryWithAdditionalAttributes( final Map<String, String> attributeMap) { mAdditionalAttributeMap = attributeMap; - clearAndFlushDictionary(); + clear(); } /* package */ void runGCIfRequired() { diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionarySessionRegistrar.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionarySessionRegistrar.java index d6c0dc0dc..9bef7a198 100644 --- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionarySessionRegistrar.java +++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionarySessionRegistrar.java @@ -20,14 +20,17 @@ import android.content.Context; import android.content.res.Configuration; import com.android.inputmethod.latin.DictionaryFacilitatorForSuggest; +import com.android.inputmethod.latin.utils.DistracterFilter; public class PersonalizationDictionarySessionRegistrar { public static void init(final Context context, - final DictionaryFacilitatorForSuggest dictionaryFacilitator) { + final DictionaryFacilitatorForSuggest dictionaryFacilitator, + final DistracterFilter distracterFilter) { } public static void onConfigurationChanged(final Context context, final Configuration conf, - final DictionaryFacilitatorForSuggest dictionaryFacilitator) { + final DictionaryFacilitatorForSuggest dictionaryFacilitator, + final DistracterFilter distracterFilter) { } public static void onUpdateData(final Context context, final String type) { diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java index 385b525b6..7c43182bc 100644 --- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java +++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java @@ -135,7 +135,7 @@ public class PersonalizationHelper { if (entry.getValue() != null) { final DecayingExpandableBinaryDictionaryBase dict = entry.getValue().get(); if (dict != null) { - dict.clearAndFlushDictionary(); + dict.clear(); } } } diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java index 504e9b2f3..8a29c354d 100644 --- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java +++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java @@ -18,7 +18,9 @@ package com.android.inputmethod.latin.personalization; import android.content.Context; +import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Dictionary; +import com.android.inputmethod.latin.ExpandableBinaryDictionary; import java.io.File; import java.util.Locale; @@ -40,13 +42,36 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas dictFile); } - public void cancelAddingUserHistory(final String word0, final String word1) { - removeBigramDynamically(word0, word1); - } - @Override public boolean isValidWord(final String word) { // Strings out of this dictionary should not be considered existing words. return false; } + + /** + * Pair will be added to the user history dictionary. + * + * The first word may be null. That means we don't know the context, in other words, + * it's only a unigram. The first word may also be an empty string : this means start + * context, as in beginning of a sentence for example. + * The second word may not be null (a NullPointerException would be thrown). + */ + public static void addToDictionary(final ExpandableBinaryDictionary userHistoryDictionary, + final String word0, final String word1, final boolean isValid, final int timestamp) { + if (word1.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH || + (word0 != null && word0.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH)) { + return; + } + final int frequency = isValid ? + FREQUENCY_FOR_WORDS_IN_DICTS : FREQUENCY_FOR_WORDS_NOT_IN_DICTS; + userHistoryDictionary.addWordDynamically(word1, frequency, null /* shortcutTarget */, + 0 /* shortcutFreq */, false /* isNotAWord */, false /* isBlacklisted */, timestamp); + // Do not insert a word as a bigram of itself + if (word1.equals(word0)) { + return; + } + if (null != word0) { + userHistoryDictionary.addBigramDynamically(word0, word1, frequency, timestamp); + } + } } diff --git a/java/src/com/android/inputmethod/latin/utils/BinaryDictionaryUtils.java b/java/src/com/android/inputmethod/latin/utils/BinaryDictionaryUtils.java index b4658b531..5d7deba15 100644 --- a/java/src/com/android/inputmethod/latin/utils/BinaryDictionaryUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/BinaryDictionaryUtils.java @@ -91,6 +91,7 @@ public final class BinaryDictionaryUtils { return false; } + @UsedForTesting public static boolean createEmptyDictFile(final String filePath, final long dictVersion, final Locale locale, final Map<String, String> attributeMap) { final String[] keyArray = new String[attributeMap.size()]; diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java new file mode 100644 index 000000000..f2a1e524d --- /dev/null +++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java @@ -0,0 +1,48 @@ +/* + * 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.keyboard.Keyboard; +import com.android.inputmethod.latin.Suggest; + +/** + * This class is used to prevent distracters/misspellings being added to personalization + * or user history dictionaries + */ +public class DistracterFilter { + private final Suggest mSuggest; + private final Keyboard mKeyboard; + + /** + * Create a DistracterFilter instance. + * + * @param suggest an instance of Suggest which will be used to obtain a list of suggestions + * for a potential distracter/misspelling + * @param keyboard the keyboard that is currently being used. This information is needed + * when calling mSuggest.getSuggestedWords(...) to obtain a list of suggestions. + */ + public DistracterFilter(final Suggest suggest, final Keyboard keyboard) { + mSuggest = suggest; + mKeyboard = keyboard; + } + + public boolean isDistractorToWordsInDictionaries(final String prevWord, + final String targetWord) { + // TODO: to be implemented + return false; + } +} |