diff options
45 files changed, 1670 insertions, 1546 deletions
diff --git a/java-overridable/src/com/android/inputmethod/latin/touchinputconsumer/GestureConsumer.java b/java-overridable/src/com/android/inputmethod/latin/touchinputconsumer/GestureConsumer.java index 7a5d2e68f..8291b4f72 100644 --- a/java-overridable/src/com/android/inputmethod/latin/touchinputconsumer/GestureConsumer.java +++ b/java-overridable/src/com/android/inputmethod/latin/touchinputconsumer/GestureConsumer.java @@ -19,6 +19,7 @@ package com.android.inputmethod.latin.touchinputconsumer; import android.view.inputmethod.EditorInfo; import com.android.inputmethod.keyboard.Keyboard; +import com.android.inputmethod.latin.DictionaryFacilitator; import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.common.InputPointers; import com.android.inputmethod.latin.inputlogic.PrivateCommandPerformer; @@ -62,6 +63,7 @@ public class GestureConsumer { } public void onImeSuggestionsProcessed(final SuggestedWords suggestedWords, - final int composingStart, final int composingLength) { + final int composingStart, final int composingLength, + final DictionaryFacilitator dictionaryFacilitator) { } } diff --git a/java-overridable/src/com/android/inputmethod/latin/utils/ManagedProfileUtils.java b/java-overridable/src/com/android/inputmethod/latin/utils/ManagedProfileUtils.java new file mode 100644 index 000000000..ef1872bf4 --- /dev/null +++ b/java-overridable/src/com/android/inputmethod/latin/utils/ManagedProfileUtils.java @@ -0,0 +1,43 @@ +/* + * 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 android.content.Context; + +import com.android.inputmethod.annotations.UsedForTesting; + +public class ManagedProfileUtils { + private static ManagedProfileUtils INSTANCE = new ManagedProfileUtils(); + private static ManagedProfileUtils sTestInstance; + + private ManagedProfileUtils() { + // This utility class is not publicly instantiable. + } + + @UsedForTesting + public static void setTestInstance(final ManagedProfileUtils testInstance) { + sTestInstance = testInstance; + } + + public static ManagedProfileUtils getInstance() { + return sTestInstance == null ? INSTANCE : sTestInstance; + } + + public boolean hasWorkProfile(final Context context) { + return false; + } +}
\ No newline at end of file diff --git a/java-overridable/src/com/android/inputmethod/latin/utils/StatsUtils.java b/java-overridable/src/com/android/inputmethod/latin/utils/StatsUtils.java index b8f835ee3..c069a0f64 100644 --- a/java-overridable/src/com/android/inputmethod/latin/utils/StatsUtils.java +++ b/java-overridable/src/com/android/inputmethod/latin/utils/StatsUtils.java @@ -72,7 +72,8 @@ public final class StatsUtils { } public static void onAutoCorrection(final String typedWord, final String autoCorrectionWord, - final boolean isBatchInput, final DictionaryFacilitator dictionaryType) { + final boolean isBatchInput, final DictionaryFacilitator dictionaryFacilitator, + final String prevWordsContext) { } public static void onWordCommitUserTyped(final String commitWord, final boolean isBatchMode) { diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml index 654157912..210d9a964 100644 --- a/java/AndroidManifest.xml +++ b/java/AndroidManifest.xml @@ -133,7 +133,7 @@ </intent-filter> </receiver> - <receiver android:name=".DictionaryPackInstallBroadcastReceiver" android:exported="false"> + <receiver android:name="DictionaryPackInstallBroadcastReceiver" android:exported="false"> <intent-filter> <action android:name="com.android.inputmethod.dictionarypack.aosp.UNKNOWN_CLIENT" /> </intent-filter> @@ -148,8 +148,7 @@ </receiver> <!-- Broadcast receiver for AccountManager#LOGIN_ACCOUNTS_CHANGED_ACTION. --> - <receiver - android:name=".accounts.AccountsChangedReceiver"> + <receiver android:name=".accounts.AccountsChangedReceiver"> <intent-filter> <action android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED" /> </intent-filter> diff --git a/java/res/values-en-rAU/strings-action-keys.xml b/java/res/values-en-rAU/strings-action-keys.xml new file mode 100644 index 000000000..e401cae2a --- /dev/null +++ b/java/res/values-en-rAU/strings-action-keys.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="label_go_key" msgid="4033615332628671065">"Go"</string> + <string name="label_next_key" msgid="5586407279258592635">"Next"</string> + <string name="label_previous_key" msgid="1421141755779895275">"Prev"</string> + <string name="label_done_key" msgid="7564866296502630852">"Done"</string> + <string name="label_send_key" msgid="482252074224462163">"Send"</string> + <string name="label_search_key" msgid="7965186050435796642">"Search"</string> + <string name="label_pause_key" msgid="2225922926459730642">"Pause"</string> + <string name="label_wait_key" msgid="5891247853595466039">"Wait"</string> +</resources> diff --git a/java/res/values-en-rAU/strings-appname.xml b/java/res/values-en-rAU/strings-appname.xml new file mode 100644 index 000000000..5ad5eae66 --- /dev/null +++ b/java/res/values-en-rAU/strings-appname.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 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. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="english_ime_name" msgid="5940510615957428904">"Android Keyboard (AOSP)"</string> + <string name="spell_checker_service_name" msgid="1254221805440242662">"Android Spell Checker (AOSP)"</string> + <string name="english_ime_settings" msgid="5760361067176802794">"Android Keyboard Settings (AOSP)"</string> + <string name="android_spell_checker_settings" msgid="6123949487832861885">"Android Spell Checker Settings (AOSP)"</string> +</resources> diff --git a/java/res/values-en-rAU/strings-config-important-notice.xml b/java/res/values-en-rAU/strings-config-important-notice.xml new file mode 100644 index 000000000..80ddd3e4b --- /dev/null +++ b/java/res/values-en-rAU/strings-config-important-notice.xml @@ -0,0 +1,24 @@ +<?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="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-rAU/strings-emoji-descriptions.xml b/java/res/values-en-rAU/strings-emoji-descriptions.xml new file mode 100644 index 000000000..2ac73fcbb --- /dev/null +++ b/java/res/values-en-rAU/strings-emoji-descriptions.xml @@ -0,0 +1,851 @@ +<?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. +*/ + --> + +<!-- + These Emoji symbols are unsupported by TTS. + TODO: Remove this file when TTS/TalkBack support these Emoji symbols. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="spoken_emoji_00A9" msgid="2859822817116803638">"Copyright sign"</string> + <string name="spoken_emoji_00AE" msgid="7708335454134589027">"Registered sign"</string> + <string name="spoken_emoji_203C" msgid="153340916701508663">"Double exclamation mark"</string> + <string name="spoken_emoji_2049" msgid="4877256448299555371">"Exclamation question mark"</string> + <string name="spoken_emoji_2122" msgid="9188440722954720429">"Trade mark sign"</string> + <string name="spoken_emoji_2139" msgid="9114342638917304327">"Information source"</string> + <string name="spoken_emoji_2194" msgid="8055202727034946680">"Left right arrow"</string> + <string name="spoken_emoji_2195" msgid="8028122253301087407">"Up down arrow"</string> + <string name="spoken_emoji_2196" msgid="4019164898967854363">"North west arrow"</string> + <string name="spoken_emoji_2197" msgid="4255723717709017801">"North east arrow"</string> + <string name="spoken_emoji_2198" msgid="1452063451313622090">"South east arrow"</string> + <string name="spoken_emoji_2199" msgid="6942722693368807849">"South west arrow"</string> + <string name="spoken_emoji_21A9" msgid="5204750172335111188">"Leftwards arrow with hook"</string> + <string name="spoken_emoji_21AA" msgid="3950259884359247006">"Rightwards arrow with hook"</string> + <string name="spoken_emoji_231A" msgid="6751448803233874993">"Watch"</string> + <string name="spoken_emoji_231B" msgid="5956428809948426182">"Hourglass"</string> + <string name="spoken_emoji_23E9" msgid="4022497733535162237">"Black right-pointing double triangle"</string> + <string name="spoken_emoji_23EA" msgid="2251396938087774944">"Black left-pointing double triangle"</string> + <string name="spoken_emoji_23EB" msgid="3746885195641491865">"Black up-pointing double triangle"</string> + <string name="spoken_emoji_23EC" msgid="7852372752901163416">"Black down-pointing double triangle"</string> + <string name="spoken_emoji_23F0" msgid="8474219588750627870">"Alarm clock"</string> + <string name="spoken_emoji_23F3" msgid="166900119581024371">"Hourglass with flowing sand"</string> + <string name="spoken_emoji_24C2" msgid="3948348737566038470">"Circled latin capital letter m"</string> + <string name="spoken_emoji_25AA" msgid="7865181015100227349">"Black small square"</string> + <string name="spoken_emoji_25AB" msgid="6446532820937381457">"White small square"</string> + <string name="spoken_emoji_25B6" msgid="2423897708496040947">"Black right-pointing triangle"</string> + <string name="spoken_emoji_25C0" msgid="3595083440074484934">"Black left-pointing triangle"</string> + <string name="spoken_emoji_25FB" msgid="4838691986881215419">"White medium square"</string> + <string name="spoken_emoji_25FC" msgid="7008859564991191050">"Black medium square"</string> + <string name="spoken_emoji_25FD" msgid="7673439755069217479">"White medium small square"</string> + <string name="spoken_emoji_25FE" msgid="6782214109919768923">"Black medium small square"</string> + <string name="spoken_emoji_2600" msgid="2272722634618990413">"Black sun with rays"</string> + <string name="spoken_emoji_2601" msgid="6205136889311537150">"Cloud"</string> + <string name="spoken_emoji_260E" msgid="8670395193046424238">"Black telephone"</string> + <string name="spoken_emoji_2611" msgid="4530550203347054611">"Ballot box with tick"</string> + <string name="spoken_emoji_2614" msgid="1612791247861229500">"Umbrella with rain drops"</string> + <string name="spoken_emoji_2615" msgid="3320562382424018588">"Hot beverage"</string> + <string name="spoken_emoji_261D" msgid="4690554173549768467">"White up pointing index"</string> + <string name="spoken_emoji_263A" msgid="3170094381521989300">"White smiling face"</string> + <string name="spoken_emoji_2648" msgid="4621241062667020673">"Aries"</string> + <string name="spoken_emoji_2649" msgid="7694461245947059086">"Taurus"</string> + <string name="spoken_emoji_264A" msgid="1258074605878705030">"Gemini"</string> + <string name="spoken_emoji_264B" msgid="4409219914377810956">"Cancer"</string> + <string name="spoken_emoji_264C" msgid="6520255367817054163">"Leo"</string> + <string name="spoken_emoji_264D" msgid="1504758945499854018">"Virgo"</string> + <string name="spoken_emoji_264E" msgid="2354847104530633519">"Libra"</string> + <string name="spoken_emoji_264F" msgid="5822933280406416112">"Scorpio"</string> + <string name="spoken_emoji_2650" msgid="4832481156714796163">"Sagittarius"</string> + <string name="spoken_emoji_2651" msgid="840953134601595090">"Capricorn"</string> + <string name="spoken_emoji_2652" msgid="3586925968718775281">"Aquarius"</string> + <string name="spoken_emoji_2653" msgid="8420547731496254492">"Pisces"</string> + <string name="spoken_emoji_2660" msgid="4541170554542412536">"Black spade suit"</string> + <string name="spoken_emoji_2663" msgid="3669352721942285724">"Black club suit"</string> + <string name="spoken_emoji_2665" msgid="6347941599683765843">"Black heart suit"</string> + <string name="spoken_emoji_2666" msgid="8296769213401115999">"Black diamond suit"</string> + <string name="spoken_emoji_2668" msgid="7063148281053820386">"Hot springs"</string> + <string name="spoken_emoji_267B" msgid="21716857176812762">"Black universal recycling symbol"</string> + <string name="spoken_emoji_267F" msgid="8833496533226475443">"Wheelchair symbol"</string> + <string name="spoken_emoji_2693" msgid="7443148847598433088">"Anchor"</string> + <string name="spoken_emoji_26A0" msgid="6272635532992727510">"Warning sign"</string> + <string name="spoken_emoji_26A1" msgid="5604749644693339145">"High voltage sign"</string> + <string name="spoken_emoji_26AA" msgid="8005748091690377153">"Medium white circle"</string> + <string name="spoken_emoji_26AB" msgid="1655910278422753244">"Medium black circle"</string> + <string name="spoken_emoji_26BD" msgid="1545218197938889737">"Football"</string> + <string name="spoken_emoji_26BE" msgid="8959760533076498209">"Baseball"</string> + <string name="spoken_emoji_26C4" msgid="3045791757044255626">"Snowman without snow"</string> + <string name="spoken_emoji_26C5" msgid="5580129409712578639">"Sun behind cloud"</string> + <string name="spoken_emoji_26CE" msgid="8963656417276062998">"Ophiuchus"</string> + <string name="spoken_emoji_26D4" msgid="2231451988209604130">"No entry"</string> + <string name="spoken_emoji_26EA" msgid="7513319636103804907">"Church"</string> + <string name="spoken_emoji_26F2" msgid="7134115206158891037">"Fountain"</string> + <string name="spoken_emoji_26F3" msgid="4912302210162075465">"Flag in hole"</string> + <string name="spoken_emoji_26F5" msgid="4766328116769075217">"Sailing boat"</string> + <string name="spoken_emoji_26FA" msgid="5888017494809199037">"Tent"</string> + <string name="spoken_emoji_26FD" msgid="2417060622927453534">"Fuel pump"</string> + <string name="spoken_emoji_2702" msgid="4005741160717451912">"Black scissors"</string> + <string name="spoken_emoji_2705" msgid="164605766946697759">"White heavy tick"</string> + <string name="spoken_emoji_2708" msgid="7153840886849268988">"Aeroplane"</string> + <string name="spoken_emoji_2709" msgid="2217319160724311369">"Envelope"</string> + <string name="spoken_emoji_270A" msgid="508347232762319473">"Raised fist"</string> + <string name="spoken_emoji_270B" msgid="6640562128327753423">"Raised hand"</string> + <string name="spoken_emoji_270C" msgid="1344288035704944581">"Victory hand"</string> + <string name="spoken_emoji_270F" msgid="6108251586067318718">"Pencil"</string> + <string name="spoken_emoji_2712" msgid="6320544535087710482">"Black nib"</string> + <string name="spoken_emoji_2714" msgid="1968242800064001654">"Heavy tick"</string> + <string name="spoken_emoji_2716" msgid="511941294762977228">"Heavy multiplication x"</string> + <string name="spoken_emoji_2728" msgid="5650330815808691881">"Sparkles"</string> + <string name="spoken_emoji_2733" msgid="8915809595141157327">"Eight spoked asterisk"</string> + <string name="spoken_emoji_2734" msgid="4846583547980754332">"Eight pointed black star"</string> + <string name="spoken_emoji_2744" msgid="4350636647760161042">"Snowflake"</string> + <string name="spoken_emoji_2747" msgid="3718282973916474455">"Sparkle"</string> + <string name="spoken_emoji_274C" msgid="2752145886733295314">"Cross mark"</string> + <string name="spoken_emoji_274E" msgid="4262918689871098338">"Negative squared cross mark"</string> + <string name="spoken_emoji_2753" msgid="6935897159942119808">"Black question mark ornament"</string> + <string name="spoken_emoji_2754" msgid="7277504915105532954">"White question mark ornament"</string> + <string name="spoken_emoji_2755" msgid="6853076969826960210">"White exclamation mark ornament"</string> + <string name="spoken_emoji_2757" msgid="3707907828776912174">"Heavy exclamation mark symbol"</string> + <string name="spoken_emoji_2764" msgid="4214257843609432167">"Heavy black heart"</string> + <string name="spoken_emoji_2795" msgid="6563954833786162168">"Heavy plus sign"</string> + <string name="spoken_emoji_2796" msgid="5990926508250772777">"Heavy minus sign"</string> + <string name="spoken_emoji_2797" msgid="24694184172879174">"Heavy division sign"</string> + <string name="spoken_emoji_27A1" msgid="3513434778263100580">"Black rightwards arrow"</string> + <string name="spoken_emoji_27B0" msgid="203395646864662198">"Curly loop"</string> + <string name="spoken_emoji_27BF" msgid="4940514642375640510">"Double curly loop"</string> + <string name="spoken_emoji_2934" msgid="9062130477982973457">"Arrow pointing rightwards then curving upwards"</string> + <string name="spoken_emoji_2935" msgid="6198710960720232074">"Arrow pointing rightwards then curving downwards"</string> + <string name="spoken_emoji_2B05" msgid="4813405635410707690">"Leftwards black arrow"</string> + <string name="spoken_emoji_2B06" msgid="1223172079106250748">"Upwards black arrow"</string> + <string name="spoken_emoji_2B07" msgid="1599124424746596150">"Downwards black arrow"</string> + <string name="spoken_emoji_2B1B" msgid="3461247311988501626">"Black large square"</string> + <string name="spoken_emoji_2B1C" msgid="5793146430145248915">"White large square"</string> + <string name="spoken_emoji_2B50" msgid="3850845519526950524">"White medium star"</string> + <string name="spoken_emoji_2B55" msgid="9137882158811541824">"Heavy large circle"</string> + <string name="spoken_emoji_3030" msgid="4609172241893565639">"Wavy dash"</string> + <string name="spoken_emoji_303D" msgid="2545833934975907505">"Part alternation mark"</string> + <string name="spoken_emoji_3297" msgid="928912923628973800">"Circled ideograph congratulation"</string> + <string name="spoken_emoji_3299" msgid="3930347573693668426">"Circled ideograph secret"</string> + <string name="spoken_emoji_1F004" msgid="1705216181345894600">"Mahjong tile red dragon"</string> + <string name="spoken_emoji_1F0CF" msgid="7601493592085987866">"Playing card black joker"</string> + <string name="spoken_emoji_1F170" msgid="3817698686602826773">"Blood type A"</string> + <string name="spoken_emoji_1F171" msgid="3684218589626650242">"Blood type B"</string> + <string name="spoken_emoji_1F17E" msgid="2978809190364779029">"Blood type O"</string> + <string name="spoken_emoji_1F17F" msgid="463634348668462040">"Car park"</string> + <string name="spoken_emoji_1F18E" msgid="1650705325221496768">"Blood type AB"</string> + <string name="spoken_emoji_1F191" msgid="5386969264431429221">"Squared CL"</string> + <string name="spoken_emoji_1F192" msgid="8324226436829162496">"Squared cool"</string> + <string name="spoken_emoji_1F193" msgid="4731758603321515364">"Squared free"</string> + <string name="spoken_emoji_1F194" msgid="4903128609556175887">"Squared ID"</string> + <string name="spoken_emoji_1F195" msgid="1433142500411060924">"Squared new"</string> + <string name="spoken_emoji_1F196" msgid="8825160701159634202">"Squared N G"</string> + <string name="spoken_emoji_1F197" msgid="7841079241554176535">"Squared OK"</string> + <string name="spoken_emoji_1F198" msgid="7020298909426960622">"Squared SOS"</string> + <string name="spoken_emoji_1F199" msgid="5971252667136235630">"Squared up with exclamation mark"</string> + <string name="spoken_emoji_1F19A" msgid="4557270135899843959">"Squared vs"</string> + <string name="spoken_emoji_1F201" msgid="7000490044681139002">"Squared katakana here"</string> + <string name="spoken_emoji_1F202" msgid="8560906958695043947">"Squared katakana service"</string> + <string name="spoken_emoji_1F21A" msgid="1496435317324514033">"Squared ideograph charge-free"</string> + <string name="spoken_emoji_1F22F" msgid="609797148862445402">"Squared ideograph reserved-seat"</string> + <string name="spoken_emoji_1F232" msgid="8125716331632035820">"Squared ideograph prohibitation"</string> + <string name="spoken_emoji_1F233" msgid="8749401090457355028">"Squared ideograph vacancy"</string> + <string name="spoken_emoji_1F234" msgid="3546951604285970768">"Squared ideograph acceptance"</string> + <string name="spoken_emoji_1F235" msgid="5320186982841793711">"Squared ideograph full occupancy"</string> + <string name="spoken_emoji_1F236" msgid="879755752069393034">"Squared ideograph paid"</string> + <string name="spoken_emoji_1F237" msgid="6741807001205851437">"Squared ideograph monthly"</string> + <string name="spoken_emoji_1F238" msgid="5504414186438196912">"Squared ideograph application"</string> + <string name="spoken_emoji_1F239" msgid="1634067311597618959">"Squared ideograph discount"</string> + <string name="spoken_emoji_1F23A" msgid="3107862957630169536">"Squared ideograph in business"</string> + <string name="spoken_emoji_1F250" msgid="6586943922806727907">"Circled ideograph advantage"</string> + <string name="spoken_emoji_1F251" msgid="9099032855993346948">"Circled ideograph accept"</string> + <string name="spoken_emoji_1F300" msgid="4720098285295840383">"Cyclone"</string> + <string name="spoken_emoji_1F301" msgid="3601962477653752974">"Foggy"</string> + <string name="spoken_emoji_1F302" msgid="3404357123421753593">"Closed umbrella"</string> + <string name="spoken_emoji_1F303" msgid="3899301321538188206">"Night with stars"</string> + <string name="spoken_emoji_1F304" msgid="2767148930689050040">"Sunrise over mountains"</string> + <string name="spoken_emoji_1F305" msgid="9165812924292061196">"Sunrise"</string> + <string name="spoken_emoji_1F306" msgid="5889294736109193104">"Cityscape at dusk"</string> + <string name="spoken_emoji_1F307" msgid="2714290867291163713">"Sunset over buildings"</string> + <string name="spoken_emoji_1F308" msgid="688704703985173377">"Rainbow"</string> + <string name="spoken_emoji_1F309" msgid="6217981957992313528">"Bridge at night"</string> + <string name="spoken_emoji_1F30A" msgid="4329309263152110893">"Water wave"</string> + <string name="spoken_emoji_1F30B" msgid="5729430693700923112">"Volcano"</string> + <string name="spoken_emoji_1F30C" msgid="2961230863217543082">"Milky way"</string> + <string name="spoken_emoji_1F30D" msgid="1113905673331547953">"Earth globe Europe-Africa"</string> + <string name="spoken_emoji_1F30E" msgid="5278512600749223671">"Earth globe Americas"</string> + <string name="spoken_emoji_1F30F" msgid="5718144880978707493">"Earth globe Asia-Australia"</string> + <string name="spoken_emoji_1F310" msgid="2959618582975247601">"Globe with meridians"</string> + <string name="spoken_emoji_1F311" msgid="623906380914895542">"New moon symbol"</string> + <string name="spoken_emoji_1F312" msgid="4458575672576125401">"Waxing crescent moon symbol"</string> + <string name="spoken_emoji_1F313" msgid="7599181787989497294">"First quarter moon symbol"</string> + <string name="spoken_emoji_1F314" msgid="4898293184964365413">"Waxing gibbous moon symbol"</string> + <string name="spoken_emoji_1F315" msgid="3218117051779496309">"Full moon symbol"</string> + <string name="spoken_emoji_1F316" msgid="2061317145777689569">"Waning gibbous moon symbol"</string> + <string name="spoken_emoji_1F317" msgid="2721090687319539049">"Last quarter moon symbol"</string> + <string name="spoken_emoji_1F318" msgid="3814091755648887570">"Waning crescent moon symbol"</string> + <string name="spoken_emoji_1F319" msgid="4074299824890459465">"Crescent moon"</string> + <string name="spoken_emoji_1F31A" msgid="3092285278116977103">"New moon with face"</string> + <string name="spoken_emoji_1F31B" msgid="2658562138386927881">"First quarter moon with face"</string> + <string name="spoken_emoji_1F31C" msgid="7914768515547867384">"Last quarter moon with face"</string> + <string name="spoken_emoji_1F31D" msgid="1925730459848297182">"Full moon with face"</string> + <string name="spoken_emoji_1F31E" msgid="8022112382524084418">"Sun with face"</string> + <string name="spoken_emoji_1F31F" msgid="1051661214137766369">"Glowing star"</string> + <string name="spoken_emoji_1F320" msgid="5450591979068216115">"Shooting star"</string> + <string name="spoken_emoji_1F330" msgid="3115760035618051575">"Chestnut"</string> + <string name="spoken_emoji_1F331" msgid="5658888205290008691">"Seedling"</string> + <string name="spoken_emoji_1F332" msgid="2935650450421165938">"Evergreen tree"</string> + <string name="spoken_emoji_1F333" msgid="5898847427062482675">"Deciduous tree"</string> + <string name="spoken_emoji_1F334" msgid="6183375224678417894">"Palm tree"</string> + <string name="spoken_emoji_1F335" msgid="5352418412103584941">"Cactus"</string> + <string name="spoken_emoji_1F337" msgid="3839107352363566289">"Tulip"</string> + <string name="spoken_emoji_1F338" msgid="6389970364260468490">"Cherry blossom"</string> + <string name="spoken_emoji_1F339" msgid="9128891447985256151">"Rose"</string> + <string name="spoken_emoji_1F33A" msgid="2025828400095233078">"Hibiscus"</string> + <string name="spoken_emoji_1F33B" msgid="8163868254348448552">"Sunflower"</string> + <string name="spoken_emoji_1F33C" msgid="6850371206262335812">"Blossom"</string> + <string name="spoken_emoji_1F33D" msgid="9033484052864509610">"Ear of maize"</string> + <string name="spoken_emoji_1F33E" msgid="2540173396638444120">"Ear of rice"</string> + <string name="spoken_emoji_1F33F" msgid="4384823344364908558">"Herb"</string> + <string name="spoken_emoji_1F340" msgid="3494255459156499305">"Four leaf clover"</string> + <string name="spoken_emoji_1F341" msgid="4581959481754990158">"Maple leaf"</string> + <string name="spoken_emoji_1F342" msgid="3119068426871821222">"Fallen leaf"</string> + <string name="spoken_emoji_1F343" msgid="2663317495805149004">"Leaf fluttering in wind"</string> + <string name="spoken_emoji_1F344" msgid="2738517881678722159">"Mushroom"</string> + <string name="spoken_emoji_1F345" msgid="6135288642349085554">"Tomato"</string> + <string name="spoken_emoji_1F346" msgid="2075395322785406367">"Aubergine"</string> + <string name="spoken_emoji_1F347" msgid="7753453754963890571">"Grapes"</string> + <string name="spoken_emoji_1F348" msgid="1247076837284932788">"Melon"</string> + <string name="spoken_emoji_1F349" msgid="5563054555180611086">"Watermelon"</string> + <string name="spoken_emoji_1F34A" msgid="4688661208570160524">"Tangerine"</string> + <string name="spoken_emoji_1F34B" msgid="4335318423164185706">"Lemon"</string> + <string name="spoken_emoji_1F34C" msgid="3712827239858159474">"Banana"</string> + <string name="spoken_emoji_1F34D" msgid="7712521967162622936">"Pineapple"</string> + <string name="spoken_emoji_1F34E" msgid="1859466882598614228">"Red apple"</string> + <string name="spoken_emoji_1F34F" msgid="8251711032295005633">"Green apple"</string> + <string name="spoken_emoji_1F350" msgid="625802980159197701">"Pear"</string> + <string name="spoken_emoji_1F351" msgid="4269460120610911895">"Peach"</string> + <string name="spoken_emoji_1F352" msgid="965600953360182635">"Cherries"</string> + <string name="spoken_emoji_1F353" msgid="7068623879906925592">"Strawberry"</string> + <string name="spoken_emoji_1F354" msgid="45162285238888494">"Hamburger"</string> + <string name="spoken_emoji_1F355" msgid="9157587635526433283">"Slice of pizza"</string> + <string name="spoken_emoji_1F356" msgid="2667196119149852244">"Meat on bone"</string> + <string name="spoken_emoji_1F357" msgid="8022817413851052256">"Poultry leg"</string> + <string name="spoken_emoji_1F358" msgid="3042693264748036476">"Rice cracker"</string> + <string name="spoken_emoji_1F359" msgid="3988148661730121958">"Rice ball"</string> + <string name="spoken_emoji_1F35A" msgid="1763824172198327268">"Cooked rice"</string> + <string name="spoken_emoji_1F35B" msgid="62530406745717835">"Curry and rice"</string> + <string name="spoken_emoji_1F35C" msgid="7537756539198945509">"Steaming bowl"</string> + <string name="spoken_emoji_1F35D" msgid="8173523083861875196">"Spaghetti"</string> + <string name="spoken_emoji_1F35E" msgid="2935428307894662571">"Bread"</string> + <string name="spoken_emoji_1F35F" msgid="4840297386785728443">"French fries"</string> + <string name="spoken_emoji_1F360" msgid="4094659855684686801">"Roasted sweet potato"</string> + <string name="spoken_emoji_1F361" msgid="6475486395784096109">"Dango"</string> + <string name="spoken_emoji_1F362" msgid="5004692577661076275">"Oden"</string> + <string name="spoken_emoji_1F363" msgid="1606603765717743806">"Sushi"</string> + <string name="spoken_emoji_1F364" msgid="6550457766169570811">"Fried shrimp"</string> + <string name="spoken_emoji_1F365" msgid="4963815540953316307">"Fish cake with swirl design"</string> + <string name="spoken_emoji_1F366" msgid="7862401745277049404">"Soft ice cream"</string> + <string name="spoken_emoji_1F367" msgid="7447972978281980414">"Shaved ice"</string> + <string name="spoken_emoji_1F368" msgid="7790003146142724913">"Ice cream"</string> + <string name="spoken_emoji_1F369" msgid="7383712944084857350">"Doughnut"</string> + <string name="spoken_emoji_1F36A" msgid="2726271795913042295">"Cookie"</string> + <string name="spoken_emoji_1F36B" msgid="6342163604299875931">"Chocolate bar"</string> + <string name="spoken_emoji_1F36C" msgid="2168934753998218790">"Candy"</string> + <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lollipop"</string> + <string name="spoken_emoji_1F36E" msgid="4630541402785165902">"Custard"</string> + <string name="spoken_emoji_1F36F" msgid="5577915387425169439">"Honey pot"</string> + <string name="spoken_emoji_1F370" msgid="7243244547866114951">"Shortcake"</string> + <string name="spoken_emoji_1F371" msgid="6731527040552916358">"Bento box"</string> + <string name="spoken_emoji_1F372" msgid="1635035323832181733">"Pot of food"</string> + <string name="spoken_emoji_1F373" msgid="7799289534289221045">"Cooking"</string> + <string name="spoken_emoji_1F374" msgid="5973820884987069131">"Fork and knife"</string> + <string name="spoken_emoji_1F375" msgid="1074832087699617700">"Teacup without handle"</string> + <string name="spoken_emoji_1F376" msgid="6499274685584852067">"Sake bottle and cup"</string> + <string name="spoken_emoji_1F377" msgid="1762398562314172075">"Wine glass"</string> + <string name="spoken_emoji_1F378" msgid="5528234560590117516">"Cocktail glass"</string> + <string name="spoken_emoji_1F379" msgid="790581290787943325">"Tropical drink"</string> + <string name="spoken_emoji_1F37A" msgid="391966822450619516">"Beer mug"</string> + <string name="spoken_emoji_1F37B" msgid="9015043286465670662">"Clinking beer mugs"</string> + <string name="spoken_emoji_1F37C" msgid="2532113819464508894">"Baby bottle"</string> + <string name="spoken_emoji_1F380" msgid="3487363857092458827">"Ribbon"</string> + <string name="spoken_emoji_1F381" msgid="614180683680675444">"Wrapped present"</string> + <string name="spoken_emoji_1F382" msgid="4720497171946687501">"Birthday cake"</string> + <string name="spoken_emoji_1F383" msgid="3536505941578757623">"Jack-o-lantern"</string> + <string name="spoken_emoji_1F384" msgid="1797870204479059004">"Christmas tree"</string> + <string name="spoken_emoji_1F385" msgid="1754174063483626367">"Father christmas"</string> + <string name="spoken_emoji_1F386" msgid="2130445450758114746">"Fireworks"</string> + <string name="spoken_emoji_1F387" msgid="3403182563117999933">"Firework sparkler"</string> + <string name="spoken_emoji_1F388" msgid="2903047203723251804">"Balloon"</string> + <string name="spoken_emoji_1F389" msgid="2352830665883549388">"Party popper"</string> + <string name="spoken_emoji_1F38A" msgid="6280428984773641322">"Confetti ball"</string> + <string name="spoken_emoji_1F38B" msgid="4902225837479015489">"Tanabata tree"</string> + <string name="spoken_emoji_1F38C" msgid="7623268024030989365">"Crossed flags"</string> + <string name="spoken_emoji_1F38D" msgid="8237542796124408528">"Pine decoration"</string> + <string name="spoken_emoji_1F38E" msgid="5373397476238212371">"Japanese dolls"</string> + <string name="spoken_emoji_1F38F" msgid="8754091376829552844">"Carp streamer"</string> + <string name="spoken_emoji_1F390" msgid="8903307048095431374">"Wind chime"</string> + <string name="spoken_emoji_1F391" msgid="2134952069191911841">"Moon viewing ceremony"</string> + <string name="spoken_emoji_1F392" msgid="6380405493914304737">"School satchel"</string> + <string name="spoken_emoji_1F393" msgid="6947890064872470996">"Graduation cap"</string> + <string name="spoken_emoji_1F3A0" msgid="3572095190082826057">"Carousel horse"</string> + <string name="spoken_emoji_1F3A1" msgid="4300565511681058798">"Ferris wheel"</string> + <string name="spoken_emoji_1F3A2" msgid="15486093912232140">"Roller coaster"</string> + <string name="spoken_emoji_1F3A3" msgid="921739319504942924">"Fishing pole and fish"</string> + <string name="spoken_emoji_1F3A4" msgid="7497596355346856950">"Microphone"</string> + <string name="spoken_emoji_1F3A5" msgid="4290497821228183002">"Movie camera"</string> + <string name="spoken_emoji_1F3A6" msgid="26019057872319055">"Cinema"</string> + <string name="spoken_emoji_1F3A7" msgid="837856608794094105">"Headphone"</string> + <string name="spoken_emoji_1F3A8" msgid="2332260356509244587">"Artist palette"</string> + <string name="spoken_emoji_1F3A9" msgid="9045869366525115256">"Top hat"</string> + <string name="spoken_emoji_1F3AA" msgid="5728760354237132">"Circus tent"</string> + <string name="spoken_emoji_1F3AB" msgid="1657997517193216284">"Ticket"</string> + <string name="spoken_emoji_1F3AC" msgid="4317366554314492152">"Clapper board"</string> + <string name="spoken_emoji_1F3AD" msgid="607157286336130470">"Performing arts"</string> + <string name="spoken_emoji_1F3AE" msgid="2902308174671548150">"Video game"</string> + <string name="spoken_emoji_1F3AF" msgid="5420539221790296407">"Direct hit"</string> + <string name="spoken_emoji_1F3B0" msgid="7440244806527891956">"Slot machine"</string> + <string name="spoken_emoji_1F3B1" msgid="545544382391379234">"Billiards"</string> + <string name="spoken_emoji_1F3B2" msgid="8302262034774787493">"Game die"</string> + <string name="spoken_emoji_1F3B3" msgid="5180870610771027520">"Bowling"</string> + <string name="spoken_emoji_1F3B4" msgid="4723852033266071564">"Flower playing cards"</string> + <string name="spoken_emoji_1F3B5" msgid="1998470239850548554">"Musical note"</string> + <string name="spoken_emoji_1F3B6" msgid="3827730457113941705">"Multiple musical notes"</string> + <string name="spoken_emoji_1F3B7" msgid="5503403099445042180">"Saxophone"</string> + <string name="spoken_emoji_1F3B8" msgid="3985658156795011430">"Guitar"</string> + <string name="spoken_emoji_1F3B9" msgid="5596295757967881451">"Musical keyboard"</string> + <string name="spoken_emoji_1F3BA" msgid="4284064120340683558">"Trumpet"</string> + <string name="spoken_emoji_1F3BB" msgid="2856598510069988745">"Violin"</string> + <string name="spoken_emoji_1F3BC" msgid="1608424748821446230">"Musical score"</string> + <string name="spoken_emoji_1F3BD" msgid="5490786111375627777">"Running shirt with sash"</string> + <string name="spoken_emoji_1F3BE" msgid="1851613105691627931">"Tennis racquet and ball"</string> + <string name="spoken_emoji_1F3BF" msgid="6862405997423247921">"Ski and ski boot"</string> + <string name="spoken_emoji_1F3C0" msgid="7421420756115104085">"Basketball and hoop"</string> + <string name="spoken_emoji_1F3C1" msgid="6926537251677319922">"Chequered flag"</string> + <string name="spoken_emoji_1F3C2" msgid="5708596929237987082">"Snowboarder"</string> + <string name="spoken_emoji_1F3C3" msgid="5850982999510115824">"Runner"</string> + <string name="spoken_emoji_1F3C4" msgid="8468355585994639838">"Surfer"</string> + <string name="spoken_emoji_1F3C6" msgid="9094474706847545409">"Trophy"</string> + <string name="spoken_emoji_1F3C7" msgid="8172206200368370116">"Horse racing"</string> + <string name="spoken_emoji_1F3C8" msgid="5619171461277597709">"American football"</string> + <string name="spoken_emoji_1F3C9" msgid="6371294008765871043">"Rugby football"</string> + <string name="spoken_emoji_1F3CA" msgid="130977831787806932">"Swimmer"</string> + <string name="spoken_emoji_1F3E0" msgid="6277213201655811842">"House building"</string> + <string name="spoken_emoji_1F3E1" msgid="233476176077538885">"House with garden"</string> + <string name="spoken_emoji_1F3E2" msgid="919736380093964570">"Office building"</string> + <string name="spoken_emoji_1F3E3" msgid="6177606081825094184">"Japanese post office"</string> + <string name="spoken_emoji_1F3E4" msgid="717377871070970293">"European post office"</string> + <string name="spoken_emoji_1F3E5" msgid="1350532500431776780">"Hospital"</string> + <string name="spoken_emoji_1F3E6" msgid="342132788513806214">"Bank"</string> + <string name="spoken_emoji_1F3E7" msgid="6322352038284944265">"Automated teller machine"</string> + <string name="spoken_emoji_1F3E8" msgid="5864918444350599907">"Hotel"</string> + <string name="spoken_emoji_1F3E9" msgid="7830416185375326938">"Love hotel"</string> + <string name="spoken_emoji_1F3EA" msgid="5081084413084360479">"Convenience store"</string> + <string name="spoken_emoji_1F3EB" msgid="7010966528205150525">"School"</string> + <string name="spoken_emoji_1F3EC" msgid="4845978861878295154">"Department store"</string> + <string name="spoken_emoji_1F3ED" msgid="3980316226665215370">"Factory"</string> + <string name="spoken_emoji_1F3EE" msgid="1253964276770550248">"Izakaya lantern"</string> + <string name="spoken_emoji_1F3EF" msgid="1128975573507389883">"Japanese castle"</string> + <string name="spoken_emoji_1F3F0" msgid="1544632297502291578">"European castle"</string> + <string name="spoken_emoji_1F400" msgid="2063034795679578294">"Rat"</string> + <string name="spoken_emoji_1F401" msgid="6736421616217369594">"Mouse"</string> + <string name="spoken_emoji_1F402" msgid="7276670995895485604">"Ox"</string> + <string name="spoken_emoji_1F403" msgid="8045709541897118928">"Water buffalo"</string> + <string name="spoken_emoji_1F404" msgid="5240777285676662335">"Cow"</string> + <string name="spoken_emoji_1F406" msgid="5163461930159540018">"Leopard"</string> + <string name="spoken_emoji_1F407" msgid="6905370221172708160">"Rabbit"</string> + <string name="spoken_emoji_1F408" msgid="1362164550508207284">"Cat"</string> + <string name="spoken_emoji_1F409" msgid="8476130983168866013">"Dragon"</string> + <string name="spoken_emoji_1F40A" msgid="1149626786411545043">"Crocodile"</string> + <string name="spoken_emoji_1F40B" msgid="5199104921208397643">"Whale"</string> + <string name="spoken_emoji_1F40C" msgid="2704006052881702675">"Snail"</string> + <string name="spoken_emoji_1F40D" msgid="8648186663643157522">"Snake"</string> + <string name="spoken_emoji_1F40E" msgid="7219137467573327268">"Horse"</string> + <string name="spoken_emoji_1F40F" msgid="7834336676729040395">"Ram"</string> + <string name="spoken_emoji_1F410" msgid="8686765722255775031">"Goat"</string> + <string name="spoken_emoji_1F411" msgid="3585715397876383525">"Sheep"</string> + <string name="spoken_emoji_1F412" msgid="4924794582980077838">"Monkey"</string> + <string name="spoken_emoji_1F413" msgid="1460475310405677377">"Rooster"</string> + <string name="spoken_emoji_1F414" msgid="5857296282631892219">"Chicken"</string> + <string name="spoken_emoji_1F415" msgid="5920041074892949527">"Dog"</string> + <string name="spoken_emoji_1F416" msgid="4362403392912540286">"Pig"</string> + <string name="spoken_emoji_1F417" msgid="6836978415840795128">"Boar"</string> + <string name="spoken_emoji_1F418" msgid="7926161463897783691">"Elephant"</string> + <string name="spoken_emoji_1F419" msgid="1055233959755784186">"Octopus"</string> + <string name="spoken_emoji_1F41A" msgid="5195666556511558060">"Spiral shell"</string> + <string name="spoken_emoji_1F41B" msgid="7652480167465557832">"Bug"</string> + <string name="spoken_emoji_1F41C" msgid="1123461148697574239">"Ant"</string> + <string name="spoken_emoji_1F41D" msgid="718579308764058851">"Honeybee"</string> + <string name="spoken_emoji_1F41E" msgid="6766305509608115467">"Lady beetle"</string> + <string name="spoken_emoji_1F41F" msgid="1207261298343160838">"Fish"</string> + <string name="spoken_emoji_1F420" msgid="1041145003133609221">"Tropical fish"</string> + <string name="spoken_emoji_1F421" msgid="1748378324417438751">"Blowfish"</string> + <string name="spoken_emoji_1F422" msgid="4106724877523329148">"Turtle"</string> + <string name="spoken_emoji_1F423" msgid="4077407945958691907">"Hatching chick"</string> + <string name="spoken_emoji_1F424" msgid="6911326019270172283">"Baby chick"</string> + <string name="spoken_emoji_1F425" msgid="5466514196557885577">"Front-facing baby chick"</string> + <string name="spoken_emoji_1F426" msgid="2163979138772892755">"Bird"</string> + <string name="spoken_emoji_1F427" msgid="3585670324511212961">"Penguin"</string> + <string name="spoken_emoji_1F428" msgid="7955440808647898579">"Koala"</string> + <string name="spoken_emoji_1F429" msgid="5028269352809819035">"Poodle"</string> + <string name="spoken_emoji_1F42A" msgid="4681926706404032484">"Dromedary camel"</string> + <string name="spoken_emoji_1F42B" msgid="2725166074981558322">"Bactrian camel"</string> + <string name="spoken_emoji_1F42C" msgid="6764791873413727085">"Dolphin"</string> + <string name="spoken_emoji_1F42D" msgid="1033643138546864251">"Mouse face"</string> + <string name="spoken_emoji_1F42E" msgid="8099223337120508820">"Cow face"</string> + <string name="spoken_emoji_1F42F" msgid="2104743989330781572">"Tiger face"</string> + <string name="spoken_emoji_1F430" msgid="525492897063150160">"Rabbit face"</string> + <string name="spoken_emoji_1F431" msgid="6051358666235016851">"Cat face"</string> + <string name="spoken_emoji_1F432" msgid="7698001871193018305">"Dragon face"</string> + <string name="spoken_emoji_1F433" msgid="3762356053512899326">"Spouting whale"</string> + <string name="spoken_emoji_1F434" msgid="3619943222159943226">"Horse face"</string> + <string name="spoken_emoji_1F435" msgid="59199202683252958">"Monkey face"</string> + <string name="spoken_emoji_1F436" msgid="340544719369009828">"Dog face"</string> + <string name="spoken_emoji_1F437" msgid="1219818379784982585">"Pig face"</string> + <string name="spoken_emoji_1F438" msgid="9128124743321008210">"Frog face"</string> + <string name="spoken_emoji_1F439" msgid="1424161319554642266">"Hamster face"</string> + <string name="spoken_emoji_1F43A" msgid="6727645488430385584">"Wolf face"</string> + <string name="spoken_emoji_1F43B" msgid="5397170068392865167">"Bear face"</string> + <string name="spoken_emoji_1F43C" msgid="2715995734367032431">"Panda face"</string> + <string name="spoken_emoji_1F43D" msgid="6005480717951776597">"Pig nose"</string> + <string name="spoken_emoji_1F43E" msgid="8917626103219080547">"Paw prints"</string> + <string name="spoken_emoji_1F440" msgid="7144338258163384433">"Eyes"</string> + <string name="spoken_emoji_1F442" msgid="1905515392292676124">"Ear"</string> + <string name="spoken_emoji_1F443" msgid="1491504447758933115">"Nose"</string> + <string name="spoken_emoji_1F444" msgid="3654613047946080332">"Mouth"</string> + <string name="spoken_emoji_1F445" msgid="7024905244040509204">"Tongue"</string> + <string name="spoken_emoji_1F446" msgid="2150365643636471745">"White up pointing backhand index"</string> + <string name="spoken_emoji_1F447" msgid="8794022344940891388">"White down pointing backhand index"</string> + <string name="spoken_emoji_1F448" msgid="3261812959215550650">"White left pointing backhand index"</string> + <string name="spoken_emoji_1F449" msgid="4764447975177805991">"White right pointing backhand index"</string> + <string name="spoken_emoji_1F44A" msgid="7197417095486424841">"Fisted hand sign"</string> + <string name="spoken_emoji_1F44B" msgid="1975968945250833117">"Waving hand sign"</string> + <string name="spoken_emoji_1F44C" msgid="3185919567897876562">"OK hand sign"</string> + <string name="spoken_emoji_1F44D" msgid="6182553970602667815">"Thumbs up sign"</string> + <string name="spoken_emoji_1F44E" msgid="8030851867365111809">"Thumbs down sign"</string> + <string name="spoken_emoji_1F44F" msgid="5148753662268213389">"Clapping hands sign"</string> + <string name="spoken_emoji_1F450" msgid="1012021072085157054">"Open hands sign"</string> + <string name="spoken_emoji_1F451" msgid="8257466714629051320">"Crown"</string> + <string name="spoken_emoji_1F452" msgid="4567394011149905466">"Womans hat"</string> + <string name="spoken_emoji_1F453" msgid="5978410551173163010">"Eyeglasses"</string> + <string name="spoken_emoji_1F454" msgid="348469036193323252">"Necktie"</string> + <string name="spoken_emoji_1F455" msgid="5665118831861433578">"T-shirt"</string> + <string name="spoken_emoji_1F456" msgid="1890991330923356408">"Jeans"</string> + <string name="spoken_emoji_1F457" msgid="3904310482655702620">"Dress"</string> + <string name="spoken_emoji_1F458" msgid="5704243858031107692">"Kimono"</string> + <string name="spoken_emoji_1F459" msgid="3553148747050035251">"Bikini"</string> + <string name="spoken_emoji_1F45A" msgid="1389654639484716101">"Womans clothes"</string> + <string name="spoken_emoji_1F45B" msgid="1113293170254222904">"Purse"</string> + <string name="spoken_emoji_1F45C" msgid="3410257778598006936">"Handbag"</string> + <string name="spoken_emoji_1F45D" msgid="812176504300064819">"Pouch"</string> + <string name="spoken_emoji_1F45E" msgid="2901741399934723562">"Mans shoe"</string> + <string name="spoken_emoji_1F45F" msgid="6828566359287798863">"Athletic shoe"</string> + <string name="spoken_emoji_1F460" msgid="305863879170420855">"High-heeled shoe"</string> + <string name="spoken_emoji_1F461" msgid="5160493217831417630">"Womans sandal"</string> + <string name="spoken_emoji_1F462" msgid="1722897795554863734">"Womans boots"</string> + <string name="spoken_emoji_1F463" msgid="5850772903593010699">"Footprints"</string> + <string name="spoken_emoji_1F464" msgid="1228335905487734913">"Bust in silhouette"</string> + <string name="spoken_emoji_1F465" msgid="4461307702499679879">"Busts in silhouette"</string> + <string name="spoken_emoji_1F466" msgid="1938873085514108889">"Boy"</string> + <string name="spoken_emoji_1F467" msgid="8237080594860144998">"Girl"</string> + <string name="spoken_emoji_1F468" msgid="6081300722526675382">"Man"</string> + <string name="spoken_emoji_1F469" msgid="1090140923076108158">"Woman"</string> + <string name="spoken_emoji_1F46A" msgid="5063570981942606595">"Family"</string> + <string name="spoken_emoji_1F46B" msgid="6795882374287327952">"Man and woman holding hands"</string> + <string name="spoken_emoji_1F46C" msgid="6844464165783964495">"Two men holding hands"</string> + <string name="spoken_emoji_1F46D" msgid="2316773068014053180">"Two women holding hands"</string> + <string name="spoken_emoji_1F46E" msgid="5897625605860822401">"Police officer"</string> + <string name="spoken_emoji_1F46F" msgid="7716871657717641490">"Woman with bunny ears"</string> + <string name="spoken_emoji_1F470" msgid="6409995400510338892">"Bride with veil"</string> + <string name="spoken_emoji_1F471" msgid="3058247860441670806">"Person with blond hair"</string> + <string name="spoken_emoji_1F472" msgid="3928854667819339142">"Man with gua pi mao"</string> + <string name="spoken_emoji_1F473" msgid="5921952095808988381">"Man with turban"</string> + <string name="spoken_emoji_1F474" msgid="1082237499496725183">"Older man"</string> + <string name="spoken_emoji_1F475" msgid="7280323988642212761">"Older woman"</string> + <string name="spoken_emoji_1F476" msgid="4713322657821088296">"Baby"</string> + <string name="spoken_emoji_1F477" msgid="2197036131029221370">"Construction worker"</string> + <string name="spoken_emoji_1F478" msgid="7245521193493488875">"Princess"</string> + <string name="spoken_emoji_1F479" msgid="6876475321015553972">"Japanese ogre"</string> + <string name="spoken_emoji_1F47A" msgid="3900813633102703571">"Japanese goblin"</string> + <string name="spoken_emoji_1F47B" msgid="2608250873194079390">"Ghost"</string> + <string name="spoken_emoji_1F47C" msgid="3838699131276537421">"Baby angel"</string> + <string name="spoken_emoji_1F47D" msgid="2874077455888369538">"Extraterrestrial alien"</string> + <string name="spoken_emoji_1F47E" msgid="3642607168625579507">"Alien monster"</string> + <string name="spoken_emoji_1F47F" msgid="441605977269926252">"Imp"</string> + <string name="spoken_emoji_1F480" msgid="3696253485164878739">"Skull"</string> + <string name="spoken_emoji_1F481" msgid="320408708521966893">"Information desk person"</string> + <string name="spoken_emoji_1F482" msgid="3424354860245608949">"Guardsman"</string> + <string name="spoken_emoji_1F483" msgid="3221113594843849083">"Dancer"</string> + <string name="spoken_emoji_1F484" msgid="7348014979080444885">"Lipstick"</string> + <string name="spoken_emoji_1F485" msgid="6133507975565116339">"Nail polish"</string> + <string name="spoken_emoji_1F486" msgid="9085459968247394155">"Face massage"</string> + <string name="spoken_emoji_1F487" msgid="1479113637259592150">"Haircut"</string> + <string name="spoken_emoji_1F488" msgid="6922559285234100252">"Barber pole"</string> + <string name="spoken_emoji_1F489" msgid="8114863680950147305">"Syringe"</string> + <string name="spoken_emoji_1F48A" msgid="8526843630145963032">"Pill"</string> + <string name="spoken_emoji_1F48B" msgid="2538528967897640292">"Kiss mark"</string> + <string name="spoken_emoji_1F48C" msgid="1681173271652890232">"Love letter"</string> + <string name="spoken_emoji_1F48D" msgid="8259886164999042373">"Ring"</string> + <string name="spoken_emoji_1F48E" msgid="8777981696011111101">"Gem stone"</string> + <string name="spoken_emoji_1F48F" msgid="741593675183677907">"Kiss"</string> + <string name="spoken_emoji_1F490" msgid="4482549128959806736">"Bouquet"</string> + <string name="spoken_emoji_1F491" msgid="2305245307882441500">"Couple with heart"</string> + <string name="spoken_emoji_1F492" msgid="3884119934804475732">"Wedding"</string> + <string name="spoken_emoji_1F493" msgid="1208828371565525121">"Beating heart"</string> + <string name="spoken_emoji_1F494" msgid="6198876398509338718">"Broken heart"</string> + <string name="spoken_emoji_1F495" msgid="9206202744967130919">"Two hearts"</string> + <string name="spoken_emoji_1F496" msgid="5436953041732207775">"Sparkling heart"</string> + <string name="spoken_emoji_1F497" msgid="7285142863951448473">"Growing heart"</string> + <string name="spoken_emoji_1F498" msgid="7940131245037575715">"Heart with arrow"</string> + <string name="spoken_emoji_1F499" msgid="4453235040265550009">"Blue heart"</string> + <string name="spoken_emoji_1F49A" msgid="6262178648366971405">"Green heart"</string> + <string name="spoken_emoji_1F49B" msgid="8085384999750714368">"Yellow heart"</string> + <string name="spoken_emoji_1F49C" msgid="453829540120898698">"Purple heart"</string> + <string name="spoken_emoji_1F49D" msgid="3460534750224161888">"Heart with ribbon"</string> + <string name="spoken_emoji_1F49E" msgid="4490636226072523867">"Revolving hearts"</string> + <string name="spoken_emoji_1F49F" msgid="2059319756421226336">"Heart decoration"</string> + <string name="spoken_emoji_1F4A0" msgid="1954850380550212038">"Diamond shape with a dot inside"</string> + <string name="spoken_emoji_1F4A1" msgid="403137413540909021">"Electric light bulb"</string> + <string name="spoken_emoji_1F4A2" msgid="2604192053295622063">"Anger symbol"</string> + <string name="spoken_emoji_1F4A3" msgid="6378351742957821735">"Bomb"</string> + <string name="spoken_emoji_1F4A4" msgid="7217736258870346625">"Sleeping symbol"</string> + <string name="spoken_emoji_1F4A5" msgid="5401995723541239858">"Collision symbol"</string> + <string name="spoken_emoji_1F4A6" msgid="3837802182716483848">"Splashing sweat symbol"</string> + <string name="spoken_emoji_1F4A7" msgid="5718438987757885141">"Droplet"</string> + <string name="spoken_emoji_1F4A8" msgid="4472108229720006377">"Dash symbol"</string> + <string name="spoken_emoji_1F4A9" msgid="1240958472788430032">"Pile of poo"</string> + <string name="spoken_emoji_1F4AA" msgid="8427525538635146416">"Flexed biceps"</string> + <string name="spoken_emoji_1F4AB" msgid="5484114759939427459">"Dizzy symbol"</string> + <string name="spoken_emoji_1F4AC" msgid="5571196638219612682">"Speech balloon"</string> + <string name="spoken_emoji_1F4AD" msgid="353174619257798652">"Thought balloon"</string> + <string name="spoken_emoji_1F4AE" msgid="1223142786927162641">"White flower"</string> + <string name="spoken_emoji_1F4AF" msgid="3526278354452138397">"Hundred points symbol"</string> + <string name="spoken_emoji_1F4B0" msgid="4124102195175124156">"Money bag"</string> + <string name="spoken_emoji_1F4B1" msgid="8339494003418572905">"Currency exchange"</string> + <string name="spoken_emoji_1F4B2" msgid="3179159430187243132">"Heavy pound sign"</string> + <string name="spoken_emoji_1F4B3" msgid="5375412518221759596">"Credit card"</string> + <string name="spoken_emoji_1F4B4" msgid="1068592463669453204">"Banknote with yen sign"</string> + <string name="spoken_emoji_1F4B5" msgid="1426708699891832564">"Banknote with pound sign"</string> + <string name="spoken_emoji_1F4B6" msgid="8289249930736444837">"Banknote with euro sign"</string> + <string name="spoken_emoji_1F4B7" msgid="5245100496860739429">"Banknote with pound sign"</string> + <string name="spoken_emoji_1F4B8" msgid="4401099580477164440">"Money with wings"</string> + <string name="spoken_emoji_1F4B9" msgid="647509393536679903">"Chart with upwards trend and yen sign"</string> + <string name="spoken_emoji_1F4BA" msgid="1269737854891046321">"Seat"</string> + <string name="spoken_emoji_1F4BB" msgid="6252883563347816451">"Personal computer"</string> + <string name="spoken_emoji_1F4BC" msgid="6182597732218446206">"Briefcase"</string> + <string name="spoken_emoji_1F4BD" msgid="5820961044768829176">"Minidisc"</string> + <string name="spoken_emoji_1F4BE" msgid="4754542485835379808">"Floppy disk"</string> + <string name="spoken_emoji_1F4BF" msgid="2237481756984721795">"Optical disc"</string> + <string name="spoken_emoji_1F4C0" msgid="491582501089694461">"DVD"</string> + <string name="spoken_emoji_1F4C1" msgid="6645461382494158111">"File folder"</string> + <string name="spoken_emoji_1F4C2" msgid="8095638715523765338">"Open file folder"</string> + <string name="spoken_emoji_1F4C3" msgid="3727274466173970142">"Page with curl"</string> + <string name="spoken_emoji_1F4C4" msgid="4382570710795501612">"Page facing up"</string> + <string name="spoken_emoji_1F4C5" msgid="8693944622627762487">"Calendar"</string> + <string name="spoken_emoji_1F4C6" msgid="8469908708708424640">"Tear-off calendar"</string> + <string name="spoken_emoji_1F4C7" msgid="2665313547987324495">"Card index"</string> + <string name="spoken_emoji_1F4C8" msgid="8007686702282833600">"Chart with upwards trend"</string> + <string name="spoken_emoji_1F4C9" msgid="2271951411192893684">"Chart with downwards trend"</string> + <string name="spoken_emoji_1F4CA" msgid="3525692829622381444">"Bar chart"</string> + <string name="spoken_emoji_1F4CB" msgid="977639227554095521">"Clipboard"</string> + <string name="spoken_emoji_1F4CC" msgid="156107396088741574">"Pushpin"</string> + <string name="spoken_emoji_1F4CD" msgid="4266572175361190231">"Round pushpin"</string> + <string name="spoken_emoji_1F4CE" msgid="6294288509864968290">"Paperclip"</string> + <string name="spoken_emoji_1F4CF" msgid="149679400831136810">"Straight ruler"</string> + <string name="spoken_emoji_1F4D0" msgid="8130339336619202915">"Triangular ruler"</string> + <string name="spoken_emoji_1F4D1" msgid="5852176364856284968">"Bookmark tabs"</string> + <string name="spoken_emoji_1F4D2" msgid="2276810154105920052">"Ledger"</string> + <string name="spoken_emoji_1F4D3" msgid="5873386492793610808">"Notebook"</string> + <string name="spoken_emoji_1F4D4" msgid="4754469936418776360">"Notebook with decorative cover"</string> + <string name="spoken_emoji_1F4D5" msgid="4642713351802778905">"Closed book"</string> + <string name="spoken_emoji_1F4D6" msgid="6987347918381807186">"Open book"</string> + <string name="spoken_emoji_1F4D7" msgid="7813394163241379223">"Green book"</string> + <string name="spoken_emoji_1F4D8" msgid="7189799718984979521">"Blue book"</string> + <string name="spoken_emoji_1F4D9" msgid="3874664073186440225">"Orange book"</string> + <string name="spoken_emoji_1F4DA" msgid="872212072924287762">"Books"</string> + <string name="spoken_emoji_1F4DB" msgid="2015183603583392969">"Name badge"</string> + <string name="spoken_emoji_1F4DC" msgid="5075845110932456783">"Scroll"</string> + <string name="spoken_emoji_1F4DD" msgid="2494006707147586786">"Memo"</string> + <string name="spoken_emoji_1F4DE" msgid="7883008605002117671">"Telephone receiver"</string> + <string name="spoken_emoji_1F4DF" msgid="3538610110623780465">"Pager"</string> + <string name="spoken_emoji_1F4E0" msgid="2960778342609543077">"Fax machine"</string> + <string name="spoken_emoji_1F4E1" msgid="6269733703719242108">"Satellite antenna"</string> + <string name="spoken_emoji_1F4E2" msgid="1987535386302883116">"Public address loudspeaker"</string> + <string name="spoken_emoji_1F4E3" msgid="5588916572878599224">"Cheering megaphone"</string> + <string name="spoken_emoji_1F4E4" msgid="2063561529097749707">"Outbox tray"</string> + <string name="spoken_emoji_1F4E5" msgid="3232462702926143576">"Inbox tray"</string> + <string name="spoken_emoji_1F4E6" msgid="3399454337197561635">"Package"</string> + <string name="spoken_emoji_1F4E7" msgid="5557136988503873238">"E-mail symbol"</string> + <string name="spoken_emoji_1F4E8" msgid="30698793974124123">"Incoming envelope"</string> + <string name="spoken_emoji_1F4E9" msgid="5947550337678643166">"Envelope with downwards arrow above"</string> + <string name="spoken_emoji_1F4EA" msgid="772614045207213751">"Closed mailbox with lowered flag"</string> + <string name="spoken_emoji_1F4EB" msgid="6491414165464146137">"Closed mailbox with raised flag"</string> + <string name="spoken_emoji_1F4EC" msgid="7369517138779988438">"Open mailbox with raised flag"</string> + <string name="spoken_emoji_1F4ED" msgid="5657520436285454241">"Open mailbox with lowered flag"</string> + <string name="spoken_emoji_1F4EE" msgid="8464138906243608614">"Postbox"</string> + <string name="spoken_emoji_1F4EF" msgid="8801427577198798226">"Postal horn"</string> + <string name="spoken_emoji_1F4F0" msgid="6330208624731662525">"Newspaper"</string> + <string name="spoken_emoji_1F4F1" msgid="3966503935581675695">"Mobile phone"</string> + <string name="spoken_emoji_1F4F2" msgid="1057540341746100087">"Mobile phone with rightwards arrow at left"</string> + <string name="spoken_emoji_1F4F3" msgid="5003984447315754658">"Vibration mode"</string> + <string name="spoken_emoji_1F4F4" msgid="5549847566968306253">"Mobile phone off"</string> + <string name="spoken_emoji_1F4F5" msgid="3660199448671699238">"No mobile phones"</string> + <string name="spoken_emoji_1F4F6" msgid="2676974903233268860">"Antenna with bars"</string> + <string name="spoken_emoji_1F4F7" msgid="2643891943105989039">"Camera"</string> + <string name="spoken_emoji_1F4F9" msgid="4475626303058218048">"Video camera"</string> + <string name="spoken_emoji_1F4FA" msgid="1079796186652960775">"Television"</string> + <string name="spoken_emoji_1F4FB" msgid="3848729587403760645">"Radio"</string> + <string name="spoken_emoji_1F4FC" msgid="8370432508874310054">"Videocassette"</string> + <string name="spoken_emoji_1F500" msgid="2389947994502144547">"Twisted rightwards arrows"</string> + <string name="spoken_emoji_1F501" msgid="2132188352433347009">"Clockwise rightwards and leftwards open circle arrows"</string> + <string name="spoken_emoji_1F502" msgid="2361976580513178391">"Clockwise rightwards and leftwards open circle arrows with circled one overlay"</string> + <string name="spoken_emoji_1F503" msgid="8936283551917858793">"Clockwise downwards and upwards open circle arrows"</string> + <string name="spoken_emoji_1F504" msgid="708290317843535943">"Anticlockwise downwards and upwards open circle arrows"</string> + <string name="spoken_emoji_1F505" msgid="6348909939004951860">"Low brightness symbol"</string> + <string name="spoken_emoji_1F506" msgid="4449609297521280173">"High brightness symbol"</string> + <string name="spoken_emoji_1F507" msgid="7136386694923708448">"Speaker with cancellation stroke"</string> + <string name="spoken_emoji_1F508" msgid="5063567689831527865">"Speaker"</string> + <string name="spoken_emoji_1F509" msgid="3948050077992370791">"Speaker with one sound wave"</string> + <string name="spoken_emoji_1F50A" msgid="5818194948677277197">"Speaker with three sound waves"</string> + <string name="spoken_emoji_1F50B" msgid="8083470451266295876">"Battery"</string> + <string name="spoken_emoji_1F50C" msgid="7793219132036431680">"Electric plug"</string> + <string name="spoken_emoji_1F50D" msgid="8140244710637926780">"Left-pointing magnifying glass"</string> + <string name="spoken_emoji_1F50E" msgid="4751821352839693365">"Right-pointing magnifying glass"</string> + <string name="spoken_emoji_1F50F" msgid="915079280472199605">"Lock with ink pen"</string> + <string name="spoken_emoji_1F510" msgid="7658381761691758318">"Closed lock with key"</string> + <string name="spoken_emoji_1F511" msgid="262319867774655688">"Key"</string> + <string name="spoken_emoji_1F512" msgid="5628688337255115175">"Lock"</string> + <string name="spoken_emoji_1F513" msgid="8579201846619420981">"Open lock"</string> + <string name="spoken_emoji_1F514" msgid="7027268683047322521">"Bell"</string> + <string name="spoken_emoji_1F515" msgid="8903179856036069242">"Bell with cancellation stroke"</string> + <string name="spoken_emoji_1F516" msgid="108097933937925381">"Bookmark"</string> + <string name="spoken_emoji_1F517" msgid="2450846665734313397">"Link symbol"</string> + <string name="spoken_emoji_1F518" msgid="7028220286841437832">"Radio button"</string> + <string name="spoken_emoji_1F519" msgid="8211189165075445687">"Back with leftwards arrow above"</string> + <string name="spoken_emoji_1F51A" msgid="823966751787338892">"End with leftwards arrow above"</string> + <string name="spoken_emoji_1F51B" msgid="5920570742107943382">"On with exclamation mark with left right arrow above"</string> + <string name="spoken_emoji_1F51C" msgid="110609810659826676">"Soon with rightwards arrow above"</string> + <string name="spoken_emoji_1F51D" msgid="4087697222026095447">"Top with upwards arrow above"</string> + <string name="spoken_emoji_1F51E" msgid="8512873526157201775">"No one under eighteen symbol"</string> + <string name="spoken_emoji_1F51F" msgid="8673370823728653973">"Keycap ten"</string> + <string name="spoken_emoji_1F520" msgid="7335109890337048900">"Input symbol for latin capital letters"</string> + <string name="spoken_emoji_1F521" msgid="2693185864450925778">"Input symbol for latin small letters"</string> + <string name="spoken_emoji_1F522" msgid="8419130286280673347">"Input symbol for numbers"</string> + <string name="spoken_emoji_1F523" msgid="3318053476401719421">"Input symbol for symbols"</string> + <string name="spoken_emoji_1F524" msgid="1625073997522316331">"Input symbol for latin letters"</string> + <string name="spoken_emoji_1F525" msgid="4083884189172963790">"Fire"</string> + <string name="spoken_emoji_1F526" msgid="2035494936742643580">"Electric torch"</string> + <string name="spoken_emoji_1F527" msgid="134257142354034271">"Wrench"</string> + <string name="spoken_emoji_1F528" msgid="700627429570609375">"Hammer"</string> + <string name="spoken_emoji_1F529" msgid="7480548235904988573">"Nut and bolt"</string> + <string name="spoken_emoji_1F52A" msgid="7613580031502317893">"Hocho"</string> + <string name="spoken_emoji_1F52B" msgid="4554906608328118613">"Pistol"</string> + <string name="spoken_emoji_1F52C" msgid="1330294501371770790">"Microscope"</string> + <string name="spoken_emoji_1F52D" msgid="7549551775445177140">"Telescope"</string> + <string name="spoken_emoji_1F52E" msgid="4457099417872625141">"Crystal ball"</string> + <string name="spoken_emoji_1F52F" msgid="8899031001317442792">"Six pointed star with middle dot"</string> + <string name="spoken_emoji_1F530" msgid="3572898444281774023">"Japanese symbol for beginner"</string> + <string name="spoken_emoji_1F531" msgid="5225633376450025396">"Trident emblem"</string> + <string name="spoken_emoji_1F532" msgid="9169568490485180779">"Black square button"</string> + <string name="spoken_emoji_1F533" msgid="6554193837201918598">"White square button"</string> + <string name="spoken_emoji_1F534" msgid="8339298801331865340">"Large red circle"</string> + <string name="spoken_emoji_1F535" msgid="1227403104835533512">"Large blue circle"</string> + <string name="spoken_emoji_1F536" msgid="5477372445510469331">"Large orange diamond"</string> + <string name="spoken_emoji_1F537" msgid="3158915214347274626">"Large blue diamond"</string> + <string name="spoken_emoji_1F538" msgid="4300084249474451991">"Small orange diamond"</string> + <string name="spoken_emoji_1F539" msgid="6535159756325742275">"Small blue diamond"</string> + <string name="spoken_emoji_1F53A" msgid="3728196273988781389">"Up-pointing red triangle"</string> + <string name="spoken_emoji_1F53B" msgid="7182097039614128707">"Down-pointing red triangle"</string> + <string name="spoken_emoji_1F53C" msgid="4077022046319615029">"Up-pointing small red triangle"</string> + <string name="spoken_emoji_1F53D" msgid="3939112784894620713">"Down-pointing small red triangle"</string> + <string name="spoken_emoji_1F550" msgid="7761392621689986218">"Clock face one o\'clock"</string> + <string name="spoken_emoji_1F551" msgid="2699448504113431716">"Clock face two o\'clock"</string> + <string name="spoken_emoji_1F552" msgid="5872107867411853750">"Clock face three o\'clock"</string> + <string name="spoken_emoji_1F553" msgid="8490966286158640743">"Clock face four o\'clock"</string> + <string name="spoken_emoji_1F554" msgid="7662585417832909280">"Clock face five o\'clock"</string> + <string name="spoken_emoji_1F555" msgid="5564698204520412009">"Clock face six o\'clock"</string> + <string name="spoken_emoji_1F556" msgid="7325712194836512205">"Clock face seven o\'clock"</string> + <string name="spoken_emoji_1F557" msgid="4398343183682848693">"Clock face eight o\'clock"</string> + <string name="spoken_emoji_1F558" msgid="3110507820404018172">"Clock face nine o\'clock"</string> + <string name="spoken_emoji_1F559" msgid="2972160366448337839">"Clock face ten o\'clock"</string> + <string name="spoken_emoji_1F55A" msgid="5568112876681714834">"Clock face eleven o\'clock"</string> + <string name="spoken_emoji_1F55B" msgid="6731739890330659276">"Clock face twelve o\'clock"</string> + <string name="spoken_emoji_1F55C" msgid="7838853679879115890">"Clock face one-thirty"</string> + <string name="spoken_emoji_1F55D" msgid="3518832144255922544">"Clock face two-thirty"</string> + <string name="spoken_emoji_1F55E" msgid="3092760695634993002">"Clock face three-thirty"</string> + <string name="spoken_emoji_1F55F" msgid="2326720311892906763">"Clock face four-thirty"</string> + <string name="spoken_emoji_1F560" msgid="5771339179963924448">"Clock face five-thirty"</string> + <string name="spoken_emoji_1F561" msgid="3139944777062475382">"Clock face six-thirty"</string> + <string name="spoken_emoji_1F562" msgid="8273944611162457084">"Clock face seven-thirty"</string> + <string name="spoken_emoji_1F563" msgid="8643976903718136299">"Clock face eight-thirty"</string> + <string name="spoken_emoji_1F564" msgid="3511070239796141638">"Clock face nine-thirty"</string> + <string name="spoken_emoji_1F565" msgid="4567451985272963088">"Clock face ten-thirty"</string> + <string name="spoken_emoji_1F566" msgid="2790552288169929810">"Clock face eleven-thirty"</string> + <string name="spoken_emoji_1F567" msgid="9026037362100689337">"Clock face twelve-thirty"</string> + <string name="spoken_emoji_1F5FB" msgid="9037503671676124015">"Mount Fuji"</string> + <string name="spoken_emoji_1F5FC" msgid="1409415995817242150">"Tokyo tower"</string> + <string name="spoken_emoji_1F5FD" msgid="2562726956654429582">"Statue of Liberty"</string> + <string name="spoken_emoji_1F5FE" msgid="1184469756905210580">"Silhouette of Japan"</string> + <string name="spoken_emoji_1F5FF" msgid="6003594799354942297">"Moyai"</string> + <string name="spoken_emoji_1F600" msgid="7601109464776835283">"Grinning face"</string> + <string name="spoken_emoji_1F601" msgid="746026523967444503">"Grinning face with smiling eyes"</string> + <string name="spoken_emoji_1F602" msgid="8354558091785198246">"Face with tears of joy"</string> + <string name="spoken_emoji_1F603" msgid="3861022912544159823">"Smiling face with open mouth"</string> + <string name="spoken_emoji_1F604" msgid="5119021072966343531">"Smiling face with open mouth and smiling eyes"</string> + <string name="spoken_emoji_1F605" msgid="6140813923973561735">"Smiling face with open mouth and cold sweat"</string> + <string name="spoken_emoji_1F606" msgid="3549936813966832799">"Smiling face with open mouth and tightly-closed eyes"</string> + <string name="spoken_emoji_1F607" msgid="2826424078212384817">"Smiling face with halo"</string> + <string name="spoken_emoji_1F608" msgid="7343559595089811640">"Smiling face with horns"</string> + <string name="spoken_emoji_1F609" msgid="5481030187207504405">"Winking face"</string> + <string name="spoken_emoji_1F60A" msgid="5023337769148679767">"Smiling face with smiling eyes"</string> + <string name="spoken_emoji_1F60B" msgid="3005248217216195694">"Face savouring delicious food"</string> + <string name="spoken_emoji_1F60C" msgid="349384012958268496">"Relieved face"</string> + <string name="spoken_emoji_1F60D" msgid="7921853137164938391">"Smiling face with heart-shaped eyes"</string> + <string name="spoken_emoji_1F60E" msgid="441718886380605643">"Smiling face with sunglasses"</string> + <string name="spoken_emoji_1F60F" msgid="2674453144890180538">"Smirking face"</string> + <string name="spoken_emoji_1F610" msgid="3225675825334102369">"Neutral face"</string> + <string name="spoken_emoji_1F611" msgid="7199179827619679668">"Expressionless face"</string> + <string name="spoken_emoji_1F612" msgid="985081329745137998">"Unamused face"</string> + <string name="spoken_emoji_1F613" msgid="5548607684830303562">"Face with cold sweat"</string> + <string name="spoken_emoji_1F614" msgid="3196305665259916390">"Pensive face"</string> + <string name="spoken_emoji_1F615" msgid="3051674239303969101">"Confused face"</string> + <string name="spoken_emoji_1F616" msgid="8124887056243813089">"Confounded face"</string> + <string name="spoken_emoji_1F617" msgid="7052733625511122870">"Kissing face"</string> + <string name="spoken_emoji_1F618" msgid="408207170572303753">"Face throwing a kiss"</string> + <string name="spoken_emoji_1F619" msgid="8645430335143153645">"Kissing face with smiling eyes"</string> + <string name="spoken_emoji_1F61A" msgid="2882157190974340247">"Kissing face with closed eyes"</string> + <string name="spoken_emoji_1F61B" msgid="3765927202787211499">"Face with stuck-out tongue"</string> + <string name="spoken_emoji_1F61C" msgid="198943912107589389">"Face with stuck-out tongue and winking eye"</string> + <string name="spoken_emoji_1F61D" msgid="7643546385877816182">"Face with stuck-out tongue and tightly-closed eyes"</string> + <string name="spoken_emoji_1F61E" msgid="1528732952202098364">"Disappointed face"</string> + <string name="spoken_emoji_1F61F" msgid="1853664164636082404">"Worried face"</string> + <string name="spoken_emoji_1F620" msgid="6051942001307375830">"Angry face"</string> + <string name="spoken_emoji_1F621" msgid="2114711878097257704">"Pouting face"</string> + <string name="spoken_emoji_1F622" msgid="29291014645931822">"Crying face"</string> + <string name="spoken_emoji_1F623" msgid="7803959833595184773">"Persevering face"</string> + <string name="spoken_emoji_1F624" msgid="8637637647725752799">"Face with look of triumph"</string> + <string name="spoken_emoji_1F625" msgid="6153625183493635030">"Disappointed but relieved face"</string> + <string name="spoken_emoji_1F626" msgid="6179485689935562950">"Frowning face with open mouth"</string> + <string name="spoken_emoji_1F627" msgid="8566204052903012809">"Anguished face"</string> + <string name="spoken_emoji_1F628" msgid="8875777401624904224">"Fearful face"</string> + <string name="spoken_emoji_1F629" msgid="1411538490319190118">"Weary face"</string> + <string name="spoken_emoji_1F62A" msgid="4726686726690289969">"Sleepy face"</string> + <string name="spoken_emoji_1F62B" msgid="3221980473921623613">"Tired face"</string> + <string name="spoken_emoji_1F62C" msgid="4616356691941225182">"Grimacing face"</string> + <string name="spoken_emoji_1F62D" msgid="4283677508698812232">"Loudly crying face"</string> + <string name="spoken_emoji_1F62E" msgid="726083405284353894">"Face with open mouth"</string> + <string name="spoken_emoji_1F62F" msgid="7746620088234710962">"Hushed face"</string> + <string name="spoken_emoji_1F630" msgid="3298804852155581163">"Face with open mouth and cold sweat"</string> + <string name="spoken_emoji_1F631" msgid="1603391150954646779">"Face screaming in fear"</string> + <string name="spoken_emoji_1F632" msgid="4846193232203976013">"Astonished face"</string> + <string name="spoken_emoji_1F633" msgid="4023593836629700443">"Flushed face"</string> + <string name="spoken_emoji_1F634" msgid="3155265083246248129">"Sleeping face"</string> + <string name="spoken_emoji_1F635" msgid="4616691133452764482">"Dizzy face"</string> + <string name="spoken_emoji_1F636" msgid="947000211822375683">"Face without mouth"</string> + <string name="spoken_emoji_1F637" msgid="1269551267347165774">"Face with medical mask"</string> + <string name="spoken_emoji_1F638" msgid="3410766467496872301">"Grinning cat face with smiling eyes"</string> + <string name="spoken_emoji_1F639" msgid="1833417519781022031">"Cat face with tears of joy"</string> + <string name="spoken_emoji_1F63A" msgid="8566294484007152613">"Smiling cat face with open mouth"</string> + <string name="spoken_emoji_1F63B" msgid="74417995938927571">"Smiling cat face with heart-shaped eyes"</string> + <string name="spoken_emoji_1F63C" msgid="6472812005729468870">"Cat face with wry smile"</string> + <string name="spoken_emoji_1F63D" msgid="1638398369553349509">"Kissing cat face with closed eyes"</string> + <string name="spoken_emoji_1F63E" msgid="6788969063020278986">"Pouting cat face"</string> + <string name="spoken_emoji_1F63F" msgid="1207234562459550185">"Crying cat face"</string> + <string name="spoken_emoji_1F640" msgid="6023054549904329638">"Weary cat face"</string> + <string name="spoken_emoji_1F645" msgid="5202090629227587076">"Face with no good gesture"</string> + <string name="spoken_emoji_1F646" msgid="6734425134415138134">"Face with OK gesture"</string> + <string name="spoken_emoji_1F647" msgid="1090285518444205483">"Person bowing deeply"</string> + <string name="spoken_emoji_1F648" msgid="8978535230610522356">"See-no-evil monkey"</string> + <string name="spoken_emoji_1F649" msgid="8486145279809495102">"Hear-no-evil monkey"</string> + <string name="spoken_emoji_1F64A" msgid="1237524974033228660">"Speak-no-evil monkey"</string> + <string name="spoken_emoji_1F64B" msgid="4251150782016370475">"Happy person raising one hand"</string> + <string name="spoken_emoji_1F64C" msgid="5446231430684558344">"Person raising both hands in celebration"</string> + <string name="spoken_emoji_1F64D" msgid="4646485595309482342">"Person frowning"</string> + <string name="spoken_emoji_1F64E" msgid="3376579939836656097">"Person with pouting face"</string> + <string name="spoken_emoji_1F64F" msgid="1044439574356230711">"Person with folded hands"</string> + <string name="spoken_emoji_1F680" msgid="513263736012689059">"Rocket"</string> + <string name="spoken_emoji_1F681" msgid="9201341783850525339">"Helicopter"</string> + <string name="spoken_emoji_1F682" msgid="8046933583867498698">"Steam locomotive"</string> + <string name="spoken_emoji_1F683" msgid="8772750354339223092">"Railway car"</string> + <string name="spoken_emoji_1F684" msgid="346396777356203608">"High-speed train"</string> + <string name="spoken_emoji_1F685" msgid="1237059817190832730">"High-speed train with bullet nose"</string> + <string name="spoken_emoji_1F686" msgid="3525197227223620343">"Train"</string> + <string name="spoken_emoji_1F687" msgid="5110143437960392837">"Metro"</string> + <string name="spoken_emoji_1F688" msgid="4702085029871797965">"Light rail"</string> + <string name="spoken_emoji_1F689" msgid="2375851019798817094">"Station"</string> + <string name="spoken_emoji_1F68A" msgid="6368370859718717198">"Tram"</string> + <string name="spoken_emoji_1F68B" msgid="2920160427117436633">"Tram car"</string> + <string name="spoken_emoji_1F68C" msgid="1061520934758810864">"Bus"</string> + <string name="spoken_emoji_1F68D" msgid="2890059031360969304">"Oncoming bus"</string> + <string name="spoken_emoji_1F68E" msgid="6234042976027309654">"Tram"</string> + <string name="spoken_emoji_1F68F" msgid="5871099334672012107">"Bus stop"</string> + <string name="spoken_emoji_1F690" msgid="8080964620200195262">"Minibus"</string> + <string name="spoken_emoji_1F691" msgid="999173032408730501">"Ambulance"</string> + <string name="spoken_emoji_1F692" msgid="1712863785341849487">"Fire engine"</string> + <string name="spoken_emoji_1F693" msgid="7987109037389768934">"Police car"</string> + <string name="spoken_emoji_1F694" msgid="6061658916653884608">"Oncoming police car"</string> + <string name="spoken_emoji_1F695" msgid="6913445460364247283">"Taxi"</string> + <string name="spoken_emoji_1F696" msgid="6391604457418285404">"Oncoming taxi"</string> + <string name="spoken_emoji_1F697" msgid="7978399334396733790">"Automobile"</string> + <string name="spoken_emoji_1F698" msgid="7006050861129732018">"Oncoming automobile"</string> + <string name="spoken_emoji_1F699" msgid="630317052666590607">"Recreational vehicle"</string> + <string name="spoken_emoji_1F69A" msgid="4739797891735823577">"Delivery truck"</string> + <string name="spoken_emoji_1F69B" msgid="4715997280786620649">"Articulated lorry"</string> + <string name="spoken_emoji_1F69C" msgid="5557395610750818161">"Tractor"</string> + <string name="spoken_emoji_1F69D" msgid="5467164189942951047">"Monorail"</string> + <string name="spoken_emoji_1F69E" msgid="169238196389832234">"Mountain railway"</string> + <string name="spoken_emoji_1F69F" msgid="7508128757012845102">"Suspension railway"</string> + <string name="spoken_emoji_1F6A0" msgid="8733056213790160147">"Mountain cableway"</string> + <string name="spoken_emoji_1F6A1" msgid="4666516337749347253">"Aerial tramway"</string> + <string name="spoken_emoji_1F6A2" msgid="4511220588943129583">"Ship"</string> + <string name="spoken_emoji_1F6A3" msgid="8412962252222205387">"Rowing boat"</string> + <string name="spoken_emoji_1F6A4" msgid="8867571300266339211">"Speedboat"</string> + <string name="spoken_emoji_1F6A5" msgid="7650260812741963884">"Horizontal traffic light"</string> + <string name="spoken_emoji_1F6A6" msgid="485575967773793454">"Vertical traffic light"</string> + <string name="spoken_emoji_1F6A7" msgid="6411048933816976794">"Construction sign"</string> + <string name="spoken_emoji_1F6A8" msgid="6345717218374788364">"Police cars revolving light"</string> + <string name="spoken_emoji_1F6A9" msgid="6586380356807600412">"Triangular flag on post"</string> + <string name="spoken_emoji_1F6AA" msgid="8954448167261738885">"Door"</string> + <string name="spoken_emoji_1F6AB" msgid="5313946262888343544">"No entry sign"</string> + <string name="spoken_emoji_1F6AC" msgid="6946858177965948288">"Smoking symbol"</string> + <string name="spoken_emoji_1F6AD" msgid="6320088669185507241">"No smoking symbol"</string> + <string name="spoken_emoji_1F6AE" msgid="1062469925352817189">"Put litter in its place symbol"</string> + <string name="spoken_emoji_1F6AF" msgid="2286668056123642208">"Do not litter symbol"</string> + <string name="spoken_emoji_1F6B0" msgid="179424763882990952">"Drinking water symbol"</string> + <string name="spoken_emoji_1F6B1" msgid="5585212805429161877">"Non-drinking water symbol"</string> + <string name="spoken_emoji_1F6B2" msgid="1771885082068421875">"Bicycle"</string> + <string name="spoken_emoji_1F6B3" msgid="8033779581263314408">"No bicycles"</string> + <string name="spoken_emoji_1F6B4" msgid="1999538449018476947">"Cyclist"</string> + <string name="spoken_emoji_1F6B5" msgid="340846352660993117">"Mountain cyclist"</string> + <string name="spoken_emoji_1F6B6" msgid="4351024386495098336">"Pedestrian"</string> + <string name="spoken_emoji_1F6B7" msgid="4564800655866838802">"No pedestrians"</string> + <string name="spoken_emoji_1F6B8" msgid="3020531906940267349">"Children crossing"</string> + <string name="spoken_emoji_1F6B9" msgid="1207095844125041251">"Mens symbol"</string> + <string name="spoken_emoji_1F6BA" msgid="2346879310071017531">"Womens symbol"</string> + <string name="spoken_emoji_1F6BB" msgid="2370172469642078526">"Restroom"</string> + <string name="spoken_emoji_1F6BC" msgid="5558827593563530851">"Baby symbol"</string> + <string name="spoken_emoji_1F6BD" msgid="9213590243049835957">"Toilet"</string> + <string name="spoken_emoji_1F6BE" msgid="394016533781742491">"Water closet"</string> + <string name="spoken_emoji_1F6BF" msgid="906336365928291207">"Shower"</string> + <string name="spoken_emoji_1F6C0" msgid="4592099854378821599">"Bath"</string> + <string name="spoken_emoji_1F6C1" msgid="2845056048320031158">"Bathtub"</string> + <string name="spoken_emoji_1F6C2" msgid="8117262514698011877">"Passport control"</string> + <string name="spoken_emoji_1F6C3" msgid="1176342001834630675">"Customs"</string> + <string name="spoken_emoji_1F6C4" msgid="1477622834179978886">"Baggage claim"</string> + <string name="spoken_emoji_1F6C5" msgid="2495834050856617451">"Left luggage"</string> +</resources> diff --git a/java/res/values-en-rAU/strings-letter-descriptions.xml b/java/res/values-en-rAU/strings-letter-descriptions.xml new file mode 100644 index 000000000..514bc6cbd --- /dev/null +++ b/java/res/values-en-rAU/strings-letter-descriptions.xml @@ -0,0 +1,208 @@ +<?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. +*/ + --> + +<!-- + These accented letters (spoken_accented_letter_*) are unsupported by TTS. + These symbols (spoken_symbol_*) are also unsupported by TTS. + TODO: Remove these string resources when TTS/TalkBack support these letters. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="spoken_accented_letter_00AA" msgid="4374325261868451570">"Feminine ordinal indicator"</string> + <string name="spoken_accented_letter_00B5" msgid="9031387673828823891">"Micro sign"</string> + <string name="spoken_accented_letter_00BA" msgid="5045198452071207437">"Masculine ordinal indicator"</string> + <string name="spoken_accented_letter_00DF" msgid="2260098367028134281">"Sharp S"</string> + <string name="spoken_accented_letter_00E0" msgid="2234515772182387086">"A, grave"</string> + <string name="spoken_accented_letter_00E1" msgid="7780174500802535063">"A, acute"</string> + <string name="spoken_accented_letter_00E2" msgid="7054108480488102631">"A, circumflex"</string> + <string name="spoken_accented_letter_00E3" msgid="8252569677935693343">"A, tilde"</string> + <string name="spoken_accented_letter_00E4" msgid="6610118430986969466">"A, diaeresis"</string> + <string name="spoken_accented_letter_00E5" msgid="7630449270070348394">"A, ring above"</string> + <string name="spoken_accented_letter_00E6" msgid="701838036007000032">"A, E, ligature"</string> + <string name="spoken_accented_letter_00E7" msgid="2991289211702135310">"C, cedilla"</string> + <string name="spoken_accented_letter_00E8" msgid="2080035251848179782">"E, grave"</string> + <string name="spoken_accented_letter_00E9" msgid="2708473976407506968">"E, acute"</string> + <string name="spoken_accented_letter_00EA" msgid="1898848081635119449">"E, circumflex"</string> + <string name="spoken_accented_letter_00EB" msgid="8318942663983499634">"E, diaeresis"</string> + <string name="spoken_accented_letter_00EC" msgid="7643810590358306098">"I, grave"</string> + <string name="spoken_accented_letter_00ED" msgid="8288035355103120759">"I, acute"</string> + <string name="spoken_accented_letter_00EE" msgid="1137417730211688894">"I, circumflex"</string> + <string name="spoken_accented_letter_00EF" msgid="8993714322731956785">"I, diaeresis"</string> + <string name="spoken_accented_letter_00F0" msgid="3427567511221967857">"Eth"</string> + <string name="spoken_accented_letter_00F1" msgid="6983294908255378605">"N, tilde"</string> + <string name="spoken_accented_letter_00F2" msgid="2623804069332183695">"O, grave"</string> + <string name="spoken_accented_letter_00F3" msgid="8945987631729216917">"O, acute"</string> + <string name="spoken_accented_letter_00F4" msgid="2415494299699717276">"O, circumflex"</string> + <string name="spoken_accented_letter_00F5" msgid="7320512716652765243">"O, tilde"</string> + <string name="spoken_accented_letter_00F6" msgid="9101179351242478555">"O, diaeresis"</string> + <string name="spoken_accented_letter_00F8" msgid="1488324280918884122">"O, stroke"</string> + <string name="spoken_accented_letter_00F9" msgid="2823570256527173278">"U, grave"</string> + <string name="spoken_accented_letter_00FA" msgid="6883092085077298608">"U, acute"</string> + <string name="spoken_accented_letter_00FB" msgid="4948239400399514418">"U, circumflex"</string> + <string name="spoken_accented_letter_00FC" msgid="2496066211694000442">"U, diaeresis"</string> + <string name="spoken_accented_letter_00FD" msgid="2400529610834233890">"Y, acute"</string> + <string name="spoken_accented_letter_00FE" msgid="8788160115017853040">"Thorn"</string> + <string name="spoken_accented_letter_00FF" msgid="5225610161025124830">"Y, diaeresis"</string> + <string name="spoken_accented_letter_0101" msgid="5573209280917268157">"A, macron"</string> + <string name="spoken_accented_letter_0103" msgid="2469151120095164730">"A, breve"</string> + <string name="spoken_accented_letter_0105" msgid="8312689789855786427">"A, ogonek"</string> + <string name="spoken_accented_letter_0107" msgid="5708507895287798642">"C, acute"</string> + <string name="spoken_accented_letter_0109" msgid="7008112603489583335">"C, circumflex"</string> + <string name="spoken_accented_letter_010B" msgid="5641359473019753216">"C, dot above"</string> + <string name="spoken_accented_letter_010D" msgid="1048661826408437168">"C, caron"</string> + <string name="spoken_accented_letter_010F" msgid="603374318657992205">"D, caron"</string> + <string name="spoken_accented_letter_0111" msgid="5517997642285938260">"D, stroke"</string> + <string name="spoken_accented_letter_0113" msgid="2326009009311798997">"E, macron"</string> + <string name="spoken_accented_letter_0115" msgid="3964545407091037747">"E, breve"</string> + <string name="spoken_accented_letter_0117" msgid="8799753183781089777">"E, dot above"</string> + <string name="spoken_accented_letter_0119" msgid="3772451226935709136">"E, ogonek"</string> + <string name="spoken_accented_letter_011B" msgid="7663481332351461288">"E, caron"</string> + <string name="spoken_accented_letter_011D" msgid="1181326600595482369">"G, circumflex"</string> + <string name="spoken_accented_letter_011F" msgid="6843415389823096647">"G, breve"</string> + <string name="spoken_accented_letter_0121" msgid="6205288708713306903">"G, dot above"</string> + <string name="spoken_accented_letter_0123" msgid="2394277128105386261">"G, cedilla"</string> + <string name="spoken_accented_letter_0125" msgid="6575866461277751345">"H, circumflex"</string> + <string name="spoken_accented_letter_0127" msgid="1316971762214091641">"H, stroke"</string> + <string name="spoken_accented_letter_0129" msgid="7824912405885325754">"I, tilde"</string> + <string name="spoken_accented_letter_012B" msgid="6772690258769905270">"I, macron"</string> + <string name="spoken_accented_letter_012D" msgid="2933871131556503448">"I, breve"</string> + <string name="spoken_accented_letter_012F" msgid="1340511254985181663">"I, ogonek"</string> + <string name="spoken_accented_letter_0131" msgid="5635600720566083969">"Dotless I"</string> + <string name="spoken_accented_letter_0133" msgid="7593704176516791941">"I, J, ligature"</string> + <string name="spoken_accented_letter_0135" msgid="4521109674238248436">"J, circumflex"</string> + <string name="spoken_accented_letter_0137" msgid="5886444641003852175">"K, cedilla"</string> + <string name="spoken_accented_letter_0138" msgid="4200294389170924853">"Kra"</string> + <string name="spoken_accented_letter_013A" msgid="3558015385412543517">"L, acute"</string> + <string name="spoken_accented_letter_013C" msgid="1853639924813858734">"L, cedilla"</string> + <string name="spoken_accented_letter_013E" msgid="7489345561739421886">"L, caron"</string> + <string name="spoken_accented_letter_0140" msgid="7946718707268270589">"L, middle dot"</string> + <string name="spoken_accented_letter_0142" msgid="752931798111122240">"L, stroke"</string> + <string name="spoken_accented_letter_0144" msgid="201843550323875352">"N, acute"</string> + <string name="spoken_accented_letter_0146" msgid="3403847152606051818">"N, cedilla"</string> + <string name="spoken_accented_letter_0148" msgid="9215300786722209338">"N, caron"</string> + <string name="spoken_accented_letter_0149" msgid="3191850286630154063">"N, preceded by apostrophe"</string> + <string name="spoken_accented_letter_014B" msgid="8503022408522837410">"Eng"</string> + <string name="spoken_accented_letter_014D" msgid="4452323602550610641">"O, macron"</string> + <string name="spoken_accented_letter_014F" msgid="2795957717094385336">"O, breve"</string> + <string name="spoken_accented_letter_0151" msgid="8013704745216410244">"O, double acute"</string> + <string name="spoken_accented_letter_0153" msgid="8410582495993285221">"O, E, ligature"</string> + <string name="spoken_accented_letter_0155" msgid="7601517174689798560">"R, acute"</string> + <string name="spoken_accented_letter_0157" msgid="9071455715455643810">"R, cedilla"</string> + <string name="spoken_accented_letter_0159" msgid="7726911392381543439">"R, caron"</string> + <string name="spoken_accented_letter_015B" msgid="1854129531164494117">"S, acute"</string> + <string name="spoken_accented_letter_015D" msgid="4743571603550582530">"S, circumflex"</string> + <string name="spoken_accented_letter_015F" msgid="1519945638631588761">"S, cedilla"</string> + <string name="spoken_accented_letter_0161" msgid="7493478552029144246">"S, caron"</string> + <string name="spoken_accented_letter_0163" msgid="9103547637928833069">"T, cedilla"</string> + <string name="spoken_accented_letter_0165" msgid="7306159398214872062">"T, caron"</string> + <string name="spoken_accented_letter_0167" msgid="5578767705098672443">"T, stroke"</string> + <string name="spoken_accented_letter_0169" msgid="413046581387735371">"U, tilde"</string> + <string name="spoken_accented_letter_016B" msgid="3209778874978859441">"U, macron"</string> + <string name="spoken_accented_letter_016D" msgid="2983326533258602840">"U, breve"</string> + <string name="spoken_accented_letter_016F" msgid="4416532499516387231">"U, ring above"</string> + <string name="spoken_accented_letter_0171" msgid="3435171971353200807">"U, double acute"</string> + <string name="spoken_accented_letter_0173" msgid="4494154432483553480">"U, ogonek"</string> + <string name="spoken_accented_letter_0175" msgid="2154545579611918513">"W, circumflex"</string> + <string name="spoken_accented_letter_0177" msgid="4034463827306904781">"Y, circumflex"</string> + <string name="spoken_accented_letter_017A" msgid="3368292232292925369">"Z, acute"</string> + <string name="spoken_accented_letter_017C" msgid="2834484584505860430">"Z, dot above"</string> + <string name="spoken_accented_letter_017E" msgid="1209240442434887098">"Z, caron"</string> + <string name="spoken_accented_letter_017F" msgid="317501463253362415">"Long S"</string> + <string name="spoken_accented_letter_01A1" msgid="630186564859044196">"O, horn"</string> + <string name="spoken_accented_letter_01B0" msgid="8544012177684640443">"U, horn"</string> + <string name="spoken_accented_letter_0219" msgid="1960371842020076066">"S, comma below"</string> + <string name="spoken_accented_letter_021B" msgid="1398418662032919032">"T, comma below"</string> + <string name="spoken_accented_letter_0259" msgid="2464085263158415898">"Schwa"</string> + <string name="spoken_accented_letter_1EA1" msgid="688124877202887630">"A, dot below"</string> + <string name="spoken_accented_letter_1EA3" msgid="327960130366386256">"A, hook above"</string> + <string name="spoken_accented_letter_1EA5" msgid="637406363453769610">"A, circumflex and acute"</string> + <string name="spoken_accented_letter_1EA7" msgid="1419591804181615409">"A, circumflex and grave"</string> + <string name="spoken_accented_letter_1EA9" msgid="6068887382734896756">"A, circumflex and hook above"</string> + <string name="spoken_accented_letter_1EAB" msgid="7236523151662538333">"A, circumflex and tilde"</string> + <string name="spoken_accented_letter_1EAD" msgid="2363364864106332076">"A, circumflex and dot below"</string> + <string name="spoken_accented_letter_1EAF" msgid="1576329511464272935">"A, breve and acute"</string> + <string name="spoken_accented_letter_1EB1" msgid="4634735072816076592">"A, breve and grave"</string> + <string name="spoken_accented_letter_1EB3" msgid="2325245849038771534">"A, breve and hook above"</string> + <string name="spoken_accented_letter_1EB5" msgid="3720427596242746295">"A, breve and tilde"</string> + <string name="spoken_accented_letter_1EB7" msgid="700415535653646695">"A, breve and dot below"</string> + <string name="spoken_accented_letter_1EB9" msgid="3901338692305890487">"E, dot below"</string> + <string name="spoken_accented_letter_1EBB" msgid="4028688699415417302">"E, hook above"</string> + <string name="spoken_accented_letter_1EBD" msgid="181253633045931897">"E, tilde"</string> + <string name="spoken_accented_letter_1EBF" msgid="3309618845007944963">"E, circumflex and acute"</string> + <string name="spoken_accented_letter_1EC1" msgid="8139046749226332542">"E, circumflex and grave"</string> + <string name="spoken_accented_letter_1EC3" msgid="3239674223053133383">"E, circumflex and hook above"</string> + <string name="spoken_accented_letter_1EC5" msgid="2216559244705714587">"E, circumflex and tilde"</string> + <string name="spoken_accented_letter_1EC7" msgid="9012731468253986792">"E, circumflex and dot below"</string> + <string name="spoken_accented_letter_1EC9" msgid="2901917620195717034">"I, hook above"</string> + <string name="spoken_accented_letter_1ECB" msgid="5470387489820034621">"I, dot below"</string> + <string name="spoken_accented_letter_1ECD" msgid="1340122876914839806">"O, dot below"</string> + <string name="spoken_accented_letter_1ECF" msgid="2326921263882559755">"O, hook above"</string> + <string name="spoken_accented_letter_1ED1" msgid="2885683296042774958">"O, circumflex and acute"</string> + <string name="spoken_accented_letter_1ED3" msgid="6857664926477376178">"O, circumflex and grave"</string> + <string name="spoken_accented_letter_1ED5" msgid="2015209467290624062">"O, circumflex and hook above"</string> + <string name="spoken_accented_letter_1ED7" msgid="7924481354960306389">"O, circumflex and tilde"</string> + <string name="spoken_accented_letter_1ED9" msgid="7023315590332365554">"O, circumflex and dot below"</string> + <string name="spoken_accented_letter_1EDB" msgid="2379438944917634496">"O, horn and acute"</string> + <string name="spoken_accented_letter_1EDD" msgid="8107077534204404085">"O, horn and grave"</string> + <string name="spoken_accented_letter_1EDF" msgid="1846880105528347966">"O, horn and hook above"</string> + <string name="spoken_accented_letter_1EE1" msgid="1520037313389776718">"O, horn and tilde"</string> + <string name="spoken_accented_letter_1EE3" msgid="907964027171008963">"O, horn and dot below"</string> + <string name="spoken_accented_letter_1EE5" msgid="1522024630360038700">"U, dot below"</string> + <string name="spoken_accented_letter_1EE7" msgid="7815412228302952637">"U, hook above"</string> + <string name="spoken_accented_letter_1EE9" msgid="4219119671251485651">"U, horn and acute"</string> + <string name="spoken_accented_letter_1EEB" msgid="4086009841269002231">"U, horn and grave"</string> + <string name="spoken_accented_letter_1EED" msgid="3528151733528719847">"U, horn and hook above"</string> + <string name="spoken_accented_letter_1EEF" msgid="3508548229409072119">"U, horn and tilde"</string> + <string name="spoken_accented_letter_1EF1" msgid="1912816350401931115">"U, horn and dot below"</string> + <string name="spoken_accented_letter_1EF3" msgid="7211760439435946494">"Y, grave"</string> + <string name="spoken_accented_letter_1EF5" msgid="8998864482764007384">"Y, dot below"</string> + <string name="spoken_accented_letter_1EF7" msgid="922043627252869200">"Y, hook above"</string> + <string name="spoken_accented_letter_1EF9" msgid="6213977100552260366">"Y, tilde"</string> + <string name="spoken_symbol_00A1" msgid="4281758332905123408">"Inverted exclamation mark"</string> + <string name="spoken_symbol_00AB" msgid="4093069643313064892">"Left-pointing double angle quotation mark"</string> + <string name="spoken_symbol_00B7" msgid="2447718728927874920">"Middle dot"</string> + <string name="spoken_symbol_00B9" msgid="8026257165451461231">"Superscript one"</string> + <string name="spoken_symbol_00BB" msgid="1102740075655373928">"Right-pointing double angle quotation mark"</string> + <string name="spoken_symbol_00BF" msgid="6233794752573788098">"Inverted question mark"</string> + <string name="spoken_symbol_2018" msgid="4886476295598930225">"Left single quotation mark"</string> + <string name="spoken_symbol_2019" msgid="8892530161598134083">"Right single quotation mark"</string> + <string name="spoken_symbol_201A" msgid="2072987157683446644">"Single low-9 quotation mark"</string> + <string name="spoken_symbol_201C" msgid="4588048378803665427">"Left double quotation mark"</string> + <string name="spoken_symbol_201D" msgid="1642776849495925895">"Right double quotation mark"</string> + <string name="spoken_symbol_2020" msgid="9084628638189344431">"Dagger"</string> + <string name="spoken_symbol_2021" msgid="5081396468559426475">"Double dagger"</string> + <string name="spoken_symbol_2030" msgid="9068837172419431755">"Per mille sign"</string> + <string name="spoken_symbol_2032" msgid="3014506329156664396">"Prime"</string> + <string name="spoken_symbol_2033" msgid="1251022699713475088">"Double prime"</string> + <string name="spoken_symbol_2039" msgid="6989616457213775957">"Single left-pointing angle quotation mark"</string> + <string name="spoken_symbol_203A" msgid="31245095449823701">"Single right-pointing angle quotation mark"</string> + <string name="spoken_symbol_2074" msgid="2116717717093306894">"Superscript four"</string> + <string name="spoken_symbol_207F" msgid="1706731172134246659">"Superscript latin small letter n"</string> + <string name="spoken_symbol_20B1" msgid="2159994270622444689">"Peso sign"</string> + <string name="spoken_symbol_2105" msgid="7289404939366976829">"Care of"</string> + <string name="spoken_symbol_2192" msgid="827804523596125414">"Rightwards arrow"</string> + <string name="spoken_symbol_2193" msgid="2659541693445985717">"Downwards arrow"</string> + <string name="spoken_symbol_2205" msgid="4457188084269117343">"Empty set"</string> + <string name="spoken_symbol_2206" msgid="4856786565708380687">"Increment"</string> + <string name="spoken_symbol_2264" msgid="5092061257745123554">"Less than or equal to"</string> + <string name="spoken_symbol_2265" msgid="1907966479878036357">"Greater than or equal to"</string> + <string name="spoken_symbol_2605" msgid="5202920479405857753">"Black star"</string> +</resources> diff --git a/java/res/values-en-rAU/strings-talkback-descriptions.xml b/java/res/values-en-rAU/strings-talkback-descriptions.xml new file mode 100644 index 000000000..78c290545 --- /dev/null +++ b/java/res/values-en-rAU/strings-talkback-descriptions.xml @@ -0,0 +1,90 @@ +<?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">"Plug in a headset to hear password keys spoken aloud."</string> + <string name="spoken_current_text_is" msgid="4240549866156675799">"Current text is %s"</string> + <string name="spoken_no_text_entered" msgid="1711276837961785646">"No text entered"</string> + <string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> corrects <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> to <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> performs auto-correction"</string> + <string name="spoken_empty_suggestion" msgid="4250215619373459752">"No suggestion"</string> + <string name="spoken_description_unknown" msgid="5139930082759824442">"Unknown character"</string> + <string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string> + <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"More symbols"</string> + <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string> + <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Symbols"</string> + <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string> + <string name="spoken_description_delete" msgid="3878902286264983302">"Delete"</string> + <string name="spoken_description_to_symbol" msgid="8244903740201126590">"Symbols"</string> + <string name="spoken_description_to_alpha" msgid="4081215210530031950">"Letters"</string> + <string name="spoken_description_to_numeric" msgid="4560261331530795682">"Numbers"</string> + <string name="spoken_description_settings" msgid="7281251004003143204">"Settings"</string> + <string name="spoken_description_tab" msgid="8210782459446866716">"Tab"</string> + <string name="spoken_description_space" msgid="5908716896642059145">"Space"</string> + <string name="spoken_description_mic" msgid="6153138783813452464">"Voice input"</string> + <string name="spoken_description_emoji" msgid="7990051553008088470">"Emoji"</string> + <string name="spoken_description_return" msgid="3183692287397645708">"Return"</string> + <string name="spoken_description_search" msgid="5099937658231911288">"Search"</string> + <string name="spoken_description_dot" msgid="5644176501632325560">"Full stop"</string> + <string name="spoken_description_language_switch" msgid="6818666779313544553">"Switch language"</string> + <string name="spoken_description_action_next" msgid="431761808119616962">"Next"</string> + <string name="spoken_description_action_previous" msgid="2919072174697865110">"Previous"</string> + <string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift enabled"</string> + <string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps lock enabled"</string> + <string name="spoken_description_mode_symbol" msgid="111186851131446691">"Symbols mode"</string> + <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"More symbols mode"</string> + <string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Letters mode"</string> + <string name="spoken_description_mode_phone" msgid="2061220553756692903">"Phone mode"</string> + <string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Phone symbols mode"</string> + <string name="announce_keyboard_hidden" msgid="2313574218950517779">"Keyboard hidden"</string> + <string name="announce_keyboard_mode" msgid="6698257917367823205">"Showing <xliff:g id="KEYBOARD_MODE">%s</xliff:g> keyboard"</string> + <string name="keyboard_mode_date" msgid="6597407244976713364">"date"</string> + <string name="keyboard_mode_date_time" msgid="3642804408726668808">"date and time"</string> + <string name="keyboard_mode_email" msgid="1239682082047693644">"email"</string> + <string name="keyboard_mode_im" msgid="3812086215529493501">"messaging"</string> + <string name="keyboard_mode_number" msgid="5395042245837996809">"number"</string> + <string name="keyboard_mode_phone" msgid="2486230278064523665">"phone"</string> + <string name="keyboard_mode_text" msgid="9138789594969187494">"text"</string> + <string name="keyboard_mode_time" msgid="8558297845514402675">"time"</string> + <string name="keyboard_mode_url" msgid="8072011652949962550">"URL"</string> + <string name="spoken_descrption_emoji_category_recents" msgid="4185344945205590692">"Recents"</string> + <string name="spoken_descrption_emoji_category_people" msgid="8414196269847492817">"People"</string> + <string name="spoken_descrption_emoji_category_objects" msgid="6116297906606195278">"Objects"</string> + <string name="spoken_descrption_emoji_category_nature" msgid="5018340512472354640">"Nature"</string> + <string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Places"</string> + <string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Symbols"</string> + <string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emoticons"</string> + <string name="spoken_description_upper_case" msgid="4904835255229433916">"Capital <xliff:g id="LOWER_LETTER">%s</xliff:g>"</string> + <string name="spoken_letter_0049" msgid="4743162182646977944">"Capital I"</string> + <string name="spoken_letter_0130" msgid="4766619646231612274">"Capital I, dot above"</string> + <string name="spoken_symbol_unknown" msgid="717298227061173706">"Unknown symbol"</string> + <string name="spoken_emoji_unknown" msgid="5981009928135394306">"Unknown emoji"</string> + <string name="spoken_emoticon_3A_2D_21_20" msgid="2410905667389534573">"Bored face"</string> + <string name="spoken_emoticon_3A_2D_24_20" msgid="2481260475945560438">"Embarrassed face"</string> + <string name="spoken_emoticon_42_2D_29_20" msgid="1063205250387128068">"Face wearing sunglasses"</string> + <string name="spoken_emoticon_3A_4F_20" msgid="532695091593447238">"Surprised face"</string> + <string name="spoken_emoticon_3A_2D_2A_20" msgid="5612342617244114291">"Kissing face"</string> + <string name="spoken_emoticon_3A_2D_5B_20" msgid="2223507987759905920">"Frowning face"</string> + <string name="spoken_open_more_keys_keyboard" msgid="6832897688371903747">"Alternative characters are available"</string> + <string name="spoken_close_more_keys_keyboard" msgid="3524914657934712026">"Alternative characters are dismissed"</string> + <string name="spoken_open_more_suggestions" msgid="4231720702882969760">"Alternative suggestions are available"</string> + <string name="spoken_close_more_suggestions" msgid="9118455416075032839">"Alternative suggestions are dismissed"</string> +</resources> diff --git a/java/res/values-en-rAU/strings.xml b/java/res/values-en-rAU/strings.xml new file mode 100644 index 000000000..e60c7212e --- /dev/null +++ b/java/res/values-en-rAU/strings.xml @@ -0,0 +1,207 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** +** Copyright 2008, 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="english_ime_input_options" msgid="3909945612939668554">"Input options"</string> + <string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Look up contact names"</string> + <string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Spell checker uses entries from your contact list"</string> + <string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrate on keypress"</string> + <string name="sound_on_keypress" msgid="6093592297198243644">"Sound on keypress"</string> + <string name="popup_on_keypress" msgid="123894815723512944">"Pop-up on key press"</string> + <string name="settings_screen_preferences" msgid="2696713156722014624">"Preferences"</string> + <string name="settings_screen_accounts" msgid="2786418968536696670">"Accounts & Privacy"</string> + <string name="settings_screen_appearance" msgid="7358046399111611615">"Appearance & Layouts"</string> + <string name="settings_screen_gesture" msgid="8826372746901183556">"Gesture Typing"</string> + <string name="settings_screen_correction" msgid="1616818407747682955">"Text correction"</string> + <string name="settings_screen_advanced" msgid="7472408607625972994">"Advanced"</string> + <string name="settings_screen_theme" msgid="2137262503543943871">"Theme"</string> + <string name="enable_split_keyboard" msgid="4177264923999493614">"Enable split keyboard"</string> + <string name="cloud_sync_title" msgid="8579271074443847055">"Google Keyboard Sync"</string> + <string name="cloud_sync_summary" msgid="7684887161145650857">"Sync is turned on"</string> + <string name="cloud_sync_summary_disabled" msgid="4553338970382825796">"Sync your personal dictionary across devices"</string> + <string name="sync_now_title" msgid="3088838136743277721">"Sync now"</string> + <string name="clear_sync_data_title" msgid="2041801164014550565">"Delete Keyboard Cloud data"</string> + <string name="clear_sync_data_summary" msgid="993477139012576584">"Deletes your synced data from Google"</string> + <string name="clear_sync_data_confirmation" msgid="2811931135574727678">"Your synced data will be deleted from the cloud. Are you sure?"</string> + <string name="clear_sync_data_ok" msgid="613104067705915132">"Delete"</string> + <string name="cloud_sync_cancel" msgid="5877481252150919037">"Cancel"</string> + <string name="cloud_sync_opt_in_text" msgid="9176039655776298248">"Your personal dictionary will be synced and backed up to Google servers. The statistical information of word frequency may be collected to help improve our products. The collection and usage of all the information will be compliant with "<a href="https://www.google.com/policies/privacy">"Google\'s Privacy Policy"</a>"."</string> + <string name="add_account_to_enable_sync" msgid="7836932571852055265">"Please add a Google account to this device to enable this feature"</string> + <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"Switch to other input methods"</string> + <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"Language switch key also covers other input methods"</string> + <string name="show_language_switch_key" msgid="5915478828318774384">"Language switch key"</string> + <string name="show_language_switch_key_summary" msgid="7343403647474265713">"Show when multiple input languages are enabled"</string> + <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"Key pop-up dismiss delay"</string> + <string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"No delay"</string> + <string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"Default"</string> + <string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g>ms"</string> + <string name="settings_system_default" msgid="6268225104743331821">"System default"</string> + <string name="use_contacts_dict" msgid="4435317977804180815">"Suggest Contact names"</string> + <string name="use_contacts_dict_summary" msgid="6599983334507879959">"Use names from Contacts for suggestions and corrections"</string> + <string name="use_personalized_dicts" msgid="5167396352105467626">"Personalised suggestions"</string> + <string name="enable_metrics_logging" msgid="5506372337118822837">"Improve <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> + <string name="use_double_space_period" msgid="8781529969425082860">"Double-space full stop"</string> + <string name="use_double_space_period_summary" msgid="6532892187247952799">"Double tap on spacebar inserts a full stop followed by a space"</string> + <string name="auto_cap" msgid="1719746674854628252">"Auto-capitalisation"</string> + <string name="auto_cap_summary" msgid="7934452761022946874">"Capitalise the first word of each sentence"</string> + <string name="edit_personal_dictionary" msgid="3996910038952940420">"Personal dictionary"</string> + <string name="configure_dictionaries_title" msgid="4238652338556902049">"Add-on dictionaries"</string> + <string name="main_dictionary" msgid="4798763781818361168">"Main dictionary"</string> + <string name="prefs_show_suggestions" msgid="8026799663445531637">"Show correction suggestions"</string> + <string name="prefs_show_suggestions_summary" msgid="1583132279498502825">"Display suggested words while typing"</string> + <string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"Block offensive words"</string> + <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"Do not suggest potentially offensive words"</string> + <string name="auto_correction" msgid="7630720885194996950">"Auto-correction"</string> + <string name="auto_correction_summary" msgid="5625751551134658006">"Correct mistyped words automatically with spacebar and punctuation"</string> + <string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"Off"</string> + <string name="auto_correction_threshold_mode_modest" msgid="8788366690620799097">"Modest"</string> + <string name="auto_correction_threshold_mode_aggressive" msgid="7319007299148899623">"Aggressive"</string> + <string name="auto_correction_threshold_mode_very_aggressive" msgid="1853309024129480416">"Very aggressive"</string> + <string name="bigram_prediction" msgid="1084449187723948550">"Next-word suggestions"</string> + <string name="bigram_prediction_summary" msgid="3896362682751109677">"Use the previous word when making suggestions"</string> + <string name="gesture_input" msgid="826951152254563827">"Enable gesture typing"</string> + <string name="gesture_input_summary" msgid="9180350639305731231">"Input a word by sliding through the letters"</string> + <string name="gesture_preview_trail" msgid="3802333369335722221">"Show gesture trail"</string> + <string name="gesture_floating_preview_text" msgid="4443240334739381053">"Dynamic floating preview"</string> + <string name="gesture_floating_preview_text_summary" msgid="4472696213996203533">"See the suggested word while gesturing"</string> + <string name="gesture_space_aware" msgid="2078291600664682496">"Phrase gesture"</string> + <string name="gesture_space_aware_summary" msgid="4371385818348528538">"Input spaces during gestures by gliding to the space key"</string> + <string name="voice_input" msgid="3583258583521397548">"Voice input key"</string> + <string name="voice_input_disabled_summary" msgid="8141750303464726129">"No voice input methods enabled. Check Language & input settings."</string> + <string name="configure_input_method" msgid="373356270290742459">"Configure input methods"</string> + <string name="language_selection_title" msgid="3666971864764478269">"Languages"</string> + <string name="help_and_feedback" msgid="5328219371839879161">"Help & feedback"</string> + <string name="select_language" msgid="5709487854987078367">"Languages"</string> + <string name="hint_add_to_dictionary" msgid="573678656946085380">"Touch again to save"</string> + <string name="hint_add_to_dictionary_without_word" msgid="3040385779511255101">"Touch here to save"</string> + <string name="has_dictionary" msgid="6071847973466625007">"Dictionary available"</string> + <string name="keyboard_layout" msgid="8451164783510487501">"Keyboard theme"</string> + <string name="switch_accounts" msgid="3321216593719006162">"Change accounts"</string> + <string name="no_accounts_selected" msgid="2073821619103904330">"No accounts selected"</string> + <string name="account_selected" msgid="2846876462199625974">"Currently using <xliff:g id="EMAIL_ADDRESS">%1$s</xliff:g>"</string> + <string name="account_select_ok" msgid="9141195141763227797">"OK"</string> + <string name="account_select_cancel" msgid="5181012062618504340">"Cancel"</string> + <string name="account_select_sign_out" msgid="3299651159390187933">"Sign out"</string> + <string name="account_select_title" msgid="6279711684772922649">"Select an account to use"</string> + <string name="subtype_en_GB" msgid="88170601942311355">"English (UK)"</string> + <string name="subtype_en_US" msgid="6160452336634534239">"English (US)"</string> + <string name="subtype_es_US" msgid="5583145191430180200">"Spanish (US)"</string> + <string name="subtype_hi_ZZ" msgid="8860448146262798623">"Hinglish"</string> + <string name="subtype_sr_ZZ" msgid="9059219552986034343">"Serbian (Latin)"</string> + <string name="subtype_with_layout_en_GB" msgid="1931018968641592304">"English (UK) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_en_US" msgid="8809311287529805422">"English (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_es_US" msgid="510930471167541338">"Spanish (US) (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_hi_ZZ" msgid="6827402953860547044">"Hinglish (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_with_layout_sr_ZZ" msgid="2859024772719772407">"Serbian (<xliff:g id="KEYBOARD_LAYOUT">%s</xliff:g>)"</string> + <string name="subtype_generic_traditional" msgid="8584594350973800586">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Traditional)"</string> + <string name="subtype_generic_compact" msgid="3353673321203202922">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g> (Compact)"</string> + <string name="subtype_no_language" msgid="7137390094240139495">"No language (Alphabet)"</string> + <string name="subtype_no_language_qwerty" msgid="244337630616742604">"Alphabet (QWERTY)"</string> + <string name="subtype_no_language_qwertz" msgid="443066912507547976">"Alphabet (QWERTZ)"</string> + <string name="subtype_no_language_azerty" msgid="8144348527575640087">"Alphabet (AZERTY)"</string> + <string name="subtype_no_language_dvorak" msgid="1564494667584718094">"Alphabet (Dvorak)"</string> + <string name="subtype_no_language_colemak" msgid="5837418400010302623">"Alphabet (Colemak)"</string> + <string name="subtype_no_language_pcqwerty" msgid="5354918232046200018">"Alphabet (PC)"</string> + <string name="subtype_emoji" msgid="7483586578074549196">"Emoji"</string> + <string name="keyboard_theme" msgid="4909551808526178852">"Keyboard theme"</string> + <string name="custom_input_styles_title" msgid="8429952441821251512">"Customised input styles"</string> + <string name="add_style" msgid="6163126614514489951">"Add style"</string> + <string name="add" msgid="8299699805688017798">"Add"</string> + <string name="remove" msgid="4486081658752944606">"Remove"</string> + <string name="save" msgid="7646738597196767214">"Save"</string> + <string name="subtype_locale" msgid="8576443440738143764">"Language"</string> + <string name="keyboard_layout_set" msgid="4309233698194565609">"Layout"</string> + <string name="custom_input_style_note_message" msgid="8826731320846363423">"Your customised input style needs to be enabled before you start using it. Do you want to enable it now?"</string> + <string name="enable" msgid="5031294444630523247">"Enable"</string> + <string name="not_now" msgid="6172462888202790482">"Not now"</string> + <string name="custom_input_style_already_exists" msgid="8008728952215449707">"The same input style already exists: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string> + <string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Keypress vibration duration"</string> + <string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Keypress sound volume"</string> + <string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Key long press delay"</string> + <string name="button_default" msgid="3988017840431881491">"Default"</string> + <string name="setup_welcome_title" msgid="6112821709832031715">"Welcome to <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> + <string name="setup_welcome_additional_description" msgid="8150252008545768953">"with Gesture Typing"</string> + <string name="setup_start_action" msgid="8936036460897347708">"Get started"</string> + <string name="setup_next_action" msgid="371821437915144603">"Next step"</string> + <string name="setup_steps_title" msgid="6400373034871816182">"Setting up <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> + <string name="setup_step1_title" msgid="3147967630253462315">"Enable <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> + <string name="setup_step1_instruction" msgid="2578631936624637241">"Please tick \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" in your Language & input settings. This will authorise it to run on your device."</string> + <string name="setup_step1_finished_instruction" msgid="10761482004957994">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> is already enabled in your Language & input settings, so this step is done. On to the next one!"</string> + <string name="setup_step1_action" msgid="4366513534999901728">"Enable in Settings"</string> + <string name="setup_step2_title" msgid="6860725447906690594">"Switch to <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> + <string name="setup_step2_instruction" msgid="9141481964870023336">"Next, select \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\" as your active text-input method."</string> + <string name="setup_step2_action" msgid="1660330307159824337">"Switch input methods"</string> + <string name="setup_step3_title" msgid="3154757183631490281">"Congratulations, you\'re all set!"</string> + <string name="setup_step3_instruction" msgid="8025981829605426000">"Now you can type in all your favourite apps with <xliff:g id="APPLICATION_NAME">%s</xliff:g>."</string> + <string name="setup_step3_action" msgid="600879797256942259">"Configure additional languages"</string> + <string name="setup_finish_action" msgid="276559243409465389">"Finished"</string> + <string name="app_name" msgid="6320102637491234792">"Dictionary Provider"</string> + <string name="dictionary_provider_name" msgid="3027315045397363079">"Dictionary Provider"</string> + <string name="dictionary_service_name" msgid="6237472350693511448">"Dictionary Service"</string> + <string name="download_description" msgid="6014835283119198591">"Dictionary update information"</string> + <string name="dictionary_settings_title" msgid="8091417676045693313">"Add-on dictionaries"</string> + <string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"Dictionary available"</string> + <string name="dictionary_settings_summary" msgid="5305694987799824349">"Settings for dictionaries"</string> + <string name="user_dictionaries" msgid="3582332055892252845">"User dictionaries"</string> + <string name="default_user_dict_pref_name" msgid="1625055720489280530">"User dictionary"</string> + <string name="dictionary_available" msgid="4728975345815214218">"Dictionary available"</string> + <string name="dictionary_downloading" msgid="2982650524622620983">"Currently downloading"</string> + <string name="dictionary_installed" msgid="8081558343559342962">"Installed"</string> + <string name="dictionary_disabled" msgid="8950383219564621762">"Installed, disabled"</string> + <string name="cannot_connect_to_dict_service" msgid="9216933695765732398">"Problem connecting to dictionary service"</string> + <string name="no_dictionaries_available" msgid="8039920716566132611">"No dictionaries available"</string> + <string name="check_for_updates_now" msgid="8087688440916388581">"Refresh"</string> + <string name="last_update" msgid="730467549913588780">"Last updated"</string> + <string name="message_updating" msgid="4457761393932375219">"Checking for updates"</string> + <string name="message_loading" msgid="5638680861387748936">"Loading…"</string> + <string name="main_dict_description" msgid="3072821352793492143">"Main dictionary"</string> + <string name="cancel" msgid="6830980399865683324">"Cancel"</string> + <string name="go_to_settings" msgid="3876892339342569259">"Settings"</string> + <string name="install_dict" msgid="180852772562189365">"Install"</string> + <string name="cancel_download_dict" msgid="7843340278507019303">"Cancel"</string> + <string name="delete_dict" msgid="756853268088330054">"Delete"</string> + <string name="should_download_over_metered_prompt" msgid="1583881200688185508">"The selected language on your mobile device has an available dictionary.<br/> We recommend <b>downloading</b> the <xliff:g id="LANGUAGE_NAME">%1$s</xliff:g> dictionary to improve your typing experience.<br/> <br/> The download could take a minute or two over 3G. Charges may apply if you don\'t have an <b>unlimited data plan</b>.<br/> If you are not sure which data plan you have, we recommend finding a Wi-Fi connection to start the download automatically.<br/> <br/> Tip: You can download and remove dictionaries by going to <b>Language & input</b> in the <b>Settings</b> menu of your mobile device."</string> + <string name="download_over_metered" msgid="1643065851159409546">"Download now (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g>MB)"</string> + <string name="do_not_download_over_metered" msgid="2176209579313941583">"Download over Wi-Fi"</string> + <string name="dict_available_notification_title" msgid="4583842811218581658">"A dictionary is available for <xliff:g id="LANGUAGE_NAME">%1$s</xliff:g>"</string> + <string name="dict_available_notification_description" msgid="1075194169443163487">"Press to review and download"</string> + <string name="toast_downloading_suggestions" msgid="6128155879830851739">"Downloading: suggestions for <xliff:g id="LANGUAGE_NAME">%1$s</xliff:g> will be ready soon."</string> + <string name="version_text" msgid="2715354215568469385">"Version <xliff:g id="VERSION_NUMBER">%1$s</xliff:g>"</string> + <string name="user_dict_settings_add_menu_title" msgid="1254195365689387076">"Add"</string> + <string name="user_dict_settings_add_dialog_title" msgid="4096700390211748168">"Add to dictionary"</string> + <string name="user_dict_settings_add_screen_title" msgid="5818914331629278758">"Phrase"</string> + <string name="user_dict_settings_add_dialog_more_options" msgid="5671682004887093112">"More options"</string> + <string name="user_dict_settings_add_dialog_less_options" msgid="2716586567241724126">"Fewer options"</string> + <string name="user_dict_settings_add_dialog_confirm" msgid="4703129507388332950">"OK"</string> + <string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"Word:"</string> + <string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"Shortcut:"</string> + <string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"Language:"</string> + <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"Type a word"</string> + <string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"Optional shortcut"</string> + <string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"Edit word"</string> + <string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"Edit"</string> + <string name="user_dict_settings_context_menu_delete_title" msgid="8142932447689461181">"Delete"</string> + <string name="user_dict_settings_empty_text" msgid="558499587532668203">"You don\'t have any words in the user dictionary. Add a word by touching the Add (+) button."</string> + <string name="user_dict_settings_all_languages" msgid="8276126583216298886">"For all languages"</string> + <string name="user_dict_settings_more_languages" msgid="7131268499685180461">"More languages…"</string> + <string name="user_dict_settings_delete" msgid="110413335187193859">"Delete"</string> + <string name="user_dict_fast_scroll_alphabet" msgid="5431919401558285473">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> +</resources> diff --git a/java/res/values/donottranslate-debug-settings.xml b/java/res/values/donottranslate-debug-settings.xml index 491043f1a..9df73ae4f 100644 --- a/java/res/values/donottranslate-debug-settings.xml +++ b/java/res/values/donottranslate-debug-settings.xml @@ -41,20 +41,10 @@ <string name="prefs_key_popup_dismiss_end_x_scale_settings">Key popup dismiss end X scale</string> <!-- Title of the settings for key popup dismiss animation end Y-scale (in percentile) [CHAR LIMIT=35] --> <string name="prefs_key_popup_dismiss_end_y_scale_settings">Key popup dismiss end Y scale</string> - <!-- Title of the settings for reading an external dictionary file --> - <string name="prefs_read_external_dictionary">Read external dictionary file</string> <!-- Title of the settings to enable keyboard resizing --> <string name="prefs_resize_keyboard">Enable keyboard resizing</string> <!-- Title of the settings for setting keyboard height --> <string name="prefs_keyboard_height_scale">Keyboard height scale</string> - <!-- Message to show when there are no files to install as an external dictionary [CHAR LIMIT=100] --> - <string name="read_external_dictionary_no_files_message">No dictionary files in the Downloads folder</string> - <!-- Title of the dialog that selects a file to install as an external dictionary [CHAR LIMIT=50] --> - <string name="read_external_dictionary_multiple_files_title">Select a dictionary file to install</string> - <!-- Title of the confirmation dialog to install a file as an external dictionary [CHAR LIMIT=50] --> - <string name="read_external_dictionary_confirm_install_message">Really install this file for <xliff:g id="LANGUAGE_NAME" example="English">%s</xliff:g>?</string> - <!-- Title for an error dialog that contains the details of the error in the body [CHAR LIMIT=80] --> - <string name="read_external_dictionary_error">There was an error</string> <!-- Title of the settings group for dumpping dictionary files that have been created on the device [CHAR LIMIT=35] --> <string name="prefs_dump_dynamic_dicts">Dump dictionary</string> </resources> diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml index 54579f2d6..5655a5529 100644 --- a/java/res/values/strings.xml +++ b/java/res/values/strings.xml @@ -62,9 +62,9 @@ <string name="cloud_sync_summary_disabled">Sync your personal dictionary across devices</string> <!-- Option title for starting the sync cycle now. [CHAR LIMIT=33]--> <string name="sync_now_title">Sync now</string> - <!-- Option title for letting user delete data from Google servers. [CHAR LIMIT=33] --> - <string name="clear_sync_data_title">Delete Keyboard Cloud data</string> - <!-- Option summary for letting user delete data from Google servers. [CHAR LIMIT=65] --> + <!-- Option title for letting user delete synced google keyboard data from Google servers. [CHAR LIMIT=35] --> + <string name="clear_sync_data_title">Delete cloud data</string> + <!-- Option summary for letting user delete synced google keyboard data from Google servers. [CHAR LIMIT=65] --> <string name="clear_sync_data_summary">Deletes your synced data from Google</string> <!-- Text for confirmation dialog box asking user to confirm deletion of cloud data. [CHAR LIMIT=65] --> <string name="clear_sync_data_confirmation">Your synced data will be deleted from the cloud. Are you sure?</string> diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml index 64929adf1..0b0c93e84 100644 --- a/java/res/xml/method.xml +++ b/java/res/xml/method.xml @@ -366,6 +366,7 @@ /> <!-- TODO: This Hinglish keyboard is a preliminary layout. This isn't based on the final specification. --> + <!-- Disabled because there is no LM yet, and this layout does not offer anything different. <subtype android:icon="@drawable/ic_ime_switcher_dark" android:label="@string/subtype_hi_ZZ" android:subtypeId="0x352eb37c" @@ -374,6 +375,7 @@ android:imeSubtypeExtraValue="AsciiCapable,KeyboardLayoutSet=qwerty,EmojiCapable" android:isAsciiCapable="true" /> + --> <subtype android:icon="@drawable/ic_ime_switcher_dark" android:label="@string/subtype_generic" android:subtypeId="0x35b7526a" diff --git a/java/res/xml/prefs_screen_debug.xml b/java/res/xml/prefs_screen_debug.xml index 905bc045c..1ae2d0e9f 100644 --- a/java/res/xml/prefs_screen_debug.xml +++ b/java/res/xml/prefs_screen_debug.xml @@ -87,9 +87,6 @@ android:title="@string/prefs_keyboard_height_scale" latin:minValue="50" latin:maxValue="120" /> <!-- percentage --> - <PreferenceScreen - android:key="read_external_dictionary" - android:title="@string/prefs_read_external_dictionary" /> <PreferenceCategory android:key="pref_key_dump_dictionaries" android:title="@string/prefs_dump_dynamic_dicts"> diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 7f4631b2d..9a3ac674e 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -27,7 +27,6 @@ import com.android.inputmethod.latin.common.Constants; import com.android.inputmethod.latin.common.FileUtils; import com.android.inputmethod.latin.common.InputPointers; import com.android.inputmethod.latin.common.StringUtils; -import com.android.inputmethod.latin.define.DecoderSpecificConstants; import com.android.inputmethod.latin.makedict.DictionaryHeader; import com.android.inputmethod.latin.makedict.FormatSpec; import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions; @@ -330,7 +329,9 @@ public final class BinaryDictionary extends Dictionary { if (len > 0) { suggestions.add(new SuggestedWordInfo( new String(session.mOutputCodePoints, start, len), - (int)(session.mOutputScores[j] * weightForLocale), session.mOutputTypes[j], + "" /* prevWordsContext */, + (int)(session.mOutputScores[j] * weightForLocale), + session.mOutputTypes[j], this /* sourceDict */, session.mSpaceIndices[j] /* indexOfTouchPointOfSecondWord */, session.mOutputAutoCommitFirstWordConfidence[0])); diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java index 5f981a009..6b49f9aa6 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java @@ -89,6 +89,24 @@ public interface DictionaryFacilitator { void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable); } + /** + * Called every time {@link LatinIME} starts on a new text field. + * Dot not affect {@link AndroidSpellCheckerService}. + * + * WARNING: The service methods that call start/finish are very spammy. + */ + void onStartInput(); + + /** + * Called every time the {@link LatinIME} finishes with the current text field. + * May be followed by {@link #onStartInput} again in another text field, + * or it may be done for a while. + * Dot not affect {@link AndroidSpellCheckerService}. + * + * WARNING: The service methods that call start/finish are very spammy. + */ + void onFinishInput(); + boolean isActive(); Locale getLocale(); diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java index a59253aad..e5d770aee 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java @@ -202,6 +202,15 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { public DictionaryFacilitatorImpl() { } + @Override + public void onStartInput() { + } + + @Override + public void onFinishInput() { + } + + @Override public boolean isActive() { return mDictionaryGroup.mLocale != null; } diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index fa8fb2028..80daedd50 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -121,8 +121,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { private static boolean needsToMigrateDictionary(final int formatVersion) { // When we bump up the dictionary format version, the old version should be added to here // for supporting migration. Note that native code has to support reading such formats. - return formatVersion == FormatSpec.VERSION4_ONLY_FOR_TESTING - || formatVersion == FormatSpec.VERSION402; + return formatVersion == FormatSpec.VERSION402; } public boolean isValidDictionaryLocked() { diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index a8aeb8795..330be377b 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -792,6 +792,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @SuppressWarnings("deprecation") void onStartInputViewInternal(final EditorInfo editorInfo, final boolean restarting) { super.onStartInputView(editorInfo, restarting); + + mDictionaryFacilitator.onStartInput(); // Switch to the null consumer to handle cases leading to early exit below, for which we // also wouldn't be consuming gesture data. mGestureConsumer = GestureConsumer.NULL_GESTURE_CONSUMER; @@ -970,6 +972,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen void onFinishInputInternal() { super.onFinishInput(); + mDictionaryFacilitator.onFinishInput(); final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); if (mainKeyboardView != null) { mainKeyboardView.closing(); @@ -1383,7 +1386,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public void onUpdateBatchInput(final InputPointers batchPointers) { - mInputLogic.onUpdateBatchInput(mSettings.getCurrent(), batchPointers, mKeyboardSwitcher); + mInputLogic.onUpdateBatchInput(batchPointers); } @Override @@ -1407,7 +1410,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen */ public void onTailBatchInputResultShown(final SuggestedWords suggestedWords) { mGestureConsumer.onImeSuggestionsProcessed(suggestedWords, - mInputLogic.getComposingStart(), mInputLogic.getComposingLength()); + mInputLogic.getComposingStart(), mInputLogic.getComposingLength(), + mDictionaryFacilitator); } // This method must run on the UI Thread. @@ -1537,7 +1541,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen setSuggestedWords(neutralSuggestions); } - // TODO: Make this private // Outside LatinIME, only used by the {@link InputTestsBase} test suite. @UsedForTesting void loadKeyboard() { @@ -1768,7 +1771,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen dialog.show(); } - // TODO: can this be removed somehow without breaking the tests? @UsedForTesting SuggestedWords getSuggestedWordsForTest() { // You may not use this method for anything else than debug diff --git a/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java index c9b6d6b70..e2c562174 100644 --- a/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java +++ b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java @@ -114,7 +114,8 @@ public final class PunctuationSuggestions extends SuggestedWords { } private static SuggestedWordInfo newHardCodedWordInfo(final String keySpec) { - return new SuggestedWordInfo(keySpec, SuggestedWordInfo.MAX_SCORE, + return new SuggestedWordInfo(keySpec, "" /* prevWordsContext */, + SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_HARDCODED, Dictionary.DICTIONARY_HARDCODED, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 8562acd83..7ccefd2dd 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -36,7 +36,6 @@ import java.util.HashMap; import java.util.Locale; import javax.annotation.Nonnull; -import javax.annotation.Nullable; /** * This class loads a dictionary and provides a list of suggestions for a given sequence of @@ -249,7 +248,8 @@ public final class Suggest { } final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo(typedWordString, - SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED, + "" /* prevWordsContext */, SuggestedWordInfo.MAX_SCORE, + SuggestedWordInfo.KIND_TYPED, null == sourceDictionaryOfRemovedWord ? Dictionary.DICTIONARY_USER_TYPED : sourceDictionaryOfRemovedWord, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, @@ -426,7 +426,8 @@ public final class Suggest { for (int i = quotesToAppend - 1; i >= 0; --i) { sb.appendCodePoint(Constants.CODE_SINGLE_QUOTE); } - return new SuggestedWordInfo(sb.toString(), wordInfo.mScore, wordInfo.mKindAndFlags, + return new SuggestedWordInfo(sb.toString(), wordInfo.mPrevWordsContext, + wordInfo.mScore, wordInfo.mKindAndFlags, wordInfo.mSourceDict, wordInfo.mIndexOfTouchPointOfSecondWord, wordInfo.mAutoCommitFirstWordConfidence); } diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index 87fe29159..bcd4d5f69 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -17,11 +17,9 @@ package com.android.inputmethod.latin; import android.text.TextUtils; -import android.util.Log; import android.view.inputmethod.CompletionInfo; import com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.common.Constants; import com.android.inputmethod.latin.common.StringUtils; import com.android.inputmethod.latin.define.DebugFlags; @@ -264,6 +262,7 @@ public class SuggestedWords { public static final int KIND_FLAG_APPROPRIATE_FOR_AUTO_CORRECTION = 0x10000000; public final String mWord; + public final String mPrevWordsContext; // The completion info from the application. Null for suggestions that don't come from // the application (including keyboard-computed ones, so this is almost always null) public final CompletionInfo mApplicationSpecifiedCompletionInfo; @@ -284,6 +283,7 @@ public class SuggestedWords { /** * Create a new suggested word info. * @param word The string to suggest. + * @param prevWordsContext previous words context. * @param score A measure of how likely this suggestion is. * @param kindAndFlags The kind of suggestion, as one of the above KIND_* constants with * flags. @@ -291,10 +291,12 @@ public class SuggestedWords { * @param indexOfTouchPointOfSecondWord See mIndexOfTouchPointOfSecondWord. * @param autoCommitFirstWordConfidence See mAutoCommitFirstWordConfidence. */ - public SuggestedWordInfo(final String word, final int score, final int kindAndFlags, + public SuggestedWordInfo(final String word, final String prevWordsContext, + final int score, final int kindAndFlags, final Dictionary sourceDict, final int indexOfTouchPointOfSecondWord, final int autoCommitFirstWordConfidence) { mWord = word; + mPrevWordsContext = prevWordsContext; mApplicationSpecifiedCompletionInfo = null; mScore = score; mKindAndFlags = kindAndFlags; @@ -311,6 +313,7 @@ public class SuggestedWords { */ public SuggestedWordInfo(final CompletionInfo applicationSpecifiedCompletion) { mWord = applicationSpecifiedCompletion.getText().toString(); + mPrevWordsContext = ""; mApplicationSpecifiedCompletionInfo = applicationSpecifiedCompletion; mScore = SuggestedWordInfo.MAX_SCORE; mKindAndFlags = SuggestedWordInfo.KIND_APP_DEFINED; @@ -429,27 +432,6 @@ public class SuggestedWords { return isPrediction(mInputStyle); } - // Creates a new SuggestedWordInfo from the currently suggested words that removes all but the - // last word of all suggestions, separated by a space. This is necessary because when we commit - // a multiple-word suggestion, the IME only retains the last word as the composing word, and - // we should only suggest replacements for this last word. - // TODO: make this work with languages without spaces. - public SuggestedWords getSuggestedWordsForLastWordOfPhraseGesture() { - final ArrayList<SuggestedWordInfo> newSuggestions = new ArrayList<>(); - for (int i = 0; i < mSuggestedWordInfoList.size(); ++i) { - final SuggestedWordInfo info = mSuggestedWordInfoList.get(i); - final int indexOfLastSpace = info.mWord.lastIndexOf(Constants.CODE_SPACE) + 1; - final String lastWord = info.mWord.substring(indexOfLastSpace); - newSuggestions.add(new SuggestedWordInfo(lastWord, info.mScore, info.mKindAndFlags, - info.mSourceDict, SuggestedWordInfo.NOT_AN_INDEX, - SuggestedWordInfo.NOT_A_CONFIDENCE)); - } - return new SuggestedWords(newSuggestions, null /* rawSuggestions */, - newSuggestions.isEmpty() ? null : newSuggestions.get(0) /* typedWordInfo */, - mTypedWordValid, mWillAutoCorrect, mIsObsoleteSuggestions, INPUT_STYLE_TAIL_BATCH, - NOT_A_SEQUENCE_NUMBER); - } - /** * @return the {@link SuggestedWordInfo} which corresponds to the word that is originally * typed by the user. Otherwise returns {@code null}. Note that gesture input is not diff --git a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java b/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java deleted file mode 100644 index 8cc3552ed..000000000 --- a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java +++ /dev/null @@ -1,189 +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.debug; - -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnCancelListener; -import android.content.DialogInterface.OnClickListener; -import android.os.Environment; - -import com.android.inputmethod.latin.BinaryDictionaryFileDumper; -import com.android.inputmethod.latin.BinaryDictionaryGetter; -import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.common.LocaleUtils; -import com.android.inputmethod.latin.makedict.DictionaryHeader; -import com.android.inputmethod.latin.utils.DialogUtils; -import com.android.inputmethod.latin.utils.DictionaryInfoUtils; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Locale; - -/** - * A class to read a local file as a dictionary for debugging purposes. - */ -public class ExternalDictionaryGetterForDebug { - static final String SOURCE_FOLDER = Environment.getExternalStorageDirectory().getPath() - + "/Download"; - - private static String[] findDictionariesInTheDownloadedFolder() { - final File[] files = new File(SOURCE_FOLDER).listFiles(); - final ArrayList<String> eligibleList = new ArrayList<>(); - for (File f : files) { - final DictionaryHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(f); - if (null == header) continue; - eligibleList.add(f.getName()); - } - return eligibleList.toArray(new String[0]); - } - - public static void chooseAndInstallDictionary(final Context context) { - final String[] fileNames = findDictionariesInTheDownloadedFolder(); - if (0 == fileNames.length) { - showNoFileDialog(context); - } else if (1 == fileNames.length) { - askInstallFile(context, SOURCE_FOLDER, fileNames[0], null /* completeRunnable */); - } else { - showChooseFileDialog(context, fileNames); - } - } - - private static void showNoFileDialog(final Context context) { - new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context)) - .setMessage(R.string.read_external_dictionary_no_files_message) - .setPositiveButton(android.R.string.ok, new OnClickListener() { - @Override - public void onClick(final DialogInterface dialog, final int which) { - dialog.dismiss(); - } - }).create().show(); - } - - private static void showChooseFileDialog(final Context context, final String[] fileNames) { - new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context)) - .setTitle(R.string.read_external_dictionary_multiple_files_title) - .setItems(fileNames, new OnClickListener() { - @Override - public void onClick(final DialogInterface dialog, final int which) { - askInstallFile(context, SOURCE_FOLDER, fileNames[which], - null /* completeRunnable */); - } - }) - .create().show(); - } - - /** - * Shows a dialog which offers the user to install the external dictionary. - */ - public static void askInstallFile(final Context context, final String dirPath, - final String fileName, final Runnable completeRunnable) { - final File file = new File(dirPath, fileName.toString()); - final DictionaryHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(file); - final StringBuilder message = new StringBuilder(); - final String localeString = header.mLocaleString; - for (final String key : header.mDictionaryOptions.mAttributes.keySet()) { - message.append(key + " = " + header.mDictionaryOptions.mAttributes.get(key)); - message.append("\n"); - } - final String languageName = LocaleUtils.constructLocaleFromString(localeString) - .getDisplayName(Locale.getDefault()); - final String title = String.format( - context.getString(R.string.read_external_dictionary_confirm_install_message), - languageName); - new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context)) - .setTitle(title) - .setMessage(message) - .setNegativeButton(android.R.string.cancel, new OnClickListener() { - @Override - public void onClick(final DialogInterface dialog, final int which) { - dialog.dismiss(); - if (completeRunnable != null) { - completeRunnable.run(); - } - } - }).setPositiveButton(android.R.string.ok, new OnClickListener() { - @Override - public void onClick(final DialogInterface dialog, final int which) { - installFile(context, file, header); - dialog.dismiss(); - if (completeRunnable != null) { - completeRunnable.run(); - } - } - }).setOnCancelListener(new OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - // Canceled by the user by hitting the back key - if (completeRunnable != null) { - completeRunnable.run(); - } - } - }).create().show(); - } - - static void installFile(final Context context, final File file, final DictionaryHeader header) { - BufferedOutputStream outputStream = null; - File tempFile = null; - try { - final String localeString = header.mLocaleString; - // Create the id for a main dictionary for this locale - final String id = BinaryDictionaryGetter.MAIN_DICTIONARY_CATEGORY - + BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR + localeString; - final String finalFileName = DictionaryInfoUtils.getCacheFileName( - id, localeString, context); - final String tempFileName = BinaryDictionaryGetter.getTempFileName(id, context); - tempFile = new File(tempFileName); - tempFile.delete(); - outputStream = new BufferedOutputStream(new FileOutputStream(tempFile)); - final BufferedInputStream bufferedStream = new BufferedInputStream( - new FileInputStream(file)); - BinaryDictionaryFileDumper.checkMagicAndCopyFileTo(bufferedStream, outputStream); - outputStream.flush(); - final File finalFile = new File(finalFileName); - finalFile.delete(); - if (!tempFile.renameTo(finalFile)) { - throw new IOException("Can't move the file to its final name"); - } - } catch (IOException e) { - // There was an error: show a dialog - new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context)) - .setTitle(R.string.read_external_dictionary_error) - .setMessage(e.toString()) - .setPositiveButton(android.R.string.ok, new OnClickListener() { - @Override - public void onClick(final DialogInterface dialog, final int which) { - dialog.dismiss(); - } - }).create().show(); - return; - } finally { - try { - if (null != outputStream) outputStream.close(); - if (null != tempFile) tempFile.delete(); - } catch (IOException e) { - // Don't do anything - } - } - } -} diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index 00175f024..5b3b28d75 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -225,9 +225,7 @@ public final class InputLogic { * @return the complete transaction object */ public InputTransaction onTextInput(final SettingsValues settingsValues, final Event event, - final int keyboardShiftMode, - // TODO: remove this argument - final LatinIME.UIHandler handler) { + final int keyboardShiftMode, final LatinIME.UIHandler handler) { final String rawText = event.getTextToCommit().toString(); final InputTransaction inputTransaction = new InputTransaction(settingsValues, event, SystemClock.uptimeMillis(), mSpaceState, @@ -266,12 +264,14 @@ public final class InputLogic { // interface public InputTransaction onPickSuggestionManually(final SettingsValues settingsValues, final SuggestedWordInfo suggestionInfo, final int keyboardShiftState, - // TODO: remove these arguments final int currentKeyboardScriptId, final LatinIME.UIHandler handler) { final SuggestedWords suggestedWords = mSuggestedWords; final String suggestion = suggestionInfo.mWord; // If this is a punctuation picked from the suggestion strip, pass it to onCodeInput if (suggestion.length() == 1 && suggestedWords.isPunctuationSuggestions()) { + // We still want to log a suggestion click. + StatsUtils.onPickSuggestionManually( + mSuggestedWords, suggestionInfo, mDictionaryFacilitator); // Word separators are suggested before the user inputs something. // Rely on onCodeInput to do the complicated swapping/stripping logic consistently. final Event event = Event.createPunctuationSuggestionPickedEvent(suggestionInfo); @@ -419,7 +419,6 @@ public final class InputLogic { */ public InputTransaction onCodeInput(final SettingsValues settingsValues, @Nonnull final Event event, final int keyboardShiftMode, - // TODO: remove these arguments final int currentKeyboardScriptId, final LatinIME.UIHandler handler) { final Event processedEvent = mWordComposer.processEvent(event); final InputTransaction inputTransaction = new InputTransaction(settingsValues, @@ -466,7 +465,6 @@ public final class InputLogic { } public void onStartBatchInput(final SettingsValues settingsValues, - // TODO: remove these arguments final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler) { mInputLogicHandler.onStartBatchInput(); handler.showGesturePreviewAndSuggestionStrip( @@ -530,10 +528,7 @@ public final class InputLogic { * earlier sequence number. */ private int mAutoCommitSequenceNumber = 1; - public void onUpdateBatchInput(final SettingsValues settingsValues, - final InputPointers batchPointers, - // TODO: remove these arguments - final KeyboardSwitcher keyboardSwitcher) { + public void onUpdateBatchInput(final InputPointers batchPointers) { mInputLogicHandler.onUpdateBatchInput(batchPointers, mAutoCommitSequenceNumber); } @@ -542,7 +537,6 @@ public final class InputLogic { ++mAutoCommitSequenceNumber; } - // TODO: remove this argument public void onCancelBatchInput(final LatinIME.UIHandler handler) { mInputLogicHandler.onCancelBatchInput(); handler.showGesturePreviewAndSuggestionStrip( @@ -618,7 +612,6 @@ public final class InputLogic { * @param inputTransaction The transaction in progress. */ private void handleFunctionalEvent(final Event event, final InputTransaction inputTransaction, - // TODO: remove these arguments final int currentKeyboardScriptId, final LatinIME.UIHandler handler) { switch (event.mKeyCode) { case Constants.CODE_DELETE: @@ -670,7 +663,6 @@ public final class InputLogic { // handled in {@link KeyboardState#onEvent(Event,int)}. break; case Constants.CODE_SHIFT_ENTER: - // TODO: remove this object final Event tmpEvent = Event.createSoftwareKeypressEvent(Constants.CODE_ENTER, event.mKeyCode, event.mX, event.mY, event.isKeyRepeat()); handleNonSpecialCharacterEvent(tmpEvent, inputTransaction, handler); @@ -694,7 +686,6 @@ public final class InputLogic { */ private void handleNonFunctionalEvent(final Event event, final InputTransaction inputTransaction, - // TODO: remove this argument final LatinIME.UIHandler handler) { inputTransaction.setDidAffectContents(); switch (event.mCodePoint) { @@ -740,7 +731,6 @@ public final class InputLogic { */ private void handleNonSpecialCharacterEvent(final Event event, final InputTransaction inputTransaction, - // TODO: remove this argument final LatinIME.UIHandler handler) { final int codePoint = event.mCodePoint; mSpaceState = SpaceState.NONE; @@ -846,7 +836,6 @@ public final class InputLogic { * @param inputTransaction The transaction in progress. */ private void handleSeparatorEvent(final Event event, final InputTransaction inputTransaction, - // TODO: remove this argument final LatinIME.UIHandler handler) { final int codePoint = event.mCodePoint; final SettingsValues settingsValues = inputTransaction.mSettingsValues; @@ -954,7 +943,6 @@ public final class InputLogic { * @param inputTransaction The transaction in progress. */ private void handleBackspaceEvent(final Event event, final InputTransaction inputTransaction, - // TODO: remove this argument, put it into settingsValues final int currentKeyboardScriptId) { mSpaceState = SpaceState.NONE; mDeleteCount++; @@ -1158,7 +1146,6 @@ public final class InputLogic { settingsValues.mSpacingAndPunctuations, currentKeyboardScriptId); if (range == null) { - // TODO(zivkovic): Check for bad connection before getting this far. // Happens if we don't have an input connection at all. return false; } @@ -1408,7 +1395,8 @@ public final class InputLogic { public void onGetSuggestedWords(final SuggestedWords suggestedWords) { final String typedWordString = mWordComposer.getTypedWord(); final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo( - typedWordString, SuggestedWordInfo.MAX_SCORE, + typedWordString, "" /* prevWordsContext */, + SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, SuggestedWordInfo.NOT_A_CONFIDENCE); @@ -1441,7 +1429,6 @@ public final class InputLogic { * to a cursor move, for example). In ICS, there is a platform bug that we need to work * around only when we come here at input start time. */ - // TODO: make this private. public void restartSuggestionsOnWordTouchedByCursor(final SettingsValues settingsValues, final boolean forStartInput, // TODO: remove this argument, put it into settingsValues @@ -1492,7 +1479,7 @@ public final class InputLogic { final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<>(); final String typedWordString = range.mWord.toString(); final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo(typedWordString, - SuggestedWords.MAX_SUGGESTIONS + 1, + "" /* prevWordsContext */, SuggestedWords.MAX_SUGGESTIONS + 1, SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */); @@ -1507,7 +1494,7 @@ public final class InputLogic { ++i; if (!TextUtils.equals(s, typedWordString)) { suggestions.add(new SuggestedWordInfo(s, - SuggestedWords.MAX_SUGGESTIONS - i, + "" /* prevWordsContext */, SuggestedWords.MAX_SUGGESTIONS - i, SuggestedWordInfo.KIND_RESUMED, Dictionary.DICTIONARY_RESUMED, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, SuggestedWordInfo.NOT_A_CONFIDENCE @@ -1721,7 +1708,6 @@ public final class InputLogic { * @param nthPreviousWord reverse index of the word to get (1-indexed) * @return the information of previous words */ - // TODO: Make this private public NgramContext getNgramContextFromNthPreviousWordForSuggestion( final SpacingAndPunctuations spacingAndPunctuations, final int nthPreviousWord) { if (spacingAndPunctuations.mCurrentLanguageHasSpaces) { @@ -1951,9 +1937,7 @@ public final class InputLogic { * @param suggestedWords suggestedWords to use. */ public void onUpdateTailBatchInputCompleted(final SettingsValues settingsValues, - final SuggestedWords suggestedWords, - // TODO: remove this argument - final KeyboardSwitcher keyboardSwitcher) { + final SuggestedWords suggestedWords, final KeyboardSwitcher keyboardSwitcher) { final String batchInputText = suggestedWords.isEmpty() ? null : suggestedWords.getWord(0); if (TextUtils.isEmpty(batchInputText)) { return; @@ -1986,7 +1970,6 @@ public final class InputLogic { * @param settingsValues the current values of the settings. * @param separatorString the separator that's causing the commit, or NOT_A_SEPARATOR if none. */ - // TODO: Make this private public void commitTyped(final SettingsValues settingsValues, final String separatorString) { if (!mWordComposer.isComposingWord()) return; final String typedWord = mWordComposer.getTypedWord(); @@ -2015,9 +1998,7 @@ public final class InputLogic { * @param separator the separator that's causing the commit to happen. */ private void commitCurrentAutoCorrection(final SettingsValues settingsValues, - final String separator, - // TODO: Remove this argument. - final LatinIME.UIHandler handler) { + final String separator, final LatinIME.UIHandler handler) { // Complete any pending suggestions query first if (handler.hasPendingUpdateSuggestions()) { handler.cancelUpdateSuggestionStrip(); @@ -2053,8 +2034,11 @@ public final class InputLogic { mConnection.commitCorrection(new CorrectionInfo( mConnection.getExpectedSelectionEnd() - stringToCommit.length(), typedWord, stringToCommit)); + String prevWordsContext = (autoCorrectionOrNull != null) + ? autoCorrectionOrNull.mPrevWordsContext + : ""; StatsUtils.onAutoCorrection(typedWord, stringToCommit, isBatchMode, - mDictionaryFacilitator); + mDictionaryFacilitator, prevWordsContext); StatsUtils.onWordCommitAutoCorrect(stringToCommit, isBatchMode); } else { StatsUtils.onWordCommitUserTyped(stringToCommit, isBatchMode); @@ -2103,11 +2087,8 @@ public final class InputLogic { * @param remainingTries How many times we may try again before giving up. * @return whether true if the caches were successfully reset, false otherwise. */ - // TODO: make this private public boolean retryResetCachesAndReturnSuccess(final boolean tryResumeSuggestions, - final int remainingTries, - // TODO: remove these arguments - final LatinIME.UIHandler handler) { + final int remainingTries, final LatinIME.UIHandler handler) { final boolean shouldFinishComposition = mConnection.hasSelection() || !mConnection.isCursorPositionKnown(); if (!mConnection.resetCachesUponCursorMoveAndReturnSuccess( diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java index 288261bf0..e422c4cd2 100644 --- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java +++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java @@ -174,9 +174,6 @@ public final class FormatSpec { public static final int VERSION202 = 202; // format version for Fava Dictionaries. public static final int VERSION_DELIGHT3 = 86736212; - public static final int MINIMUM_SUPPORTED_VERSION_OF_CODE_POINT_TABLE = VERSION201; - // Dictionary version used for testing. - public static final int VERSION4_ONLY_FOR_TESTING = 399; public static final int VERSION402 = 402; public static final int VERSION403 = 403; public static final int VERSION4 = VERSION403; diff --git a/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java index 48361bf8c..39dcddb95 100644 --- a/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java @@ -132,7 +132,7 @@ public final class AccountsSettingsFragment extends SubScreenFragment { @Override protected Void doInBackground(Void... params) { - if (ManagedProfileUtils.getInstance().hasManagedWorkProfile(mFragment.getActivity())) { + if (ManagedProfileUtils.getInstance().hasWorkProfile(mFragment.getActivity())) { mFragment.removeSyncPreferences(); } else { mFragment.enableSyncPreferences(); diff --git a/java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java index f7c5f6760..62834cd2a 100644 --- a/java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java @@ -49,7 +49,7 @@ import java.util.TreeSet; */ public final class CorrectionSettingsFragment extends SubScreenFragment { private static final boolean DBG_USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS = false; - private static final boolean USE_INTERNAL_PERSONAL_DICTIONARY_SETTIGS = + private static final boolean USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS = DBG_USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS || Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2; @@ -61,8 +61,6 @@ public final class CorrectionSettingsFragment extends SubScreenFragment { final Context context = getActivity(); final PackageManager pm = context.getPackageManager(); - ensureConsistencyOfAutoCorrectionSettings(); - final Preference dictionaryLink = findPreference(Settings.PREF_CONFIGURE_DICTIONARIES_KEY); final Intent intent = dictionaryLink.getIntent(); intent.setClassName(context.getPackageName(), DictionarySettingsActivity.class.getName()); @@ -74,7 +72,7 @@ public final class CorrectionSettingsFragment extends SubScreenFragment { final Preference editPersonalDictionary = findPreference(Settings.PREF_EDIT_PERSONAL_DICTIONARY); final Intent editPersonalDictionaryIntent = editPersonalDictionary.getIntent(); - final ResolveInfo ri = USE_INTERNAL_PERSONAL_DICTIONARY_SETTIGS ? null + final ResolveInfo ri = USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS ? null : pm.resolveActivity( editPersonalDictionaryIntent, PackageManager.MATCH_DEFAULT_ONLY); if (ri == null) { @@ -82,19 +80,6 @@ public final class CorrectionSettingsFragment extends SubScreenFragment { } } - @Override - public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) { - ensureConsistencyOfAutoCorrectionSettings(); - } - - private void ensureConsistencyOfAutoCorrectionSettings() { - final TwoStatePreference autoCorrectionPref = (TwoStatePreference) - findPreference(Settings.PREF_AUTO_CORRECTION); - if (!autoCorrectionPref.isChecked()) { - setPreferenceEnabled(Settings.PREF_BIGRAM_PREDICTIONS, false); - } - } - private void overwriteUserDictionaryPreference(final Preference userDictionaryPreference) { final Activity activity = getActivity(); final TreeSet<String> localeList = UserDictionaryList.getUserDictionaryLocalesSet(activity); diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java index a56de1f69..37855377d 100644 --- a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java @@ -30,7 +30,6 @@ import android.preference.TwoStatePreference; import com.android.inputmethod.latin.DictionaryDumpBroadcastReceiver; import com.android.inputmethod.latin.DictionaryFacilitatorImpl; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.debug.ExternalDictionaryGetterForDebug; import com.android.inputmethod.latin.utils.ApplicationUtils; import com.android.inputmethod.latin.utils.ResourceUtils; @@ -43,12 +42,10 @@ import java.util.Locale; */ public final class DebugSettingsFragment extends SubScreenFragment implements OnPreferenceClickListener { - private static final String PREF_READ_EXTERNAL_DICTIONARY = "read_external_dictionary"; private static final String PREF_KEY_DUMP_DICTS = "pref_key_dump_dictionaries"; private static final String PREF_KEY_DUMP_DICT_PREFIX = "pref_key_dump_dictionaries"; private boolean mServiceNeedsRestart = false; - private Preference mReadExternalDictionaryPref; private TwoStatePreference mDebugMode; @Override @@ -60,11 +57,6 @@ public final class DebugSettingsFragment extends SubScreenFragment removePreference(DebugSettings.PREF_SHOULD_SHOW_LXX_SUGGESTION_UI); } - mReadExternalDictionaryPref = findPreference(PREF_READ_EXTERNAL_DICTIONARY); - if (mReadExternalDictionaryPref != null) { - mReadExternalDictionaryPref.setOnPreferenceClickListener(this); - } - final PreferenceGroup dictDumpPreferenceGroup = (PreferenceGroup)findPreference(PREF_KEY_DUMP_DICTS); for (final String dictName : DictionaryFacilitatorImpl.DICT_TYPE_TO_CLASS.keySet()) { @@ -111,11 +103,6 @@ public final class DebugSettingsFragment extends SubScreenFragment @Override public boolean onPreferenceClick(final Preference pref) { final Context context = getActivity(); - if (pref == mReadExternalDictionaryPref) { - ExternalDictionaryGetterForDebug.chooseAndInstallDictionary(context); - mServiceNeedsRestart = true; - return true; - } if (pref instanceof DictDumpPreference) { final DictDumpPreference dictDumpPref = (DictDumpPreference)pref; final String dictName = dictDumpPref.mDictName; diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java index b98c53af4..f5455e3db 100644 --- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java @@ -16,10 +16,12 @@ package com.android.inputmethod.latin.settings; +import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.preference.Preference; import android.preference.PreferenceScreen; +import android.provider.Settings.Secure; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -68,13 +70,23 @@ public final class SettingsFragment extends InputMethodSettingsFragment { @Override public boolean onOptionsItemSelected(final MenuItem item) { + final Activity activity = getActivity(); + final int setupStatus = Secure.getInt( + activity.getContentResolver(), + "user_setup_complete", + 0 /* default */); + if (setupStatus == 0) { + // If setup is not complete, it's not safe to launch Help or other activities + // because they might go to the Play Store. See b/19866981. + return true; + } final int itemId = item.getItemId(); if (itemId == MENU_HELP_AND_FEEDBACK) { - FeedbackUtils.showHelpAndFeedbackForm(getActivity()); + FeedbackUtils.showHelpAndFeedbackForm(activity); return true; } if (itemId == MENU_ABOUT) { - final Intent aboutIntent = FeedbackUtils.getAboutKeyboardIntent(getActivity()); + final Intent aboutIntent = FeedbackUtils.getAboutKeyboardIntent(activity); if (aboutIntent != null) { startActivity(aboutIntent); return true; diff --git a/java/src/com/android/inputmethod/latin/utils/ManagedProfileUtils.java b/java/src/com/android/inputmethod/latin/utils/ManagedProfileUtils.java deleted file mode 100644 index 1bd8f314c..000000000 --- a/java/src/com/android/inputmethod/latin/utils/ManagedProfileUtils.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.inputmethod.latin.utils; - -import android.annotation.TargetApi; -import android.content.Context; -import android.os.Build; -import android.os.UserHandle; -import android.os.UserManager; -import android.util.Log; - -import com.android.inputmethod.annotations.UsedForTesting; - -import java.util.List; - -/** - * Utility for determining if the device has managed profiles. - */ -public class ManagedProfileUtils { - private static final boolean DEBUG = false; - private static final String TAG = ManagedProfileUtils.class.getSimpleName(); - - private static ManagedProfileUtils INSTANCE = new ManagedProfileUtils(); - private static ManagedProfileUtils sTestInstance; - - private ManagedProfileUtils() { - // This utility class is not publicly instantiable. - } - - @UsedForTesting - public static void setTestInstance(final ManagedProfileUtils testInstance) { - sTestInstance = testInstance; - } - - public static ManagedProfileUtils getInstance() { - return sTestInstance == null ? INSTANCE : sTestInstance; - } - - /** - * Note that {@link UserManager#getUserProfiles} has been introduced - * in API level 21 (Build.VERSION_CODES.LOLLIPOP). - */ - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public boolean hasManagedWorkProfile(final Context context) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - return false; - } - - final UserManager userManagerService = - (UserManager) context.getSystemService(Context.USER_SERVICE); - if (userManagerService != null) { - if (DEBUG) { - Log.d(TAG, "Detecting managed profile..."); - } - final List<UserHandle> userProfiles = userManagerService.getUserProfiles(); - if (userProfiles.size() > 1) { - if (DEBUG) { - Log.d(TAG, "More than one user profile => Managed profile exists."); - } - return true; - } - } - if (DEBUG) { - Log.d(TAG, "Managed profile not detected."); - } - return false; - } -} diff --git a/tests/src/com/android/inputmethod/compat/SuggestionSpanUtilsTest.java b/tests/src/com/android/inputmethod/compat/SuggestionSpanUtilsTest.java index 7bbf965f9..daf412cc3 100644 --- a/tests/src/com/android/inputmethod/compat/SuggestionSpanUtilsTest.java +++ b/tests/src/com/android/inputmethod/compat/SuggestionSpanUtilsTest.java @@ -42,7 +42,8 @@ public class SuggestionSpanUtilsTest extends AndroidTestCase { * @return a new instance of {@link SuggestedWordInfo}. */ private static SuggestedWordInfo createWordInfo(final String word, final int kindAndFlags) { - return new SuggestedWordInfo(word, 1 /* score */, kindAndFlags, null /* sourceDict */, + return new SuggestedWordInfo(word, "" /* prevWordsContext */, 1 /* score */, kindAndFlags, + null /* sourceDict */, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/KeyboardLayoutSetSubtypesCountTests.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/KeyboardLayoutSetSubtypesCountTests.java index 3a8d19d08..87f2f3011 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/KeyboardLayoutSetSubtypesCountTests.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/KeyboardLayoutSetSubtypesCountTests.java @@ -27,8 +27,8 @@ import java.util.ArrayList; @SmallTest public class KeyboardLayoutSetSubtypesCountTests extends KeyboardLayoutSetTestsBase { - private static final int NUMBER_OF_SUBTYPES = 82; - private static final int NUMBER_OF_ASCII_CAPABLE_SUBTYPES = 50; + private static final int NUMBER_OF_SUBTYPES = 81; + private static final int NUMBER_OF_ASCII_CAPABLE_SUBTYPES = 49; private static final int NUMBER_OF_PREDEFINED_ADDITIONAL_SUBTYPES = 2; @Override diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHinglish.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHinglish.java index 613b3bbc2..a8e872316 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHinglish.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHinglish.java @@ -16,7 +16,7 @@ package com.android.inputmethod.keyboard.layout.tests; -import android.test.suitebuilder.annotation.SmallTest; +import android.test.suitebuilder.annotation.Suppress; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Qwerty; @@ -30,7 +30,7 @@ import java.util.Locale; /* * hi_ZZ: Hinglish/qwerty */ -@SmallTest +@Suppress public final class TestsHinglish extends LayoutTestsBase { private static final Locale LOCALE = new Locale("hi", "ZZ"); private static final LayoutBase LAYOUT = new Qwerty(new HinglishCustomizer(LOCALE)); diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java index 89167f744..e96c934cb 100644 --- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java +++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java @@ -42,14 +42,8 @@ import java.util.Random; public class BinaryDictionaryTests extends AndroidTestCase { private static final String TEST_DICT_FILE_EXTENSION = ".testDict"; private static final String TEST_LOCALE = "test"; - private static final int[] DICT_FORMAT_VERSIONS = - new int[] { FormatSpec.VERSION402, FormatSpec.VERSION403 }; private static final String DICTIONARY_ID = "TestBinaryDictionary"; - private static boolean supportsNgram(final int formatVersion) { - return formatVersion >= FormatSpec.VERSION403; - } - private HashSet<File> mDictFilesToBeDeleted = new HashSet<>(); @Override @@ -113,13 +107,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testIsValidDictionary() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testIsValidDictionary(formatVersion); - } - } - - private void testIsValidDictionary(final int formatVersion) { - final File dictFile = createEmptyDictionaryAndGetFile(formatVersion); + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); assertTrue("binaryDictionary must be valid for existing valid dictionary file.", binaryDictionary.isValidDictionary()); @@ -134,20 +122,14 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testConstructingDictionaryOnMemory() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testConstructingDictionaryOnMemory(formatVersion); - } - } - - private void testConstructingDictionaryOnMemory(final int formatVersion) { - final File dictFile = createEmptyDictionaryAndGetFile(formatVersion); + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); FileUtils.deleteRecursively(dictFile); assertFalse(dictFile.exists()); final BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), - true /* useFullEditDistance */, Locale.getDefault(), TEST_LOCALE, formatVersion, - new HashMap<String, String>()); + true /* useFullEditDistance */, Locale.getDefault(), TEST_LOCALE, + FormatSpec.VERSION403, new HashMap<String, String>()); assertTrue(binaryDictionary.isValidDictionary()); - assertEquals(formatVersion, binaryDictionary.getFormatVersion()); + assertEquals(FormatSpec.VERSION403, binaryDictionary.getFormatVersion()); final int probability = 100; addUnigramWord(binaryDictionary, "word", probability); assertEquals(probability, binaryDictionary.getFrequency("word")); @@ -155,19 +137,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { binaryDictionary.flush(); assertTrue(dictFile.exists()); assertTrue(binaryDictionary.isValidDictionary()); - assertEquals(formatVersion, binaryDictionary.getFormatVersion()); + assertEquals(FormatSpec.VERSION403, binaryDictionary.getFormatVersion()); assertEquals(probability, binaryDictionary.getFrequency("word")); binaryDictionary.close(); } public void testAddTooLongWord() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddTooLongWord(formatVersion); - } - } - - private void testAddTooLongWord(final int formatVersion) { - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final StringBuffer stringBuilder = new StringBuffer(); for (int i = 0; i < BinaryDictionary.DICTIONARY_MAX_WORD_LENGTH; i++) { stringBuilder.append('a'); @@ -234,13 +210,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testAddUnigramWord() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddUnigramWord(formatVersion); - } - } - - private void testAddUnigramWord(final int formatVersion) { - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final int probability = 100; addUnigramWord(binaryDictionary, "aaa", probability); // Reallocate and create. @@ -267,16 +237,10 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testRandomlyAddUnigramWord() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testRandomlyAddUnigramWord(formatVersion); - } - } - - private void testRandomlyAddUnigramWord(final int formatVersion) { final int wordCount = 1000; final int codePointSetSize = 50; final long seed = System.currentTimeMillis(); - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final HashMap<String, Integer> probabilityMap = new HashMap<>(); // Test a word that isn't contained within the dictionary. @@ -295,13 +259,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testAddBigramWords() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddBigramWords(formatVersion); - } - } - - private void testAddBigramWords(final int formatVersion) { - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final int unigramProbability = 100; final int bigramProbability = 150; @@ -354,18 +312,12 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testRandomlyAddBigramWords() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testRandomlyAddBigramWords(formatVersion); - } - } - - private void testRandomlyAddBigramWords(final int formatVersion) { final int wordCount = 100; final int bigramCount = 1000; final int codePointSetSize = 50; final long seed = System.currentTimeMillis(); final Random random = new Random(seed); - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final ArrayList<String> words = new ArrayList<>(); final ArrayList<Pair<String, String>> bigramWords = new ArrayList<>(); @@ -406,15 +358,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testAddTrigramWords() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - if (supportsNgram(formatVersion)) { - testAddTrigramWords(formatVersion); - } - } - } - - private void testAddTrigramWords(final int formatVersion) { - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final int unigramProbability = 100; final int trigramProbability = 150; final int updatedTrigramProbability = 200; @@ -440,13 +384,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testFlushDictionary() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testFlushDictionary(formatVersion); - } - } - - private void testFlushDictionary(final int formatVersion) { - final File dictFile = createEmptyDictionaryAndGetFile(formatVersion); + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); final int probability = 100; @@ -480,13 +418,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testFlushWithGCDictionary() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testFlushWithGCDictionary(formatVersion); - } - } - - private void testFlushWithGCDictionary(final int formatVersion) { - final File dictFile = createEmptyDictionaryAndGetFile(formatVersion); + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); final int unigramProbability = 100; final int bigramProbability = 150; @@ -516,20 +448,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testAddBigramWordsAndFlashWithGC() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddBigramWordsAndFlashWithGC(formatVersion); - } - } - - // TODO: Evaluate performance of GC - private void testAddBigramWordsAndFlashWithGC(final int formatVersion) { final int wordCount = 100; final int bigramCount = 1000; final int codePointSetSize = 30; final long seed = System.currentTimeMillis(); final Random random = new Random(seed); - final File dictFile = createEmptyDictionaryAndGetFile(formatVersion); + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); final ArrayList<String> words = new ArrayList<>(); @@ -575,12 +500,6 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testRandomOperationsAndFlashWithGC() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testRandomOperationsAndFlashWithGC(formatVersion); - } - } - - private void testRandomOperationsAndFlashWithGC(final int formatVersion) { final int maxUnigramCount = 5000; final int maxBigramCount = 10000; final HashMap<String, String> attributeMap = new HashMap<>(); @@ -596,7 +515,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { final long seed = System.currentTimeMillis(); final Random random = new Random(seed); - final File dictFile = createEmptyDictionaryWithAttributesAndGetFile(formatVersion, + final File dictFile = createEmptyDictionaryWithAttributesAndGetFile(FormatSpec.VERSION403, attributeMap); BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); @@ -675,19 +594,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testAddManyUnigramsAndFlushWithGC() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddManyUnigramsAndFlushWithGC(formatVersion); - } - } - - private void testAddManyUnigramsAndFlushWithGC(final int formatVersion) { final int flashWithGCIterationCount = 3; final int codePointSetSize = 50; final long seed = System.currentTimeMillis(); final Random random = new Random(seed); - final File dictFile = createEmptyDictionaryAndGetFile(formatVersion); + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); final ArrayList<String> words = new ArrayList<>(); final HashMap<String, Integer> unigramProbabilities = new HashMap<>(); @@ -716,12 +629,6 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testUnigramAndBigramCount() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testUnigramAndBigramCount(formatVersion); - } - } - - private void testUnigramAndBigramCount(final int formatVersion) { final int maxUnigramCount = 5000; final int maxBigramCount = 10000; final HashMap<String, String> attributeMap = new HashMap<>(); @@ -734,7 +641,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { final int bigramCountPerIteration = 2000; final long seed = System.currentTimeMillis(); final Random random = new Random(seed); - final File dictFile = createEmptyDictionaryWithAttributesAndGetFile(formatVersion, + final File dictFile = createEmptyDictionaryWithAttributesAndGetFile(FormatSpec.VERSION403, attributeMap); final ArrayList<String> words = new ArrayList<>(); @@ -778,19 +685,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testGetWordProperties() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testGetWordProperties(formatVersion); - } - } - - private void testGetWordProperties(final int formatVersion) { final long seed = System.currentTimeMillis(); final Random random = new Random(seed); final int UNIGRAM_COUNT = 1000; final int BIGRAM_COUNT = 1000; final int codePointSetSize = 20; final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); - final File dictFile = createEmptyDictionaryAndGetFile(formatVersion); + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); final BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); final WordProperty invalidWordProperty = binaryDictionary.getWordProperty("dummyWord", @@ -869,19 +770,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testIterateAllWords() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testIterateAllWords(formatVersion); - } - } - - private void testIterateAllWords(final int formatVersion) { final long seed = System.currentTimeMillis(); final Random random = new Random(seed); final int UNIGRAM_COUNT = 1000; final int BIGRAM_COUNT = 1000; final int codePointSetSize = 20; final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final WordProperty invalidWordProperty = binaryDictionary.getWordProperty("dummyWord", false /* isBeginningOfSentence */); @@ -965,123 +860,8 @@ public class BinaryDictionaryTests extends AndroidTestCase { assertEquals(true, wordProperty.mIsPossiblyOffensive); } - public void testDictMigration() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testDictMigration(FormatSpec.VERSION4_ONLY_FOR_TESTING, formatVersion); - } - } - - private void testDictMigration(final int fromFormatVersion, final int toFormatVersion) { - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(fromFormatVersion); - final int unigramProbability = 100; - addUnigramWord(binaryDictionary, "aaa", unigramProbability); - addUnigramWord(binaryDictionary, "bbb", unigramProbability); - final int bigramProbability = 150; - addBigramWords(binaryDictionary, "aaa", "bbb", bigramProbability); - binaryDictionary.addUnigramEntry("ccc", unigramProbability, - false /* isBeginningOfSentence */, false /* isNotAWord */, - false /* isPossiblyOffensive */, 0 /* timestamp */); - binaryDictionary.addUnigramEntry("ddd", unigramProbability, - false /* isBeginningOfSentence */, - true /* isNotAWord */, true /* isPossiblyOffensive */, 0 /* timestamp */); - binaryDictionary.addNgramEntry(NgramContext.BEGINNING_OF_SENTENCE, - "aaa", bigramProbability, 0 /* timestamp */); - assertEquals(unigramProbability, binaryDictionary.getFrequency("aaa")); - assertEquals(unigramProbability, binaryDictionary.getFrequency("bbb")); - assertTrue(isValidBigram(binaryDictionary, "aaa", "bbb")); - assertEquals(fromFormatVersion, binaryDictionary.getFormatVersion()); - assertTrue(binaryDictionary.migrateTo(toFormatVersion)); - assertTrue(binaryDictionary.isValidDictionary()); - assertEquals(toFormatVersion, binaryDictionary.getFormatVersion()); - assertEquals(unigramProbability, binaryDictionary.getFrequency("aaa")); - assertEquals(unigramProbability, binaryDictionary.getFrequency("bbb")); - assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "bbb")); - assertEquals(bigramProbability, binaryDictionary.getNgramProbability( - NgramContext.BEGINNING_OF_SENTENCE, "aaa")); - assertTrue(isValidBigram(binaryDictionary, "aaa", "bbb")); - WordProperty wordProperty = binaryDictionary.getWordProperty("ccc", - false /* isBeginningOfSentence */); - wordProperty = binaryDictionary.getWordProperty("ddd", - false /* isBeginningOfSentence */); - assertTrue(wordProperty.mIsPossiblyOffensive); - assertTrue(wordProperty.mIsNotAWord); - } - - public void testLargeDictMigration() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testLargeDictMigration(FormatSpec.VERSION4_ONLY_FOR_TESTING, formatVersion); - } - } - - private void testLargeDictMigration(final int fromFormatVersion, final int toFormatVersion) { - final int UNIGRAM_COUNT = 3000; - final int BIGRAM_COUNT = 3000; - final int codePointSetSize = 50; - final long seed = System.currentTimeMillis(); - final Random random = new Random(seed); - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(fromFormatVersion); - - final ArrayList<String> words = new ArrayList<>(); - final ArrayList<Pair<String, String>> bigrams = new ArrayList<>(); - final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); - final HashMap<String, Integer> unigramProbabilities = new HashMap<>(); - final HashMap<Pair<String, String>, Integer> bigramProbabilities = new HashMap<>(); - - for (int i = 0; i < UNIGRAM_COUNT; i++) { - final String word = CodePointUtils.generateWord(random, codePointSet); - final int unigramProbability = random.nextInt(0xFF); - addUnigramWord(binaryDictionary, word, unigramProbability); - if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { - binaryDictionary.flushWithGC(); - } - words.add(word); - unigramProbabilities.put(word, unigramProbability); - } - - for (int i = 0; i < BIGRAM_COUNT; i++) { - final int word0Index = random.nextInt(words.size()); - final int word1Index = random.nextInt(words.size()); - if (word0Index == word1Index) { - continue; - } - final String word0 = words.get(word0Index); - final String word1 = words.get(word1Index); - final int unigramProbability = unigramProbabilities.get(word1); - final int bigramProbability = - random.nextInt(0xFF - unigramProbability) + unigramProbability; - addBigramWords(binaryDictionary, word0, word1, bigramProbability); - if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { - binaryDictionary.flushWithGC(); - } - final Pair<String, String> bigram = new Pair<>(word0, word1); - bigrams.add(bigram); - bigramProbabilities.put(bigram, bigramProbability); - } - assertTrue(binaryDictionary.migrateTo(toFormatVersion)); - - for (final String word : words) { - assertEquals((int)unigramProbabilities.get(word), binaryDictionary.getFrequency(word)); - } - assertEquals(unigramProbabilities.size(), Integer.parseInt( - binaryDictionary.getPropertyForGettingStats(BinaryDictionary.UNIGRAM_COUNT_QUERY))); - - for (final Pair<String, String> bigram : bigrams) { - assertEquals((int)bigramProbabilities.get(bigram), - getBigramProbability(binaryDictionary, bigram.first, bigram.second)); - assertTrue(isValidBigram(binaryDictionary, bigram.first, bigram.second)); - } - assertEquals(bigramProbabilities.size(), Integer.parseInt( - binaryDictionary.getPropertyForGettingStats(BinaryDictionary.BIGRAM_COUNT_QUERY))); - } - public void testBeginningOfSentence() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testBeginningOfSentence(formatVersion); - } - } - - private void testBeginningOfSentence(final int formatVersion) { - final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(formatVersion); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final int dummyProbability = 0; final NgramContext beginningOfSentenceContext = NgramContext.BEGINNING_OF_SENTENCE; final int bigramProbability = 200; diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTests.java b/tests/src/com/android/inputmethod/latin/InputLogicTests.java index eb94e2266..02cd21c8d 100644 --- a/tests/src/com/android/inputmethod/latin/InputLogicTests.java +++ b/tests/src/com/android/inputmethod/latin/InputLogicTests.java @@ -217,22 +217,45 @@ public class InputLogicTests extends InputTestsBase { } public void testDoubleSpace() { - // Set default pref just in case - setBooleanPreference(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true, true); // U+1F607 is an emoji final String[] STRINGS_TO_TYPE = new String[] { "this ", "a+ ", "\u1F607 ", ".. ", ") ", "( ", "% " }; final String[] EXPECTED_RESULTS = new String[] { "this. ", "a+. ", "\u1F607. ", ".. ", "). ", "( ", "%. " }; - for (int i = 0; i < STRINGS_TO_TYPE.length; ++i) { + verifyDoubleSpace(STRINGS_TO_TYPE, EXPECTED_RESULTS); + } + + public void testDoubleSpaceHindi() { + changeLanguage("hi"); + // U+1F607 is an emoji + final String[] STRINGS_TO_TYPE = + new String[] { "this ", "a+ ", "\u1F607 ", "|| ", ") ", "( ", "% " }; + final String[] EXPECTED_RESULTS = + new String[] { "this| ", "a+| ", "\u1F607| ", "|| ", ")| ", "( ", "%| " }; + verifyDoubleSpace(STRINGS_TO_TYPE, EXPECTED_RESULTS); + } + + private void verifyDoubleSpace(String[] stringsToType, String[] expectedResults) { + // Set default pref just in case + setBooleanPreference(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true, true); + for (int i = 0; i < stringsToType.length; ++i) { mEditText.setText(""); - type(STRINGS_TO_TYPE[i]); - assertEquals("double space processing", EXPECTED_RESULTS[i], + type(stringsToType[i]); + assertEquals("double space processing", expectedResults[i], mEditText.getText().toString()); } } - public void testCancelDoubleSpace() { + public void testCancelDoubleSpaceEnglish() { + final String STRING_TO_TYPE = "this "; + final String EXPECTED_RESULT = "this "; + type(STRING_TO_TYPE); + type(Constants.CODE_DELETE); + assertEquals("double space make a period", EXPECTED_RESULT, mEditText.getText().toString()); + } + + public void testCancelDoubleSpaceHindi() { + changeLanguage("hi"); final String STRING_TO_TYPE = "this "; final String EXPECTED_RESULT = "this "; type(STRING_TO_TYPE); @@ -283,7 +306,7 @@ public class InputLogicTests extends InputTestsBase { setBooleanPreference(Settings.PREF_SHOW_SUGGESTIONS, true, true); setBooleanPreference(Settings.PREF_AUTO_CORRECTION, true, true); setBooleanPreference(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true, true); - testDoubleSpacePeriodWithSettings(true /* expectsPeriod */); + testDoubleSpacePeriodWithSettings(true); // "Suggestion visibility" to off testDoubleSpacePeriodWithSettings(true, Settings.PREF_SHOW_SUGGESTIONS, false); // "Suggestion visibility" to on @@ -463,38 +486,19 @@ public class InputLogicTests extends InputTestsBase { type(" "); helperTestComposing("a'", true); } + // TODO: Add some tests for non-BMP characters public void testAutoCorrectByUserHistory() { - final String WORD_TO_BE_CORRECTED = "qpmx"; - final String NOT_CORRECTED_RESULT = "qpmx "; - final String DESIRED_WORD = "qpmz"; - final String CORRECTED_RESULT = "qpmz "; - final int typeCountNotToAutocorrect = 1; - final int typeCountToAutoCorrect = 16; - int startIndex = 0; - int endIndex = 0; - - for (int i = 0; i < typeCountNotToAutocorrect; i++) { - type(DESIRED_WORD); - type(Constants.CODE_SPACE); - } - startIndex = mEditText.getText().length(); - type(WORD_TO_BE_CORRECTED); + type("qpmz"); type(Constants.CODE_SPACE); - endIndex = mEditText.getText().length(); - assertEquals("not auto-corrected by user history", NOT_CORRECTED_RESULT, - mEditText.getText().subSequence(startIndex, endIndex).toString()); - for (int i = typeCountNotToAutocorrect; i < typeCountToAutoCorrect; i++) { - type(DESIRED_WORD); - type(Constants.CODE_SPACE); - } - startIndex = mEditText.getText().length(); - type(WORD_TO_BE_CORRECTED); + + int startIndex = mEditText.getText().length(); + type("qpmx"); type(Constants.CODE_SPACE); - endIndex = mEditText.getText().length(); + int endIndex = mEditText.getText().length(); assertEquals("auto-corrected by user history", - CORRECTED_RESULT, mEditText.getText().subSequence(startIndex, endIndex).toString()); + "qpmz ", mEditText.getText().subSequence(startIndex, endIndex).toString()); } public void testPredictionsAfterSpace() { @@ -641,31 +645,15 @@ public class InputLogicTests extends InputTestsBase { mEditText.getText().toString()); } - public void testSwitchLanguages() { - final String WORD_TO_TYPE_FIRST_PART = "com"; - final String WORD_TO_TYPE_SECOND_PART = "md"; - final String EXPECTED_RESULT = "comme"; - changeLanguage("en"); - type(WORD_TO_TYPE_FIRST_PART); - changeLanguage("fr"); - runMessages(); - type(WORD_TO_TYPE_SECOND_PART); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); - runMessages(); - final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest(); - assertEquals("Suggestions updated after switching languages", - EXPECTED_RESULT, suggestedWords.size() > 0 ? suggestedWords.getWord(1) : null); - } - public void testBasicGesture() { gesture("this"); - assertEquals("gesture \"this\"", "this", mEditText.getText().toString()); + assertEquals("this", mEditText.getText().toString()); } public void testGestureGesture() { - gesture("this"); - gesture("is"); - assertEquals("gesture \"this is\"", "this is", mEditText.getText().toString()); + gesture("got"); + gesture("milk"); + assertEquals("got milk", mEditText.getText().toString()); } public void testGestureBackspaceGestureAgain() { @@ -694,8 +682,6 @@ public class InputLogicTests extends InputTestsBase { sendUpdateForCursorMoveTo(NEW_CURSOR_POSITION); sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); - ensureComposingSpanPos("move cursor inside word leaves composing span in the right place", - startPos, END_OF_WORD); } private void typeWordAndPutCursorInside(final String word, final int startPos) { @@ -725,7 +711,7 @@ public class InputLogicTests extends InputTestsBase { assertEquals("mbo", "some thing ", mEditText.getText().toString()); typeWordAndPutCursorInside(WORD_TO_TYPE, cursorPos + 1 /* startPos */); type(Constants.CODE_DELETE); - ensureComposingSpanPos("space while in the middle of a word cancels composition", -1, -1); + ensureComposingSpanPos("delete while in the middle of a word cancels composition", -1, -1); } public void testTypeWithinGestureComposing() { @@ -741,17 +727,8 @@ public class InputLogicTests extends InputTestsBase { type(" "); typeWordAndPutCursorInside(WORD_TO_TYPE, cursorPos + 1 /* startPos */); type(Constants.CODE_DELETE); - ensureComposingSpanPos("space while in the middle of a word cancels composition", -1, -1); - } - - // TODO: Verify this works when we return FIGS language models to the APK. - public void testAutoCorrectForFrench() { - final String STRING_TO_TYPE = "irq "; - final String EXPECTED_RESULT = "ir a "; - changeLanguage("es"); - type(STRING_TO_TYPE); - assertEquals("simple auto-correct for Spanish", EXPECTED_RESULT, - mEditText.getText().toString()); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); + ensureComposingSpanPos("delete while in the middle of a word cancels composition", -1, -1); } public void testManualPickThenSeparatorForFrench() { @@ -779,13 +756,12 @@ public class InputLogicTests extends InputTestsBase { mEditText.getText().toString()); } - public void testWordThenSpaceThenPunctuationFromStripTwiceForFrench() { + public void testWordThenSpaceThenPunctuationFromStripTwice() { setBooleanPreference(Settings.PREF_BIGRAM_PREDICTIONS, false, true); final String WORD_TO_TYPE = "test "; final String PUNCTUATION_FROM_STRIP = "!"; - final String EXPECTED_RESULT = "test !!"; - changeLanguage("fr"); + final String EXPECTED_RESULT = "test!! "; type(WORD_TO_TYPE); sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); @@ -793,14 +769,12 @@ public class InputLogicTests extends InputTestsBase { mLatinIME.getSuggestedWordsForTest().isPunctuationSuggestions()); pickSuggestionManually(PUNCTUATION_FROM_STRIP); pickSuggestionManually(PUNCTUATION_FROM_STRIP); - assertEquals("type word then type space then punctuation from strip twice for French", - EXPECTED_RESULT, mEditText.getText().toString()); + assertEquals(EXPECTED_RESULT, mEditText.getText().toString()); } public void testWordThenSpaceDisplaysPredictions() { - final String WORD_TO_TYPE = "beaujolais "; - final String EXPECTED_RESULT = "nouveau"; - changeLanguage("fr"); + final String WORD_TO_TYPE = "Barack "; + final String EXPECTED_RESULT = "Obama"; type(WORD_TO_TYPE); sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); @@ -808,50 +782,4 @@ public class InputLogicTests extends InputTestsBase { assertEquals("type word then type space yields predictions for French", EXPECTED_RESULT, suggestedWords.size() > 0 ? suggestedWords.getWord(0) : null); } - - public void testAutoCorrectForGerman() { - final String STRING_TO_TYPE = "unf "; - final String EXPECTED_RESULT = "und "; - changeLanguage("de"); - type(STRING_TO_TYPE); - assertEquals("simple auto-correct for German", EXPECTED_RESULT, - mEditText.getText().toString()); - } - - public void testAutoCorrectWithUmlautForGerman() { - final String STRING_TO_TYPE = "ueber "; - final String EXPECTED_RESULT = "über "; - changeLanguage("de"); - type(STRING_TO_TYPE); - assertEquals("auto-correct with umlaut for German", EXPECTED_RESULT, - mEditText.getText().toString()); - } - - // Corresponds to InputLogicTests#testDoubleSpace - public void testDoubleSpaceHindi() { - changeLanguage("hi"); - // Set default pref just in case - setBooleanPreference(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true, true); - // U+1F607 is an emoji - final String[] STRINGS_TO_TYPE = - new String[] { "this ", "a+ ", "\u1F607 ", "|| ", ") ", "( ", "% " }; - final String[] EXPECTED_RESULTS = - new String[] { "this| ", "a+| ", "\u1F607| ", "|| ", ")| ", "( ", "%| " }; - for (int i = 0; i < STRINGS_TO_TYPE.length; ++i) { - mEditText.setText(""); - type(STRINGS_TO_TYPE[i]); - assertEquals("double space processing", EXPECTED_RESULTS[i], - mEditText.getText().toString()); - } - } - - // Corresponds to InputLogicTests#testCancelDoubleSpace - public void testCancelDoubleSpaceHindi() { - changeLanguage("hi"); - final String STRING_TO_TYPE = "this "; - final String EXPECTED_RESULT = "this "; - type(STRING_TO_TYPE); - type(Constants.CODE_DELETE); - assertEquals("double space make a period", EXPECTED_RESULT, mEditText.getText().toString()); - } } diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java index ab4060a86..dead53da2 100644 --- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java +++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java @@ -66,7 +66,8 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { protected static final int DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS = 200; // We wait for gesture computation for this delay protected static final int DELAY_TO_WAIT_FOR_GESTURE_MILLIS = 200; - private final int TIMEOUT_TO_WAIT_FOR_LOADING_MAIN_DICTIONARY_IN_SECONDS = 60; + // If a dictionary takes longer to load, we could have serious problems. + private final int TIMEOUT_TO_WAIT_FOR_LOADING_MAIN_DICTIONARY_IN_SECONDS = 5; // Type for a test phony dictionary private static final String TYPE_TEST = "test"; @@ -106,12 +107,15 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { throw new RuntimeException("Expected one span, found " + spans.length); } } + public SuggestionSpan getSpan() { + return (SuggestionSpan) mSpan; + } public boolean isAutoCorrectionIndicator() { return (mSpan instanceof SuggestionSpan) && - 0 != (SuggestionSpan.FLAG_AUTO_CORRECTION & ((SuggestionSpan)mSpan).getFlags()); + 0 != (SuggestionSpan.FLAG_AUTO_CORRECTION & getSpan().getFlags()); } public String[] getSuggestions() { - return ((SuggestionSpan)mSpan).getSuggestions(); + return getSpan().getSuggestions(); } } @@ -152,8 +156,6 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { super(LatinIMEForTests.class); } - // TODO: Isn't there a way to make this generic somehow? We can take a <T> and return a <T> - // but we'd have to dispatch types on editor.put...() functions protected boolean setBooleanPreference(final String key, final boolean value, final boolean defaultValue) { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mLatinIME); @@ -409,7 +411,8 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { } protected void pickSuggestionManually(final String suggestion) { - mLatinIME.pickSuggestionManually(new SuggestedWordInfo(suggestion, 1, + mLatinIME.pickSuggestionManually(new SuggestedWordInfo(suggestion, + "" /* prevWordsContext */, 1 /* score */, SuggestedWordInfo.KIND_CORRECTION, DICTIONARY_TEST, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */)); diff --git a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java index 657cec8d7..d465ce674 100644 --- a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java +++ b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java @@ -37,7 +37,7 @@ public class SuggestedWordsTests extends AndroidTestCase { private static SuggestedWordInfo createTypedWordInfo(final String word) { // Use 100 as the frequency because the numerical value does not matter as // long as it's > 1 and < INT_MAX. - return new SuggestedWordInfo(word, 100 /* score */, + return new SuggestedWordInfo(word, "" /* prevWordsContext */, 100 /* score */, SuggestedWordInfo.KIND_TYPED, null /* sourceDict */, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, @@ -52,7 +52,7 @@ public class SuggestedWordsTests extends AndroidTestCase { * @return a new instance of {@link SuggestedWordInfo}. */ private static SuggestedWordInfo createCorrectionWordInfo(final String word) { - return new SuggestedWordInfo(word, 1 /* score */, + return new SuggestedWordInfo(word, "" /* prevWordsContext */, 1 /* score */, SuggestedWordInfo.KIND_CORRECTION, null /* sourceDict */, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java index a432ca740..da1b32a8b 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java @@ -43,22 +43,12 @@ public final class BinaryDictIOUtils { */ public static DictDecoder getDictDecoder(final File dictFile, final long offset, final long length, final int bufferType) { - if (dictFile.isDirectory()) { - return new Ver4DictDecoder(dictFile); - } else if (dictFile.isFile()) { - return new Ver2DictDecoder(dictFile, offset, length, bufferType); - } - return null; + return new Ver4DictDecoder(dictFile); } public static DictDecoder getDictDecoder(final File dictFile, final long offset, final long length, final DictionaryBufferFactory factory) { - if (dictFile.isDirectory()) { - return new Ver4DictDecoder(dictFile); - } else if (dictFile.isFile()) { - return new Ver2DictDecoder(dictFile, offset, length, factory); - } - return null; + return new Ver4DictDecoder(dictFile); } public static DictDecoder getDictDecoder(final File dictFile, final long offset, diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java deleted file mode 100644 index 7ee1df92b..000000000 --- a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java +++ /dev/null @@ -1,319 +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.makedict; - -import com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.BinaryDictionary; -import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding; -import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; - -/** - * An implementation of DictDecoder for version 2 binary dictionary. - */ -// TODO: Separate logics that are used only for testing. -@UsedForTesting -public class Ver2DictDecoder extends AbstractDictDecoder { - /** - * A utility class for reading a PtNode. - */ - static class PtNodeReader { - static ProbabilityInfo readProbabilityInfo(final DictBuffer dictBuffer) { - // Ver2 dicts don't contain historical information. - return new ProbabilityInfo(dictBuffer.readUnsignedByte()); - } - - static int readPtNodeOptionFlags(final DictBuffer dictBuffer) { - return dictBuffer.readUnsignedByte(); - } - - static int readChildrenAddress(final DictBuffer dictBuffer, - final int ptNodeFlags) { - switch (ptNodeFlags & FormatSpec.MASK_CHILDREN_ADDRESS_TYPE) { - case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE: - return dictBuffer.readUnsignedByte(); - case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_TWOBYTES: - return dictBuffer.readUnsignedShort(); - case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_THREEBYTES: - return dictBuffer.readUnsignedInt24(); - case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_NOADDRESS: - default: - return FormatSpec.NO_CHILDREN_ADDRESS; - } - } - - // Reads shortcuts and returns the read length. - static int readShortcut(final DictBuffer dictBuffer, - final ArrayList<WeightedString> shortcutTargets) { - final int pointerBefore = dictBuffer.position(); - dictBuffer.readUnsignedShort(); // skip the size - while (true) { - final int targetFlags = dictBuffer.readUnsignedByte(); - final String word = CharEncoding.readString(dictBuffer); - shortcutTargets.add(new WeightedString(word, - targetFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY)); - if (0 == (targetFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT)) break; - } - return dictBuffer.position() - pointerBefore; - } - - static int readBigramAddresses(final DictBuffer dictBuffer, - final ArrayList<PendingAttribute> bigrams, final int baseAddress) { - int readLength = 0; - int bigramCount = 0; - while (bigramCount++ < FormatSpec.MAX_BIGRAMS_IN_A_PTNODE) { - final int bigramFlags = dictBuffer.readUnsignedByte(); - ++readLength; - final int sign = 0 == (bigramFlags & FormatSpec.FLAG_BIGRAM_ATTR_OFFSET_NEGATIVE) - ? 1 : -1; - int bigramAddress = baseAddress + readLength; - switch (bigramFlags & FormatSpec.MASK_BIGRAM_ATTR_ADDRESS_TYPE) { - case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_ONEBYTE: - bigramAddress += sign * dictBuffer.readUnsignedByte(); - readLength += 1; - break; - case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_TWOBYTES: - bigramAddress += sign * dictBuffer.readUnsignedShort(); - readLength += 2; - break; - case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_THREEBYTES: - bigramAddress += sign * dictBuffer.readUnsignedInt24(); - readLength += 3; - break; - default: - throw new RuntimeException("Has bigrams with no address"); - } - bigrams.add(new PendingAttribute( - bigramFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY, - bigramAddress)); - if (0 == (bigramFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT)) break; - } - return readLength; - } - } - - 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; - - @UsedForTesting - /* 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(); - } else if ((factoryFlag & MASK_DICTBUFFER) == USE_BYTEARRAY) { - mBufferFactory = new DictionaryBufferFromByteArrayFactory(); - } else if ((factoryFlag & MASK_DICTBUFFER) == USE_WRITABLE_BYTEBUFFER) { - mBufferFactory = new DictionaryBufferFromWritableByteBufferFactory(); - } else { - mBufferFactory = new DictionaryBufferFromReadOnlyByteBufferFactory(); - } - } - - /* package */ Ver2DictDecoder(final File file, final long offset, final long length, - final DictionaryBufferFactory factory) { - mDictionaryBinaryFile = file; - mOffset = offset; - mLength = length; - mBufferFactory = factory; - } - - @Override - public void openDictBuffer() throws FileNotFoundException, IOException { - mDictBuffer = mBufferFactory.getDictionaryBuffer(mDictionaryBinaryFile); - } - - @Override - public boolean isDictBufferOpen() { - return mDictBuffer != null; - } - - /* package */ DictBuffer getDictBuffer() { - return mDictBuffer; - } - - @UsedForTesting - /* package */ DictBuffer openAndGetDictBuffer() throws FileNotFoundException, IOException { - openDictBuffer(); - return getDictBuffer(); - } - - @Override - public DictionaryHeader readHeader() throws IOException, UnsupportedFormatException { - // dictType is not being used in dicttool. Passing an empty string. - final BinaryDictionary binaryDictionary = new BinaryDictionary( - mDictionaryBinaryFile.getAbsolutePath(), mOffset, mLength, - true /* useFullEditDistance */, null /* locale */, "" /* dictType */, - false /* isUpdatable */); - final DictionaryHeader header = binaryDictionary.getHeader(); - binaryDictionary.close(); - if (header == null) { - throw new IOException("Cannot read the dictionary header."); - } - if (header.mFormatOptions.mVersion != FormatSpec.VERSION2 && - header.mFormatOptions.mVersion != FormatSpec.VERSION201 && - header.mFormatOptions.mVersion != FormatSpec.VERSION202) { - throw new UnsupportedFormatException("File header has a wrong version : " - + header.mFormatOptions.mVersion); - } - if (!isDictBufferOpen()) { - openDictBuffer(); - } - // Advance buffer reading position to the head of dictionary body. - setPosition(header.mBodyOffset); - return header; - } - - // TODO: Make this buffer multi thread safe. - private final int[] mCharacterBuffer = new int[FormatSpec.MAX_WORD_LENGTH]; - @Override - public PtNodeInfo readPtNode(final int ptNodePos) { - int addressPointer = ptNodePos; - final int flags = PtNodeReader.readPtNodeOptionFlags(mDictBuffer); - addressPointer += FormatSpec.PTNODE_FLAGS_SIZE; - final int characters[]; - if (0 != (flags & FormatSpec.FLAG_HAS_MULTIPLE_CHARS)) { - int index = 0; - int character = CharEncoding.readChar(mDictBuffer); - addressPointer += CharEncoding.getCharSize(character, null); - while (FormatSpec.INVALID_CHARACTER != character) { - // FusionDictionary is making sure that the length of the word is smaller than - // MAX_WORD_LENGTH. - // So we'll never write past the end of mCharacterBuffer. - mCharacterBuffer[index++] = character; - character = CharEncoding.readChar(mDictBuffer); - addressPointer += CharEncoding.getCharSize(character, null); - } - characters = Arrays.copyOfRange(mCharacterBuffer, 0, index); - } else { - final int character = CharEncoding.readChar(mDictBuffer); - addressPointer += CharEncoding.getCharSize(character, null); - characters = new int[] { character }; - } - final ProbabilityInfo probabilityInfo; - if (0 != (FormatSpec.FLAG_IS_TERMINAL & flags)) { - probabilityInfo = PtNodeReader.readProbabilityInfo(mDictBuffer); - addressPointer += FormatSpec.PTNODE_FREQUENCY_SIZE; - } else { - probabilityInfo = null; - } - int childrenAddress = PtNodeReader.readChildrenAddress(mDictBuffer, flags); - if (childrenAddress != FormatSpec.NO_CHILDREN_ADDRESS) { - childrenAddress += addressPointer; - } - addressPointer += BinaryDictIOUtils.getChildrenAddressSize(flags); - final ArrayList<WeightedString> shortcutTargets; - if (0 != (flags & FormatSpec.FLAG_HAS_SHORTCUT_TARGETS)) { - // readShortcut will add shortcuts to shortcutTargets. - shortcutTargets = new ArrayList<>(); - addressPointer += PtNodeReader.readShortcut(mDictBuffer, shortcutTargets); - } else { - shortcutTargets = null; - } - - final ArrayList<PendingAttribute> bigrams; - if (0 != (flags & FormatSpec.FLAG_HAS_BIGRAMS)) { - bigrams = new ArrayList<>(); - addressPointer += PtNodeReader.readBigramAddresses(mDictBuffer, bigrams, - addressPointer); - if (bigrams.size() >= FormatSpec.MAX_BIGRAMS_IN_A_PTNODE) { - throw new RuntimeException("Too many bigrams in a PtNode (" + bigrams.size() - + " but max is " + FormatSpec.MAX_BIGRAMS_IN_A_PTNODE + ")"); - } - } else { - bigrams = null; - } - return new PtNodeInfo(ptNodePos, addressPointer, flags, characters, probabilityInfo, - childrenAddress, shortcutTargets, bigrams); - } - - @Override - public FusionDictionary readDictionaryBinary(final boolean deleteDictIfBroken) - throws FileNotFoundException, 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 */); - final DictionaryHeader header = readHeader(); - final FusionDictionary fusionDict = - new FusionDictionary(new FusionDictionary.PtNodeArray(), header.mDictionaryOptions); - int token = 0; - final ArrayList<WordProperty> wordProperties = new ArrayList<>(); - do { - final BinaryDictionary.GetNextWordPropertyResult result = - binaryDictionary.getNextWordProperty(token); - final WordProperty wordProperty = result.mWordProperty; - if (wordProperty == null) { - binaryDictionary.close(); - if (deleteDictIfBroken) { - mDictionaryBinaryFile.delete(); - } - return null; - } - wordProperties.add(wordProperty); - token = result.mNextToken; - } while (token != 0); - - // Insert unigrams into the fusion dictionary. - for (final WordProperty wordProperty : wordProperties) { - fusionDict.add(wordProperty.mWord, wordProperty.mProbabilityInfo, - wordProperty.mIsNotAWord, - wordProperty.mIsPossiblyOffensive); - } - // Insert bigrams into the fusion dictionary. - for (final WordProperty wordProperty : wordProperties) { - if (!wordProperty.mHasNgrams) { - continue; - } - final String word0 = wordProperty.mWord; - for (final WeightedString bigram : wordProperty.getBigrams()) { - fusionDict.setBigram(word0, bigram.mWord, bigram.mProbabilityInfo); - } - } - binaryDictionary.close(); - return fusionDict; - } - - @Override - public void setPosition(int newPos) { - mDictBuffer.position(newPos); - } - - @Override - public int getPosition() { - return mDictBuffer.position(); - } - - @Override - public int readPtNodeCount() { - return BinaryDictDecoderUtils.readPtNodeCount(mDictBuffer); - } -} diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoderTests.java deleted file mode 100644 index 3882c2c55..000000000 --- a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoderTests.java +++ /dev/null @@ -1,150 +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.makedict; - -import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer; -import com.android.inputmethod.latin.makedict.DictDecoder.DictionaryBufferFactory; -import com.android.inputmethod.latin.makedict.DictDecoder.DictionaryBufferFromByteArrayFactory; -import com.android.inputmethod.latin.makedict.DictDecoder. - DictionaryBufferFromReadOnlyByteBufferFactory; -import com.android.inputmethod.latin.makedict.DictDecoder. - DictionaryBufferFromWritableByteBufferFactory; - -import android.test.AndroidTestCase; -import android.util.Log; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * Unit tests for Ver2DictDecoder - */ -public class Ver2DictDecoderTests extends AndroidTestCase { - private static final String TAG = Ver2DictDecoderTests.class.getSimpleName(); - - private final byte[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; - - // Utilities for testing - public void writeDataToFile(final File file) { - FileOutputStream outStream = null; - try { - outStream = new FileOutputStream(file); - outStream.write(data); - } catch (IOException e) { - fail ("Can't write data to the test file"); - } finally { - if (outStream != null) { - try { - outStream.close(); - } catch (IOException e) { - Log.e(TAG, "Failed to close the output stream", e); - } - } - } - } - - public void runTestOpenBuffer(final String testName, final DictionaryBufferFactory factory) { - File testFile = null; - try { - testFile = File.createTempFile(testName, ".tmp", getContext().getCacheDir()); - } catch (IOException e) { - Log.e(TAG, "IOException while the creating temporary file", e); - } - - assertNotNull(testFile); - final Ver2DictDecoder dictDecoder = new Ver2DictDecoder(testFile, 0, testFile.length(), - factory); - try { - dictDecoder.openDictBuffer(); - } catch (Exception e) { - Log.e(TAG, "Failed to open the buffer", e); - } - - writeDataToFile(testFile); - - try { - dictDecoder.openDictBuffer(); - } catch (Exception e) { - Log.e(TAG, "Raised the exception while opening buffer", e); - } - - assertEquals(testFile.length(), dictDecoder.getDictBuffer().capacity()); - } - - public void testOpenBufferWithByteBuffer() { - runTestOpenBuffer("testOpenBufferWithByteBuffer", - new DictionaryBufferFromReadOnlyByteBufferFactory()); - } - - public void testOpenBufferWithByteArray() { - runTestOpenBuffer("testOpenBufferWithByteArray", - new DictionaryBufferFromByteArrayFactory()); - } - - public void testOpenBufferWithWritableByteBuffer() { - runTestOpenBuffer("testOpenBufferWithWritableByteBuffer", - new DictionaryBufferFromWritableByteBufferFactory()); - } - - public void runTestGetBuffer(final String testName, final DictionaryBufferFactory factory) { - File testFile = null; - try { - testFile = File.createTempFile(testName, ".tmp", getContext().getCacheDir()); - } catch (IOException e) { - Log.e(TAG, "IOException while the creating temporary file", e); - } - - 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", - dictDecoder.getDictBuffer()); - - writeDataToFile(testFile); - assertTrue(testFile.exists()); - Log.d(TAG, "file length = " + testFile.length()); - - DictBuffer dictBuffer = null; - try { - dictBuffer = dictDecoder.openAndGetDictBuffer(); - } catch (IOException e) { - Log.e(TAG, "Failed to open and get the buffer", e); - } - assertNotNull("the buffer must not be null", dictBuffer); - - for (int i = 0; i < data.length; ++i) { - assertEquals(data[i], dictBuffer.readUnsignedByte()); - } - } - - public void testGetBufferWithByteBuffer() { - runTestGetBuffer("testGetBufferWithByteBuffer", - new DictionaryBufferFromReadOnlyByteBufferFactory()); - } - - public void testGetBufferWithByteArray() { - runTestGetBuffer("testGetBufferWithByteArray", - new DictionaryBufferFromByteArrayFactory()); - } - - public void testGetBufferWithWritableByteBuffer() { - runTestGetBuffer("testGetBufferWithWritableByteBuffer", - new DictionaryBufferFromWritableByteBufferFactory()); - } -} diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java deleted file mode 100644 index c63b972eb..000000000 --- a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java +++ /dev/null @@ -1,279 +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.makedict; - -import com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding; -import com.android.inputmethod.latin.makedict.BinaryDictEncoderUtils.CodePointTable; -import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions; -import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode; -import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map.Entry; - -/** - * An implementation of DictEncoder for version 2 binary dictionary. - */ -@UsedForTesting -public class Ver2DictEncoder implements DictEncoder { - - private final File mDictFile; - private OutputStream mOutStream; - private byte[] mBuffer; - private int mPosition; - private final int mCodePointTableMode; - public static final int CODE_POINT_TABLE_OFF = 0; - public static final int CODE_POINT_TABLE_ON = 1; - - @UsedForTesting - public Ver2DictEncoder(final File dictFile, final int codePointTableMode) { - mDictFile = dictFile; - mOutStream = null; - mBuffer = null; - mCodePointTableMode = codePointTableMode; - } - - // This constructor is used only by BinaryDictOffdeviceUtilsTests. - // If you want to use this in the production code, you should consider keeping consistency of - // the interface of Ver3DictDecoder by using factory. - @UsedForTesting - public Ver2DictEncoder(final OutputStream outStream) { - mDictFile = null; - mOutStream = outStream; - mCodePointTableMode = CODE_POINT_TABLE_OFF; - } - - private void openStream() throws FileNotFoundException { - mOutStream = new FileOutputStream(mDictFile); - } - - private void close() throws IOException { - if (mOutStream != null) { - mOutStream.close(); - mOutStream = null; - } - } - - // Package for testing - static CodePointTable makeCodePointTable(final FusionDictionary dict) { - final HashMap<Integer, Integer> codePointOccurrenceCounts = new HashMap<>(); - for (final WordProperty word : dict) { - // Store per code point occurrence - final String wordString = word.mWord; - for (int i = 0; i < wordString.length(); ++i) { - final int codePoint = Character.codePointAt(wordString, i); - if (codePointOccurrenceCounts.containsKey(codePoint)) { - codePointOccurrenceCounts.put(codePoint, - codePointOccurrenceCounts.get(codePoint) + 1); - } else { - codePointOccurrenceCounts.put(codePoint, 1); - } - } - } - final ArrayList<Entry<Integer, Integer>> codePointOccurrenceArray = - new ArrayList<>(codePointOccurrenceCounts.entrySet()); - // Descending order sort by occurrence (value side) - Collections.sort(codePointOccurrenceArray, new Comparator<Entry<Integer, Integer>>() { - @Override - public int compare(final Entry<Integer, Integer> a, final Entry<Integer, Integer> b) { - if (a.getValue() != b.getValue()) { - return b.getValue().compareTo(a.getValue()); - } - return b.getKey().compareTo(a.getKey()); - } - }); - int currentCodePointTableIndex = FormatSpec.MINIMAL_ONE_BYTE_CHARACTER_VALUE; - // Temporary map for writing of nodes - final HashMap<Integer, Integer> codePointToOneByteCodeMap = new HashMap<>(); - for (final Entry<Integer, Integer> entry : codePointOccurrenceArray) { - // Put a relation from the original code point to the one byte code. - codePointToOneByteCodeMap.put(entry.getKey(), currentCodePointTableIndex); - if (FormatSpec.MAXIMAL_ONE_BYTE_CHARACTER_VALUE < ++currentCodePointTableIndex) { - break; - } - } - // codePointToOneByteCodeMap for writing the trie - // codePointOccurrenceArray for writing the header - return new CodePointTable(codePointToOneByteCodeMap, codePointOccurrenceArray); - } - - @Override - public void writeDictionary(final FusionDictionary dict, final FormatOptions formatOptions) - throws IOException, UnsupportedFormatException { - // We no longer support anything but the latest version of v2. - if (formatOptions.mVersion != FormatSpec.VERSION202) { - throw new UnsupportedFormatException( - "The given format options has wrong version number : " - + formatOptions.mVersion); - } - - if (mOutStream == null) { - openStream(); - } - - // Make code point conversion table ordered by occurrence of code points - // Version 201 or later have codePointTable - final CodePointTable codePointTable; - if (mCodePointTableMode == CODE_POINT_TABLE_OFF || formatOptions.mVersion - < FormatSpec.MINIMUM_SUPPORTED_VERSION_OF_CODE_POINT_TABLE) { - codePointTable = new CodePointTable(); - } else { - codePointTable = makeCodePointTable(dict); - } - - BinaryDictEncoderUtils.writeDictionaryHeader(mOutStream, dict, formatOptions, - codePointTable.mCodePointOccurrenceArray); - - // Addresses are limited to 3 bytes, but since addresses can be relative to each node - // array, the structure itself is not limited to 16MB. However, if it is over 16MB deciding - // the order of the PtNode arrays becomes a quite complicated problem, because though the - // dictionary itself does not have a size limit, each node array must still be within 16MB - // of all its children and parents. As long as this is ensured, the dictionary file may - // grow to any size. - - // Leave the choice of the optimal node order to the flattenTree function. - MakedictLog.i("Flattening the tree..."); - ArrayList<PtNodeArray> flatNodes = BinaryDictEncoderUtils.flattenTree(dict.mRootNodeArray); - - MakedictLog.i("Computing addresses..."); - BinaryDictEncoderUtils.computeAddresses(dict, flatNodes, - codePointTable.mCodePointToOneByteCodeMap); - MakedictLog.i("Checking PtNode array..."); - if (MakedictLog.DBG) BinaryDictEncoderUtils.checkFlatPtNodeArrayList(flatNodes); - - // Create a buffer that matches the final dictionary size. - final PtNodeArray lastNodeArray = flatNodes.get(flatNodes.size() - 1); - final int bufferSize = lastNodeArray.mCachedAddressAfterUpdate + lastNodeArray.mCachedSize; - mBuffer = new byte[bufferSize]; - - MakedictLog.i("Writing file..."); - - for (PtNodeArray nodeArray : flatNodes) { - BinaryDictEncoderUtils.writePlacedPtNodeArray(dict, this, nodeArray, - codePointTable.mCodePointToOneByteCodeMap); - } - if (MakedictLog.DBG) BinaryDictEncoderUtils.showStatistics(flatNodes); - mOutStream.write(mBuffer, 0, mPosition); - - MakedictLog.i("Done"); - close(); - } - - @Override - public void setPosition(final int position) { - if (mBuffer == null || position < 0 || position >= mBuffer.length) return; - mPosition = position; - } - - @Override - public int getPosition() { - return mPosition; - } - - @Override - public void writePtNodeCount(final int ptNodeCount) { - final int countSize = BinaryDictIOUtils.getPtNodeCountSize(ptNodeCount); - if (countSize != 1 && countSize != 2) { - throw new RuntimeException("Strange size from getGroupCountSize : " + countSize); - } - final int encodedPtNodeCount = (countSize == 2) ? - (ptNodeCount | FormatSpec.LARGE_PTNODE_ARRAY_SIZE_FIELD_SIZE_FLAG) : ptNodeCount; - mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, encodedPtNodeCount, - countSize); - } - - private void writePtNodeFlags(final PtNode ptNode, - final HashMap<Integer, Integer> codePointToOneByteCodeMap) { - final int childrenPos = BinaryDictEncoderUtils.getChildrenPosition(ptNode, - codePointToOneByteCodeMap); - mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, - BinaryDictEncoderUtils.makePtNodeFlags(ptNode, childrenPos), - FormatSpec.PTNODE_FLAGS_SIZE); - } - - private void writeCharacters(final int[] codePoints, final boolean hasSeveralChars, - final HashMap<Integer, Integer> codePointToOneByteCodeMap) { - mPosition = CharEncoding.writeCharArray(codePoints, mBuffer, mPosition, - codePointToOneByteCodeMap); - if (hasSeveralChars) { - mBuffer[mPosition++] = FormatSpec.PTNODE_CHARACTERS_TERMINATOR; - } - } - - private void writeFrequency(final int frequency) { - if (frequency >= 0) { - mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, frequency, - FormatSpec.PTNODE_FREQUENCY_SIZE); - } - } - - private void writeChildrenPosition(final PtNode ptNode, - final HashMap<Integer, Integer> codePointToOneByteCodeMap) { - final int childrenPos = BinaryDictEncoderUtils.getChildrenPosition(ptNode, - codePointToOneByteCodeMap); - mPosition += BinaryDictEncoderUtils.writeChildrenPosition(mBuffer, mPosition, - childrenPos); - } - - /** - * Write a bigram attributes list to mBuffer. - * - * @param bigrams the bigram attributes list. - * @param dict the dictionary the node array is a part of (for relative offsets). - */ - private void writeBigrams(final ArrayList<WeightedString> bigrams, - final FusionDictionary dict) { - if (bigrams == null) return; - - final Iterator<WeightedString> bigramIterator = bigrams.iterator(); - while (bigramIterator.hasNext()) { - final WeightedString bigram = bigramIterator.next(); - final PtNode target = - FusionDictionary.findWordInTree(dict.mRootNodeArray, bigram.mWord); - final int addressOfBigram = target.mCachedAddressAfterUpdate; - final int unigramFrequencyForThisWord = target.getProbability(); - final int offset = addressOfBigram - - (mPosition + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE); - final int bigramFlags = BinaryDictEncoderUtils.makeBigramFlags(bigramIterator.hasNext(), - offset, bigram.getProbability(), unigramFrequencyForThisWord, bigram.mWord); - mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, bigramFlags, - FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE); - mPosition += BinaryDictEncoderUtils.writeChildrenPosition(mBuffer, mPosition, - Math.abs(offset)); - } - } - - @Override - public void writePtNode(final PtNode ptNode, final FusionDictionary dict, - final HashMap<Integer, Integer> codePointToOneByteCodeMap) { - writePtNodeFlags(ptNode, codePointToOneByteCodeMap); - writeCharacters(ptNode.mChars, ptNode.hasSeveralChars(), codePointToOneByteCodeMap); - writeFrequency(ptNode.getProbability()); - writeChildrenPosition(ptNode, codePointToOneByteCodeMap); - writeBigrams(ptNode.mBigrams, dict); - } -} diff --git a/tests/src/com/android/inputmethod/latin/settings/AccountsSettingsFragmentTests.java b/tests/src/com/android/inputmethod/latin/settings/AccountsSettingsFragmentTests.java index 0878e74cb..7a019c364 100644 --- a/tests/src/com/android/inputmethod/latin/settings/AccountsSettingsFragmentTests.java +++ b/tests/src/com/android/inputmethod/latin/settings/AccountsSettingsFragmentTests.java @@ -85,7 +85,7 @@ public class AccountsSettingsFragmentTests } public void testMultipleAccounts_noSettingsForManagedProfile() { - when(mManagedProfileUtils.hasManagedWorkProfile(any(Context.class))).thenReturn(true); + when(mManagedProfileUtils.hasWorkProfile(any(Context.class))).thenReturn(true); final AccountsSettingsFragment fragment = (AccountsSettingsFragment) getActivity().mFragment; @@ -97,7 +97,7 @@ public class AccountsSettingsFragmentTests } public void testMultipleAccounts_noCurrentAccount() { - when(mManagedProfileUtils.hasManagedWorkProfile(any(Context.class))).thenReturn(false); + when(mManagedProfileUtils.hasWorkProfile(any(Context.class))).thenReturn(false); final AccountsSettingsFragment fragment = (AccountsSettingsFragment) getActivity().mFragment; @@ -118,7 +118,7 @@ public class AccountsSettingsFragmentTests } public void testMultipleAccounts_currentAccount() { - when(mManagedProfileUtils.hasManagedWorkProfile(any(Context.class))).thenReturn(false); + when(mManagedProfileUtils.hasWorkProfile(any(Context.class))).thenReturn(false); final AccountsSettingsFragment fragment = (AccountsSettingsFragment) getActivity().mFragment; diff --git a/tests/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerServiceTest.java b/tests/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerServiceTest.java index 2272d6ba0..e7c48da19 100644 --- a/tests/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerServiceTest.java +++ b/tests/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerServiceTest.java @@ -53,14 +53,8 @@ public class AndroidSpellCheckerServiceTest extends InputTestsBase { sleep(1000); final SpanGetter span = new SpanGetter(mEditText.getText(), SuggestionSpan.class); - // If no span, the following will crash - final String[] suggestions = span.getSuggestions(); - // For this test we consider "годп" should yield at least 2 suggestions (at this moment - // it yields 5). - assertTrue(suggestions.length >= 2); - // We also assume the top suggestion should be "года", which is the top word in the - // Russian dictionary. - assertEquals("", "года", suggestions[0]); + // We don't ship with Russian LM + assertNull(span.getSpan()); } public void testSpellcheckWithPeriods() { diff --git a/tests/src/com/android/inputmethod/latin/touchinputconsumer/NullGestureConsumerTests.java b/tests/src/com/android/inputmethod/latin/touchinputconsumer/NullGestureConsumerTests.java index ca1039bd9..ad6bcc3c4 100644 --- a/tests/src/com/android/inputmethod/latin/touchinputconsumer/NullGestureConsumerTests.java +++ b/tests/src/com/android/inputmethod/latin/touchinputconsumer/NullGestureConsumerTests.java @@ -34,7 +34,7 @@ public class NullGestureConsumerTests extends AndroidTestCase { GestureConsumer.NULL_GESTURE_CONSUMER.onGestureStarted(null, null); GestureConsumer.NULL_GESTURE_CONSUMER.onGestureCanceled(); GestureConsumer.NULL_GESTURE_CONSUMER.onGestureCompleted(null); - GestureConsumer.NULL_GESTURE_CONSUMER.onImeSuggestionsProcessed(null, -1, -1); + GestureConsumer.NULL_GESTURE_CONSUMER.onImeSuggestionsProcessed(null, -1, -1, null); } /** |