diff options
Diffstat (limited to 'java')
32 files changed, 494 insertions, 150 deletions
diff --git a/java/proguard.flags b/java/proguard.flags index 701786a84..e33706c47 100644 --- a/java/proguard.flags +++ b/java/proguard.flags @@ -47,6 +47,10 @@ <init>(...); } +-keep class com.android.inputmethod.latin.ResearchLogger { + void setLogFileManager(...); +} + # The support library contains references to newer platform versions. # Don't warn about those in case this app is linking against an older # platform version. We know about them, and they are safe. diff --git a/java/res/drawable-hdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-hdpi/sym_keyboard_zwj_holo.png Binary files differnew file mode 100644 index 000000000..5fa30ceb8 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_zwj_holo.png diff --git a/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png Binary files differnew file mode 100644 index 000000000..91367f3d2 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png diff --git a/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png Binary files differnew file mode 100644 index 000000000..70370d83d --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png diff --git a/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png Binary files differnew file mode 100644 index 000000000..a69eade17 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png Binary files differnew file mode 100644 index 000000000..26694274e --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png Binary files differnew file mode 100644 index 000000000..75a22b65f --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png diff --git a/java/res/values-land/dimens.xml b/java/res/values-land/dimens.xml index 550d29f76..1157b2733 100644 --- a/java/res/values-land/dimens.xml +++ b/java/res/values-land/dimens.xml @@ -24,8 +24,7 @@ <dimen name="keyboardHeight">176.0dp</dimen> <fraction name="minKeyboardHeight">45%p</fraction> <!-- key_height + key_bottom_gap = popup_key_height --> -<!-- <dimen name="key_height">0.260in</dimen>--> - <dimen name="popup_key_height">0.280in</dimen> + <dimen name="popup_key_height">44.8dp</dimen> <fraction name="keyboard_top_padding">1.818%p</fraction> <fraction name="keyboard_bottom_padding">0.0%p</fraction> @@ -54,11 +53,11 @@ <fraction name="key_uppercase_letter_ratio">40%</fraction> <fraction name="key_preview_text_ratio">90%</fraction> <fraction name="spacebar_text_ratio">40.000%</fraction> - <dimen name="key_preview_offset">0.08in</dimen> + <dimen name="key_preview_offset">12.8dp</dimen> - <dimen name="key_preview_offset_ics">0.01in</dimen> + <dimen name="key_preview_offset_ics">1.6dp</dimen> <!-- popup_key_height x -0.5 --> - <dimen name="more_keys_keyboard_vertical_correction_ics">-0.140in</dimen> + <dimen name="more_keys_keyboard_vertical_correction_ics">-22.4dp</dimen> <dimen name="suggestions_strip_height">36dp</dimen> <dimen name="more_suggestions_row_height">36dp</dimen> @@ -66,7 +65,7 @@ <fraction name="min_more_suggestions_width">60%</fraction> <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. --> <!-- popup_key_height x 1.2 --> - <dimen name="more_keys_keyboard_slide_allowance">0.336in</dimen> + <dimen name="more_keys_keyboard_slide_allowance">53.76dp</dimen> <!-- popup_key_height x -1.0 --> - <dimen name="more_keys_keyboard_vertical_correction">-0.280in</dimen> + <dimen name="more_keys_keyboard_vertical_correction">-44.8dp</dimen> </resources> diff --git a/java/res/values-sw600dp-land/dimens.xml b/java/res/values-sw600dp-land/dimens.xml index c6c6f2b3b..8a59c9b54 100644 --- a/java/res/values-sw600dp-land/dimens.xml +++ b/java/res/values-sw600dp-land/dimens.xml @@ -38,7 +38,7 @@ <fraction name="key_bottom_gap_ics">4.0%p</fraction> <fraction name="keyboard_bottom_padding_ics">0.0%p</fraction> - <dimen name="popup_key_height">13.0mm</dimen> + <dimen name="popup_key_height">81.9dp</dimen> <!-- left or right padding of label alignment --> <dimen name="key_label_horizontal_padding">18dp</dimen> @@ -51,7 +51,7 @@ <fraction name="key_uppercase_letter_ratio">29%</fraction> <fraction name="spacebar_text_ratio">33.33%</fraction> - <dimen name="suggestions_strip_padding">40.0mm</dimen> + <dimen name="suggestions_strip_padding">252.0dp</dimen> <integer name="max_more_suggestions_row">5</integer> <fraction name="min_more_suggestions_width">50%</fraction> </resources> diff --git a/java/res/values-sw600dp/dimens.xml b/java/res/values-sw600dp/dimens.xml index ebe388263..f03ce2943 100644 --- a/java/res/values-sw600dp/dimens.xml +++ b/java/res/values-sw600dp/dimens.xml @@ -25,7 +25,7 @@ <fraction name="maxKeyboardHeight">50%p</fraction> <fraction name="minKeyboardHeight">-35.0%p</fraction> - <dimen name="popup_key_height">10.0mm</dimen> + <dimen name="popup_key_height">63.0dp</dimen> <fraction name="keyboard_top_padding">2.291%p</fraction> <fraction name="keyboard_bottom_padding">0.0%p</fraction> @@ -44,9 +44,9 @@ <dimen name="more_keys_keyboard_key_horizontal_padding">6dp</dimen> <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. --> <!-- popup_key_height x 1.2 --> - <dimen name="more_keys_keyboard_slide_allowance">15.6mm</dimen> + <dimen name="more_keys_keyboard_slide_allowance">98.3dp</dimen> <!-- popup_key_height x -1.0 --> - <dimen name="more_keys_keyboard_vertical_correction">-13.0mm</dimen> + <dimen name="more_keys_keyboard_vertical_correction">-81.9dp</dimen> <!-- left or right padding of label alignment --> <dimen name="key_label_horizontal_padding">6dp</dimen> @@ -61,19 +61,19 @@ <fraction name="key_uppercase_letter_ratio">26%</fraction> <fraction name="key_preview_text_ratio">50%</fraction> <fraction name="spacebar_text_ratio">32.14%</fraction> - <dimen name="key_preview_height">15.0mm</dimen> - <dimen name="key_preview_offset">0.1in</dimen> + <dimen name="key_preview_height">94.5dp</dimen> + <dimen name="key_preview_offset">16.0dp</dimen> - <dimen name="key_preview_offset_ics">0.05in</dimen> + <dimen name="key_preview_offset_ics">8.0dp</dimen> <!-- popup_key_height x -0.5 --> - <dimen name="more_keys_keyboard_vertical_correction_ics">-5mm</dimen> + <dimen name="more_keys_keyboard_vertical_correction_ics">-31.5dp</dimen> <dimen name="suggestions_strip_height">44dp</dimen> <dimen name="more_suggestions_row_height">44dp</dimen> <integer name="max_more_suggestions_row">6</integer> <fraction name="min_more_suggestions_width">90%</fraction> - <dimen name="suggestions_strip_padding">15.0mm</dimen> - <dimen name="suggestion_min_width">0.3in</dimen> + <dimen name="suggestions_strip_padding">94.5dp</dimen> + <dimen name="suggestion_min_width">48.0dp</dimen> <dimen name="suggestion_padding">12dp</dimen> <dimen name="suggestion_text_size">22dp</dimen> <dimen name="more_suggestions_hint_text_size">33dp</dimen> diff --git a/java/res/values-sw768dp-land/dimens.xml b/java/res/values-sw768dp-land/dimens.xml index 597ed5102..b95c858dc 100644 --- a/java/res/values-sw768dp-land/dimens.xml +++ b/java/res/values-sw768dp-land/dimens.xml @@ -41,7 +41,7 @@ <fraction name="key_bottom_gap_ics">3.690%p</fraction> <fraction name="key_horizontal_gap_ics">1.030%p</fraction> - <dimen name="popup_key_height">13.0mm</dimen> + <dimen name="popup_key_height">81.9dp</dimen> <!-- left or right padding of label alignment --> <dimen name="key_label_horizontal_padding">18dp</dimen> @@ -53,10 +53,10 @@ <fraction name="key_hint_label_ratio">28%</fraction> <fraction name="key_uppercase_letter_ratio">24%</fraction> <fraction name="spacebar_text_ratio">24.00%</fraction> - <dimen name="key_preview_height">17.0mm</dimen> + <dimen name="key_preview_height">107.1dp</dimen> - <dimen name="key_preview_offset_ics">0.05in</dimen> + <dimen name="key_preview_offset_ics">8.0dp</dimen> - <dimen name="suggestions_strip_padding">40.0mm</dimen> + <dimen name="suggestions_strip_padding">252.0dp</dimen> <fraction name="min_more_suggestions_width">50%</fraction> </resources> diff --git a/java/res/values-sw768dp/dimens.xml b/java/res/values-sw768dp/dimens.xml index a9f0c00aa..0a362fd68 100644 --- a/java/res/values-sw768dp/dimens.xml +++ b/java/res/values-sw768dp/dimens.xml @@ -41,14 +41,14 @@ <fraction name="key_bottom_gap_ics">3.312%p</fraction> <fraction name="key_horizontal_gap_ics">1.066%p</fraction> - <dimen name="popup_key_height">10.0mm</dimen> + <dimen name="popup_key_height">63.0dp</dimen> <dimen name="more_keys_keyboard_key_horizontal_padding">12dp</dimen> <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. --> <!-- popup_key_height x 1.2 --> - <dimen name="more_keys_keyboard_slide_allowance">15.6mm</dimen> + <dimen name="more_keys_keyboard_slide_allowance">98.3dp</dimen> <!-- popup_key_height x -1.0 --> - <dimen name="more_keys_keyboard_vertical_correction">-13.0mm</dimen> + <dimen name="more_keys_keyboard_vertical_correction">-81.9dp</dimen> <!-- left or right padding of label alignment --> <dimen name="key_label_horizontal_padding">6dp</dimen> @@ -63,18 +63,18 @@ <fraction name="key_uppercase_letter_ratio">26%</fraction> <fraction name="key_preview_text_ratio">50%</fraction> <fraction name="spacebar_text_ratio">29.03%</fraction> - <dimen name="key_preview_height">15.0mm</dimen> - <dimen name="key_preview_offset">0.1in</dimen> + <dimen name="key_preview_height">94.5dp</dimen> + <dimen name="key_preview_offset">16.0dp</dimen> - <dimen name="key_preview_offset_ics">0.05in</dimen> + <dimen name="key_preview_offset_ics">8.0dp</dimen> <!-- popup_key_height x -0.5 --> - <dimen name="more_keys_keyboard_vertical_correction_ics">-5mm</dimen> + <dimen name="more_keys_keyboard_vertical_correction_ics">-31.5dp</dimen> <dimen name="suggestions_strip_height">44dp</dimen> <dimen name="more_suggestions_row_height">44dp</dimen> <integer name="max_more_suggestions_row">6</integer> <fraction name="min_more_suggestions_width">90%</fraction> - <dimen name="suggestions_strip_padding">15.0mm</dimen> + <dimen name="suggestions_strip_padding">94.5dp</dimen> <dimen name="suggestion_min_width">46dp</dimen> <dimen name="suggestion_padding">8dp</dimen> <dimen name="suggestion_text_size">22dp</dimen> diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml index e33f0ba8a..550f5acf7 100644 --- a/java/res/values/attrs.xml +++ b/java/res/values/attrs.xml @@ -224,6 +224,8 @@ <attr name="iconDisabledShortcutKey" format="reference" /> <attr name="iconPreviewTabKey" format="reference" /> <attr name="iconLanguageSwitchKey" format="reference" /> + <attr name="iconZwnjKey" format="reference" /> + <attr name="iconZwjKey" format="reference" /> </declare-styleable> <declare-styleable name="Keyboard_Key"> @@ -309,6 +311,8 @@ <enum name="iconSpaceKeyForNumberLayout" value="10" /> <enum name="iconShiftKeyShifted" value="11" /> <enum name="iconLanguageSwitchKey" value="14" /> + <enum name="iconZwnjKey" value="15" /> + <enum name="iconZwjKey" value="16" /> </attr> <!-- The icon for disabled key --> <attr name="keyIconDisabled" format="enum"> diff --git a/java/res/values/config.xml b/java/res/values/config.xml index 1aa0dffc9..f0b12e92b 100644 --- a/java/res/values/config.xml +++ b/java/res/values/config.xml @@ -54,9 +54,9 @@ <!-- Configuration for LatinKeyboardView --> - <dimen name="config_key_hysteresis_distance">0.05in</dimen> + <dimen name="config_key_hysteresis_distance">8.0dp</dimen> <integer name="config_touch_noise_threshold_time">40</integer> - <dimen name="config_touch_noise_threshold_distance">2.0mm</dimen> + <dimen name="config_touch_noise_threshold_distance">12.6dp</dimen> <bool name="config_sliding_key_input_enabled">true</bool> <integer name="config_key_repeat_start_timeout">400</integer> <integer name="config_key_repeat_interval">50</integer> diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml index 9d64a618a..1889758b9 100644 --- a/java/res/values/dimens.xml +++ b/java/res/values/dimens.xml @@ -25,7 +25,7 @@ <fraction name="maxKeyboardHeight">50%p</fraction> <fraction name="minKeyboardHeight">-61.8%p</fraction> - <dimen name="popup_key_height">0.330in</dimen> + <dimen name="popup_key_height">52.8dp</dimen> <dimen name="more_keys_keyboard_horizontal_edges_padding">16dp</dimen> <dimen name="more_keys_keyboard_key_horizontal_padding">8dp</dimen> @@ -52,12 +52,10 @@ <!-- Amount of allowance for selecting keys in a mini popup keyboard by sliding finger. --> <!-- popup_key_height x 1.2 --> - <dimen name="more_keys_keyboard_slide_allowance">0.396in</dimen> + <dimen name="more_keys_keyboard_slide_allowance">63.36dp</dimen> <!-- popup_key_height x -1.0 --> - <dimen name="more_keys_keyboard_vertical_correction">-0.330in</dimen> - <!-- We use "inch", not "dip" because this value tries dealing with physical distance related - to user's finger. --> - <dimen name="keyboard_vertical_correction">0.0in</dimen> + <dimen name="more_keys_keyboard_vertical_correction">-52.8dp</dimen> + <dimen name="keyboard_vertical_correction">0.0dp</dimen> <fraction name="key_letter_ratio">55%</fraction> <fraction name="key_large_letter_ratio">65%</fraction> @@ -68,23 +66,23 @@ <fraction name="key_preview_text_ratio">82%</fraction> <fraction name="spacebar_text_ratio">33.735%</fraction> <dimen name="key_preview_height">80dp</dimen> - <dimen name="key_preview_offset">0.1in</dimen> + <dimen name="key_preview_offset">16.0dp</dimen> <dimen name="key_label_horizontal_padding">4dp</dimen> <dimen name="key_hint_letter_padding">1dp</dimen> <dimen name="key_popup_hint_letter_padding">2dp</dimen> <dimen name="key_uppercase_letter_padding">2dp</dimen> - <dimen name="key_preview_offset_ics">0.05in</dimen> + <dimen name="key_preview_offset_ics">8.0dp</dimen> <!-- popup_key_height x -0.5 --> - <dimen name="more_keys_keyboard_vertical_correction_ics">-0.165in</dimen> + <dimen name="more_keys_keyboard_vertical_correction_ics">-26.4dp</dimen> <dimen name="suggestions_strip_height">40dp</dimen> <dimen name="more_suggestions_key_horizontal_padding">12dp</dimen> <dimen name="more_suggestions_row_height">40dp</dimen> <dimen name="more_suggestions_bottom_gap">6dp</dimen> - <dimen name="more_suggestions_modal_tolerance">0.2in</dimen> - <dimen name="more_suggestions_slide_allowance">0.1in</dimen> + <dimen name="more_suggestions_modal_tolerance">32.0dp</dimen> + <dimen name="more_suggestions_slide_allowance">16.0dp</dimen> <integer name="max_more_suggestions_row">6</integer> <fraction name="min_more_suggestions_width">90%</fraction> <fraction name="more_suggestions_info_ratio">18%</fraction> diff --git a/java/res/values/keyboard-icons-black.xml b/java/res/values/keyboard-icons-black.xml index 44fc2b9c1..1ff597a49 100644 --- a/java/res/values/keyboard-icons-black.xml +++ b/java/res/values/keyboard-icons-black.xml @@ -36,5 +36,8 @@ <item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item> <!-- TODO: Needs dedicated black theme globe icon --> <item name="iconLanguageSwitchKey">@drawable/sym_keyboard_language_switch</item> + <!-- TODO: Needs dedicated black theme ZWNJ and ZWJ icons --> + <item name="iconZwnjKey">@drawable/sym_keyboard_zwnj_holo</item> + <item name="iconZwjKey">@drawable/sym_keyboard_zwj_holo</item> </style> </resources> diff --git a/java/res/values/keyboard-icons-ics.xml b/java/res/values/keyboard-icons-ics.xml index 5fba0253d..0774d57ac 100644 --- a/java/res/values/keyboard-icons-ics.xml +++ b/java/res/values/keyboard-icons-ics.xml @@ -34,5 +34,7 @@ <item name="iconDisabledShortcutKey">@drawable/sym_keyboard_voice_off_holo</item> <item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item> <item name="iconLanguageSwitchKey">@drawable/sym_keyboard_language_switch</item> + <item name="iconZwnjKey">@drawable/sym_keyboard_zwnj_holo</item> + <item name="iconZwjKey">@drawable/sym_keyboard_zwj_holo</item> </style> </resources> diff --git a/java/res/values/keyboard-icons-white.xml b/java/res/values/keyboard-icons-white.xml index 837b1a37a..5798786f8 100644 --- a/java/res/values/keyboard-icons-white.xml +++ b/java/res/values/keyboard-icons-white.xml @@ -32,5 +32,8 @@ <item name="iconDisabledShortcutKey">@drawable/sym_keyboard_voice_off_holo</item> <item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item> <item name="iconLanguageSwitchKey">@drawable/sym_keyboard_language_switch</item> + <!-- TODO: Needs dedicated black theme ZWNJ and ZWJ icons --> + <item name="iconZwnjKey">@drawable/sym_keyboard_zwnj_holo</item> + <item name="iconZwjKey">@drawable/sym_keyboard_zwj_holo</item> </style> </resources> diff --git a/java/res/xml-sw600dp/key_styles_common.xml b/java/res/xml-sw600dp/key_styles_common.xml index a263acd9b..77c0efd22 100644 --- a/java/res/xml-sw600dp/key_styles_common.xml +++ b/java/res/xml-sw600dp/key_styles_common.xml @@ -78,11 +78,15 @@ latin:styleName="spaceKeyStyle" latin:code="@integer/key_space" latin:keyActionFlags="noKeyPreview" /> + <!-- U+200C: ZERO WIDTH NON-JOINER + U+200D: ZERO WIDTH JOINER --> <key-style latin:styleName="zwnjKeyStyle" - latin:keyLabel="‌" - latin:moreKeys="‍" - latin:keyLabelFlags="hasPopupHint" /> + latin:code="0x200C" + latin:keyIcon="iconZwnjKey" + latin:moreKeys="\@icon/zwjKey|‍" + latin:keyLabelFlags="hasPopupHint" + latin:keyActionFlags="noKeyPreview" /> <key-style latin:styleName="smileyKeyStyle" latin:keyLabel=":-)" diff --git a/java/res/xml-sw600dp/rowkeys_thai3.xml b/java/res/xml-sw600dp/rowkeys_thai3.xml index 529d7bff0..abd67631c 100644 --- a/java/res/xml-sw600dp/rowkeys_thai3.xml +++ b/java/res/xml-sw600dp/rowkeys_thai3.xml @@ -82,13 +82,13 @@ latin:keyLabel="่" /> <!-- U+0E32: "า" THAI CHARACTER SARA AA --> <Key - latin:keyLabel="ๆ" /> + latin:keyLabel="า" /> <!-- U+0E2A: "ส" THAI CHARACTER SO SUA --> <Key - latin:keyLabel="ๆ" /> + latin:keyLabel="ส" /> <!-- U+0E27: "ว" THAI CHARACTER WO WAEN --> <Key - latin:keyLabel="ฯ" /> + latin:keyLabel="ว" /> <!-- U+0E07: "ง" THAI CHARACTER NGO NGU --> <Key latin:keyLabel="ง" /> diff --git a/java/res/xml-sw768dp/key_styles_common.xml b/java/res/xml-sw768dp/key_styles_common.xml index fade151ed..f4a1a4ea5 100644 --- a/java/res/xml-sw768dp/key_styles_common.xml +++ b/java/res/xml-sw768dp/key_styles_common.xml @@ -77,11 +77,15 @@ latin:styleName="spaceKeyStyle" latin:code="@integer/key_space" latin:keyActionFlags="noKeyPreview" /> + <!-- U+200C: ZERO WIDTH NON-JOINER + U+200D: ZERO WIDTH JOINER --> <key-style latin:styleName="zwnjKeyStyle" - latin:keyLabel="‌" - latin:moreKeys="‍" - latin:keyLabelFlags="hasPopupHint" /> + latin:code="0x200C" + latin:keyIcon="iconZwnjKey" + latin:moreKeys="\@icon/zwjKey|‍" + latin:keyLabelFlags="hasPopupHint" + latin:keyActionFlags="noKeyPreview" /> <key-style latin:styleName="smileyKeyStyle" latin:keyLabel=":-)" diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml index 087b8952f..66d8d4d9d 100644 --- a/java/res/xml/key_styles_common.xml +++ b/java/res/xml/key_styles_common.xml @@ -107,11 +107,15 @@ latin:code="@integer/key_space" latin:keyActionFlags="noKeyPreview|enableLongPress" latin:backgroundType="functional" /> + <!-- U+200C: ZERO WIDTH NON-JOINER + U+200D: ZERO WIDTH JOINER --> <key-style latin:styleName="zwnjKeyStyle" - latin:keyLabel="‌" - latin:moreKeys="‍" + latin:code="0x200C" + latin:keyIcon="iconZwnjKey" + latin:moreKeys="\@icon/zwjKey|‍" latin:keyLabelFlags="hasPopupHint" + latin:keyActionFlags="noKeyPreview" latin:backgroundType="functional" /> <key-style latin:styleName="shortcutKeyStyle" @@ -129,8 +133,6 @@ latin:keyActionFlags="noKeyPreview|altCodeWhileTyping|enableLongPress" latin:altCode="@integer/key_space" latin:backgroundType="functional" /> - <!-- U+200C: "" ZERO WIDTH NON-JOINER - U+200D: "" ZERO WIDTH JOINER --> <key-style latin:styleName="tabKeyStyle" latin:code="@integer/key_tab" diff --git a/java/res/xml/rowkeys_thai2.xml b/java/res/xml/rowkeys_thai2.xml index a5db66519..02ea6c5f8 100644 --- a/java/res/xml/rowkeys_thai2.xml +++ b/java/res/xml/rowkeys_thai2.xml @@ -46,9 +46,11 @@ <!-- U+0E0B: "ซ" THAI CHARACTER SO SO --> <Key latin:keyLabel="ซ" /> - <!-- U+0E3F: "฿" THAI CURRENCY SYMBOL BAHT --> + <!-- U+0E3F: "฿" THAI CURRENCY SYMBOL BAHT + U+0E45: "ๅ" THAI CHARACTER LAKKHANGYAO --> <Key - latin:keyLabel="฿" /> + latin:keyLabel="฿" + latin:moreKeys="ๅ" /> <!-- U+0E46: "ๆ" THAI CHARACTER MAIYAMOK U+0E2F: "ฯ" THAI CHARACTER PAIYANNOI --> <Key diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index 07b9c1e8c..962379016 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -394,7 +394,7 @@ public class Keyboard { * >Row row_attributes*< * >!-- Row Content --< * >Key key_attributes* /< - * >Spacer horizontalGap="0.2in" /< + * >Spacer horizontalGap="32.0dp" /< * >include keyboardLayout="@xml/other_keys"< * ... * >/Row< diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index b66d1661d..3f6c37477 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -46,6 +46,7 @@ import com.android.inputmethod.keyboard.internal.KeySpecParser; import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.ResearchLogger; import com.android.inputmethod.latin.StaticInnerHandlerWrapper; import com.android.inputmethod.latin.StringUtils; import com.android.inputmethod.latin.SubtypeUtils; @@ -66,6 +67,9 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke SuddenJumpingTouchEventHandler.ProcessMotionEvent { private static final String TAG = LatinKeyboardView.class.getSimpleName(); + // TODO: Kill process when the usability study mode was changed. + private static final boolean ENABLE_USABILITY_STUDY_LOG = LatinImeLogger.sUsabilityStudy; + /** Listener for {@link KeyboardActionListener}. */ private KeyboardActionListener mKeyboardActionListener; @@ -653,8 +657,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke final int index = me.getActionIndex(); final int id = me.getPointerId(index); final int x, y; - final float size = me.getSize(index); - final float pressure = me.getPressure(index); if (mMoreKeysPanel != null && id == mMoreKeysPanelPointerTrackerId) { x = mMoreKeysPanel.translateX((int)me.getX(index)); y = mMoreKeysPanel.translateY((int)me.getY(index)); @@ -662,10 +664,44 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke x = (int)me.getX(index); y = (int)me.getY(index); } - if (LatinImeLogger.sUsabilityStudy) { + if (ENABLE_USABILITY_STUDY_LOG) { + final String eventTag; + switch (action) { + case MotionEvent.ACTION_UP: + eventTag = "[Up]"; + break; + case MotionEvent.ACTION_DOWN: + eventTag = "[Down]"; + break; + case MotionEvent.ACTION_POINTER_UP: + eventTag = "[PointerUp]"; + break; + case MotionEvent.ACTION_POINTER_DOWN: + eventTag = "[PointerDown]"; + break; + case MotionEvent.ACTION_MOVE: // Skip this as being logged below + eventTag = ""; + break; + default: + eventTag = "[Action" + action + "]"; + break; + } + if (!TextUtils.isEmpty(eventTag)) { + final float size = me.getSize(index); + final float pressure = me.getPressure(index); + UsabilityStudyLogUtils.getInstance().write( + eventTag + eventTime + "," + id + "," + x + "," + y + "," + + size + "," + pressure); + } + } + if (ResearchLogger.sIsLogging) { + // TODO: remove redundant calculations of size and pressure by + // removing UsabilityStudyLog code once the ResearchLogger is mature enough + final float size = me.getSize(index); + final float pressure = me.getPressure(index); if (action != MotionEvent.ACTION_MOVE) { // Skip ACTION_MOVE events as they are logged below - UsabilityStudyLogUtils.getInstance().writeMotionEvent(action, eventTime, id, x, + ResearchLogger.getInstance().logMotionEvent(action, eventTime, id, x, y, size, pressure); } } @@ -714,8 +750,9 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke if (action == MotionEvent.ACTION_MOVE) { for (int i = 0; i < pointerCount; i++) { + final int pointerId = me.getPointerId(i); final PointerTracker tracker = PointerTracker.getPointerTracker( - me.getPointerId(i), this); + pointerId, this); final int px, py; if (mMoreKeysPanel != null && tracker.mPointerId == mMoreKeysPanelPointerTrackerId) { @@ -726,9 +763,19 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke py = (int)me.getY(i); } tracker.onMoveEvent(px, py, eventTime); - if (LatinImeLogger.sUsabilityStudy) { - UsabilityStudyLogUtils.getInstance().writeMotionEvent(action, eventTime, id, - px, py, size, pressure); + if (ENABLE_USABILITY_STUDY_LOG) { + final float pointerSize = me.getSize(i); + final float pointerPressure = me.getPressure(i); + UsabilityStudyLogUtils.getInstance().write("[Move]" + eventTime + "," + + pointerId + "," + px + "," + py + "," + + pointerSize + "," + pointerPressure); + } + if (ResearchLogger.sIsLogging) { + // TODO: earlier comment about redundant calculations applies here too + final float pointerSize = me.getSize(i); + final float pointerPressure = me.getPressure(i); + ResearchLogger.getInstance().logMotionEvent(action, eventTime, pointerId, + px, py, pointerSize, pointerPressure); } } } else { diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java index 9b9c86179..ded89b1b8 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java @@ -30,7 +30,7 @@ public class KeyboardIconsSet { // The value should be aligned with the enum value of Key.keyIcon. public static final int ICON_UNDEFINED = 0; - private static final int NUM_ICONS = 14; + private static final int NUM_ICONS = 16; private final Drawable[] mIcons = new Drawable[NUM_ICONS + 1]; @@ -58,6 +58,8 @@ public class KeyboardIconsSet { addIconIdMap(12, "disabledShortcurKey", R.styleable.Keyboard_iconDisabledShortcutKey); addIconIdMap(13, "previewTabKey", R.styleable.Keyboard_iconPreviewTabKey); addIconIdMap(14, "languageSwitchKey", R.styleable.Keyboard_iconLanguageSwitchKey); + addIconIdMap(15, "zwnjKey", R.styleable.Keyboard_iconZwnjKey); + addIconIdMap(16, "zwjKey", R.styleable.Keyboard_iconZwjKey); } private static void addIconIdMap(int iconId, String name, int attrId) { diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 175d953a6..7272006a2 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -439,6 +439,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); mPrefs = prefs; LatinImeLogger.init(this, prefs); + ResearchLogger.init(this, prefs); LanguageSwitcherProxy.init(this, prefs); InputMethodManagerCompatWrapper.init(this); SubtypeSwitcher.init(this); @@ -528,7 +529,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar resetContactsDictionary(oldContactsDictionary); mUserHistoryDictionary - = new UserHistoryDictionary(this, this, localeStr, Suggest.DIC_USER_HISTORY); + = new UserHistoryDictionary(this, localeStr, Suggest.DIC_USER_HISTORY); mSuggest.setUserHistoryDictionary(mUserHistoryDictionary); LocaleUtils.setSystemLocale(res, savedLocale); @@ -1263,8 +1264,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } mLastKeyTime = when; - if (LatinImeLogger.sUsabilityStudy) { - UsabilityStudyLogUtils.getInstance().writeKeyEvent(primaryCode, x, y); + if (ResearchLogger.sIsLogging) { + ResearchLogger.getInstance().logKeyEvent(primaryCode, x, y); } final KeyboardSwitcher switcher = mKeyboardSwitcher; @@ -2008,8 +2009,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } else { prevWord = null; } + final String secondWord; + if (mWordComposer.isAutoCapitalized() && !mWordComposer.isMostlyCaps()) { + secondWord = suggestion.toString().toLowerCase(mSubtypeSwitcher.getInputLocale()); + } else { + secondWord = suggestion.toString(); + } mUserHistoryDictionary.addToUserHistory(null == prevWord ? null : prevWord.toString(), - suggestion.toString()); + secondWord); } } @@ -2250,10 +2257,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mFeedbackManager.vibrate(mKeyboardSwitcher.getKeyboardView()); } - public boolean isAutoCapitalized() { - return mWordComposer.isAutoCapitalized(); - } - private void updateCorrectionMode() { // TODO: cleanup messy flags final boolean shouldAutoCorrect = mSettingsValues.mAutoCorrectEnabled diff --git a/java/src/com/android/inputmethod/latin/ResearchLogger.java b/java/src/com/android/inputmethod/latin/ResearchLogger.java new file mode 100644 index 000000000..3b110bd78 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/ResearchLogger.java @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.latin; + +import android.content.SharedPreferences; +import android.inputmethodservice.InputMethodService; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Process; +import android.os.SystemClock; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; + +import com.android.inputmethod.keyboard.Keyboard; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintWriter; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Logs the use of the LatinIME keyboard. + * + * This class logs operations on the IME keyboard, including what the user has typed. + * Data is stored locally in a file in app-specific storage. + * + * This functionality is off by default. + */ +public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChangeListener { + private static final String TAG = ResearchLogger.class.getSimpleName(); + private static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode"; + + private static final ResearchLogger sInstance = new ResearchLogger(new LogFileManager()); + public static boolean sIsLogging = false; + /* package */ final Handler mLoggingHandler; + private InputMethodService mIms; + private final Date mDate; + private final SimpleDateFormat mDateFormat; + + /** + * Isolates management of files. This variable should never be null, but can be changed + * to support testing. + */ + private LogFileManager mLogFileManager; + + /** + * Manages the file(s) that stores the logs. + * + * Handles creation, deletion, and provides Readers, Writers, and InputStreams to access + * the logs. + */ + public static class LogFileManager { + private static final String DEFAULT_FILENAME = "log.txt"; + private static final String DEFAULT_LOG_DIRECTORY = "researchLogger"; + + private static final long LOGFILE_PURGE_INTERVAL = 1000 * 60 * 60 * 24; + + private InputMethodService mIms; + private File mFile; + private PrintWriter mPrintWriter; + + /* package */ LogFileManager() { + } + + public void init(InputMethodService ims) { + mIms = ims; + } + + public synchronized void createLogFile() { + try { + createLogFile(DEFAULT_LOG_DIRECTORY, DEFAULT_FILENAME); + } catch (FileNotFoundException e) { + Log.w(TAG, e); + } + } + + public synchronized void createLogFile(String dir, String filename) + throws FileNotFoundException { + if (mIms == null) { + Log.w(TAG, "InputMethodService is not configured. Logging is off."); + return; + } + File filesDir = mIms.getFilesDir(); + if (filesDir == null || !filesDir.exists()) { + Log.w(TAG, "Storage directory does not exist. Logging is off."); + return; + } + File directory = new File(filesDir, dir); + if (!directory.exists()) { + boolean wasCreated = directory.mkdirs(); + if (!wasCreated) { + Log.w(TAG, "Log directory cannot be created. Logging is off."); + return; + } + } + + close(); + mFile = new File(directory, filename); + boolean append = true; + if (mFile.exists() && mFile.lastModified() + LOGFILE_PURGE_INTERVAL < + System.currentTimeMillis()) { + append = false; + } + mPrintWriter = new PrintWriter(new FileOutputStream(mFile, append), true); + } + + public synchronized boolean append(String s) { + if (mPrintWriter == null) { + Log.w(TAG, "PrintWriter is null"); + return false; + } else { + mPrintWriter.print(s); + return !mPrintWriter.checkError(); + } + } + + public synchronized void reset() { + if (mPrintWriter != null) { + mPrintWriter.close(); + mPrintWriter = null; + } + if (mFile != null && mFile.exists()) { + mFile.delete(); + mFile = null; + } + } + + public synchronized void close() { + if (mPrintWriter != null) { + mPrintWriter.close(); + mPrintWriter = null; + mFile = null; + } + } + } + + private ResearchLogger(LogFileManager logFileManager) { + mDate = new Date(); + mDateFormat = new SimpleDateFormat("yyyyMMdd-HHmmss.SSSZ"); + + HandlerThread handlerThread = new HandlerThread("ResearchLogger logging task", + Process.THREAD_PRIORITY_BACKGROUND); + handlerThread.start(); + mLoggingHandler = new Handler(handlerThread.getLooper()); + mLogFileManager = logFileManager; + } + + public static ResearchLogger getInstance() { + return sInstance; + } + + public static void init(InputMethodService ims, SharedPreferences prefs) { + sInstance.initInternal(ims, prefs); + } + + public void initInternal(InputMethodService ims, SharedPreferences prefs) { + mIms = ims; + if (mLogFileManager != null) { + mLogFileManager.init(ims); + mLogFileManager.createLogFile(); + } + if (prefs != null) { + sIsLogging = prefs.getBoolean(PREF_USABILITY_STUDY_MODE, false); + } + prefs.registerOnSharedPreferenceChangeListener(this); + } + + /** + * Change to a different logFileManager. + * + * @throws IllegalArgumentException if logFileManager is null + */ + void setLogFileManager(LogFileManager manager) { + if (manager == null) { + throw new IllegalArgumentException("warning: trying to set null logFileManager"); + } else { + mLogFileManager = manager; + } + } + + /** + * Represents a category of logging events that share the same subfield structure. + */ + private static enum LogGroup { + MOTION_EVENT("m"), + KEY("k"), + CORRECTION("c"), + STATE_CHANGE("s"); + + private final String mLogString; + + private LogGroup(String logString) { + mLogString = logString; + } + } + + public void logMotionEvent(final int action, final long eventTime, final int id, + final int x, final int y, final float size, final float pressure) { + final String eventTag; + switch (action) { + case MotionEvent.ACTION_CANCEL: eventTag = "[Cancel]"; break; + case MotionEvent.ACTION_UP: eventTag = "[Up]"; break; + case MotionEvent.ACTION_DOWN: eventTag = "[Down]"; break; + case MotionEvent.ACTION_POINTER_UP: eventTag = "[PointerUp]"; break; + case MotionEvent.ACTION_POINTER_DOWN: eventTag = "[PointerDown]"; break; + case MotionEvent.ACTION_MOVE: eventTag = "[Move]"; break; + case MotionEvent.ACTION_OUTSIDE: eventTag = "[Outside]"; break; + default: eventTag = "[Action" + action + "]"; break; + } + if (!TextUtils.isEmpty(eventTag)) { + StringBuilder sb = new StringBuilder(); + sb.append(eventTag); + sb.append('\t'); sb.append(eventTime); + sb.append('\t'); sb.append(id); + sb.append('\t'); sb.append(x); + sb.append('\t'); sb.append(y); + sb.append('\t'); sb.append(size); + sb.append('\t'); sb.append(pressure); + write(LogGroup.MOTION_EVENT, sb.toString()); + } + } + + public void logKeyEvent(int code, int x, int y) { + final StringBuilder sb = new StringBuilder(); + sb.append(Keyboard.printableCode(code)); + sb.append('\t'); sb.append(x); + sb.append('\t'); sb.append(y); + write(LogGroup.KEY, sb.toString()); + } + + public void logCorrection(String subgroup, String before, String after, int position) { + final StringBuilder sb = new StringBuilder(); + sb.append(subgroup); + sb.append('\t'); sb.append(before); + sb.append('\t'); sb.append(after); + sb.append('\t'); sb.append(position); + write(LogGroup.CORRECTION, sb.toString()); + } + + public void logStateChange(String subgroup, String details) { + write(LogGroup.STATE_CHANGE, subgroup + "\t" + details); + } + + private void write(final LogGroup logGroup, final String log) { + mLoggingHandler.post(new Runnable() { + @Override + public void run() { + final long currentTime = System.currentTimeMillis(); + mDate.setTime(currentTime); + final long upTime = SystemClock.uptimeMillis(); + + final String printString = String.format("%s\t%d\t%s\t%s\n", + mDateFormat.format(mDate), upTime, logGroup.mLogString, log); + if (LatinImeLogger.sDBG) { + Log.d(TAG, "Write: " + '[' + logGroup.mLogString + ']' + log); + } + if (mLogFileManager.append(printString)) { + // success + } else { + if (LatinImeLogger.sDBG) { + Log.w(TAG, "Unable to write to log."); + } + } + } + }); + } + + public void clearAll() { + mLoggingHandler.post(new Runnable() { + @Override + public void run() { + if (LatinImeLogger.sDBG) { + Log.d(TAG, "Delete log file."); + } + mLogFileManager.reset(); + } + }); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { + if (key == null || prefs == null) { + return; + } + sIsLogging = prefs.getBoolean(PREF_USABILITY_STUDY_MODE, false); + } +} diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java index 4e798460c..db2cdf967 100644 --- a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java @@ -75,8 +75,6 @@ public class UserHistoryDictionary extends ExpandableDictionary { private static final String FREQ_COLUMN_PAIR_ID = "pair_id"; private static final String FREQ_COLUMN_FREQUENCY = "freq"; - private final LatinIME mIme; - /** Locale for which this auto dictionary is storing words */ private String mLocale; @@ -139,9 +137,8 @@ public class UserHistoryDictionary extends ExpandableDictionary { sDeleteHistoryBigrams = deleteHistoryBigram; } - public UserHistoryDictionary(Context context, LatinIME ime, String locale, int dicTypeId) { + public UserHistoryDictionary(final Context context, final String locale, final int dicTypeId) { super(context, dicTypeId); - mIme = ime; mLocale = locale; if (sOpenHelper == null) { sOpenHelper = new DatabaseHelper(getContext()); @@ -179,10 +176,6 @@ public class UserHistoryDictionary extends ExpandableDictionary { * The second word may not be null (a NullPointerException would be thrown). */ public int addToUserHistory(final String word1, String word2) { - // remove caps if second word is autocapitalized - if (mIme != null && mIme.isAutoCapitalized()) { - word2 = Character.toLowerCase(word2.charAt(0)) + word2.substring(1); - } super.addWord(word2, FREQUENCY_FOR_TYPED); // Do not insert a word as a bigram of itself if (word2.equals(word1)) { diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java index a3589da0a..be64c2fd8 100644 --- a/java/src/com/android/inputmethod/latin/Utils.java +++ b/java/src/com/android/inputmethod/latin/Utils.java @@ -220,6 +220,7 @@ public class Utils { } public static class UsabilityStudyLogUtils { + // TODO: remove code duplication with ResearchLog class private static final String USABILITY_TAG = UsabilityStudyLogUtils.class.getSimpleName(); private static final String FILENAME = "log.txt"; private static final UsabilityStudyLogUtils sInstance = @@ -262,73 +263,28 @@ public class Utils { } } - /** - * Represents a category of logging events that share the same subfield structure. - */ - public static enum LogGroup { - MOTION_EVENT("m"), - KEY("k"), - CORRECTION("c"), - STATE_CHANGE("s"); - - private final String mLogString; - - private LogGroup(String logString) { - mLogString = logString; - } + public static void writeBackSpace(int x, int y) { + UsabilityStudyLogUtils.getInstance().write("<backspace>\t" + x + "\t" + y); } - public void writeMotionEvent(final int action, final long eventTime, final int id, - final int x, final int y, final float size, final float pressure) { - final String eventTag; - switch (action) { - case MotionEvent.ACTION_CANCEL: eventTag = "[Cancel]"; break; - case MotionEvent.ACTION_UP: eventTag = "[Up]"; break; - case MotionEvent.ACTION_DOWN: eventTag = "[Down]"; break; - case MotionEvent.ACTION_POINTER_UP: eventTag = "[PointerUp]"; break; - case MotionEvent.ACTION_POINTER_DOWN: eventTag = "[PointerDown]"; break; - case MotionEvent.ACTION_MOVE: eventTag = "[Move]"; break; - case MotionEvent.ACTION_OUTSIDE: eventTag = "[Outside]"; break; - default: eventTag = "[Action" + action + "]"; break; - } - if (!TextUtils.isEmpty(eventTag)) { - StringBuilder sb = new StringBuilder(); - sb.append(eventTag); - sb.append('\t'); sb.append(eventTime); - sb.append('\t'); sb.append(id); - sb.append('\t'); sb.append(x); - sb.append('\t'); sb.append(y); - sb.append('\t'); sb.append(size); - sb.append('\t'); sb.append(pressure); - write(LogGroup.MOTION_EVENT, sb.toString()); + public void writeChar(char c, int x, int y) { + String inputChar = String.valueOf(c); + switch (c) { + case '\n': + inputChar = "<enter>"; + break; + case '\t': + inputChar = "<tab>"; + break; + case ' ': + inputChar = "<space>"; + break; } - } - - public void writeKeyEvent(int code, int x, int y) { - final StringBuilder sb = new StringBuilder(); - sb.append(Keyboard.printableCode(code)); - sb.append('\t'); sb.append(x); - sb.append('\t'); sb.append(y); - write(LogGroup.KEY, sb.toString()); - - // TODO: replace with a cleaner flush+retrieve mechanism + UsabilityStudyLogUtils.getInstance().write(inputChar + "\t" + x + "\t" + y); LatinImeLogger.onPrintAllUsabilityStudyLogs(); } - public void writeCorrection(String subgroup, String before, String after, int position) { - final StringBuilder sb = new StringBuilder(); - sb.append(subgroup); - sb.append('\t'); sb.append(before); - sb.append('\t'); sb.append(after); - sb.append('\t'); sb.append(position); - write(LogGroup.CORRECTION, sb.toString()); - } - - public void writeStateChange(String subgroup, String details) { - write(LogGroup.STATE_CHANGE, subgroup + "\t" + details); - } - - private void write(final LogGroup logGroup, final String log) { + public void write(final String log) { mLoggingHandler.post(new Runnable() { @Override public void run() { @@ -336,8 +292,8 @@ public class Utils { final long currentTime = System.currentTimeMillis(); mDate.setTime(currentTime); - final String printString = String.format("%s\t%d\t%s\t%s\n", - mDateFormat.format(mDate), currentTime, logGroup.mLogString, log); + final String printString = String.format("%s\t%d\t%s\n", + mDateFormat.format(mDate), currentTime, log); if (LatinImeLogger.sDBG) { Log.d(USABILITY_TAG, "Write: " + log); } diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java index 973a448ee..5a173857e 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java @@ -353,6 +353,11 @@ public class AndroidSpellCheckerService extends SpellCheckerService @Override public boolean onUnbind(final Intent intent) { + closeAllDictionaries(); + return false; + } + + private void closeAllDictionaries() { final Map<String, DictionaryPool> oldPools = mDictionaryPools; mDictionaryPools = Collections.synchronizedMap(new TreeMap<String, DictionaryPool>()); final Map<String, Dictionary> oldUserDictionaries = mUserDictionaries; @@ -378,7 +383,6 @@ public class AndroidSpellCheckerService extends SpellCheckerService dictToClose.close(); } } - return false; } private DictionaryPool getDictionaryPool(final String locale) { @@ -574,7 +578,12 @@ public class AndroidSpellCheckerService extends SpellCheckerService // The getXYForCodePointAndScript method returns (Y << 16) + X final int xy = SpellCheckerProximityInfo.getXYForCodePointAndScript( codePoint, mScript); - composer.add(codePoint, xy & 0xFFFF, xy >> 16, null); + if (SpellCheckerProximityInfo.NOT_A_COORDINATE_PAIR == xy) { + composer.add(codePoint, WordComposer.NOT_A_COORDINATE, + WordComposer.NOT_A_COORDINATE, null); + } else { + composer.add(codePoint, xy & 0xFFFF, xy >> 16, null); + } } final int capitalizeType = getCapitalizationType(text); diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java index 7627700dd..0103e8423 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java @@ -35,6 +35,9 @@ public class SpellCheckerProximityInfo { // The number of rows in the grid used by the spell checker. final public static int PROXIMITY_GRID_HEIGHT = 3; + final private static int NOT_AN_INDEX = -1; + final public static int NOT_A_COORDINATE_PAIR = -1; + // Helper methods final protected static void buildProximityIndices(final int[] proximity, final TreeMap<Integer, Integer> indices) { @@ -45,7 +48,7 @@ public class SpellCheckerProximityInfo { final protected static int computeIndex(final int characterCode, final TreeMap<Integer, Integer> indices) { final Integer result = indices.get(characterCode); - if (null == result) return -1; + if (null == result) return NOT_AN_INDEX; return result; } @@ -196,8 +199,10 @@ public class SpellCheckerProximityInfo { // Returns (Y << 16) + X to avoid creating a temporary object. This is okay because // X and Y are limited to PROXIMITY_GRID_WIDTH resp. PROXIMITY_GRID_HEIGHT which is very // inferior to 1 << 16 + // As an exception, this returns NOT_A_COORDINATE_PAIR if the key is not on the grid public static int getXYForCodePointAndScript(final int codePoint, final int script) { final int index = getIndexOfCodeForScript(codePoint, script); + if (NOT_AN_INDEX == index) return NOT_A_COORDINATE_PAIR; final int y = index / PROXIMITY_GRID_WIDTH; final int x = index % PROXIMITY_GRID_WIDTH; if (y > PROXIMITY_GRID_HEIGHT) { |