aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/proguard.flags4
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_zwj_holo.pngbin0 -> 973 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_zwnj_holo.pngbin0 -> 961 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_zwj_holo.pngbin0 -> 733 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_zwnj_holo.pngbin0 -> 704 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_zwj_holo.pngbin0 -> 1185 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.pngbin0 -> 1148 bytes
-rw-r--r--java/res/values-land/dimens.xml13
-rw-r--r--java/res/values-sw600dp-land/dimens.xml4
-rw-r--r--java/res/values-sw600dp/dimens.xml18
-rw-r--r--java/res/values-sw768dp-land/dimens.xml8
-rw-r--r--java/res/values-sw768dp/dimens.xml16
-rw-r--r--java/res/values/attrs.xml4
-rw-r--r--java/res/values/config.xml4
-rw-r--r--java/res/values/dimens.xml20
-rw-r--r--java/res/values/keyboard-icons-black.xml3
-rw-r--r--java/res/values/keyboard-icons-ics.xml2
-rw-r--r--java/res/values/keyboard-icons-white.xml3
-rw-r--r--java/res/xml-sw600dp/key_styles_common.xml10
-rw-r--r--java/res/xml-sw600dp/rowkeys_thai3.xml6
-rw-r--r--java/res/xml-sw768dp/key_styles_common.xml10
-rw-r--r--java/res/xml/key_styles_common.xml10
-rw-r--r--java/res/xml/rowkeys_thai2.xml6
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java63
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java4
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java19
-rw-r--r--java/src/com/android/inputmethod/latin/ResearchLogger.java304
-rw-r--r--java/src/com/android/inputmethod/latin/UserHistoryDictionary.java9
-rw-r--r--java/src/com/android/inputmethod/latin/Utils.java82
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java13
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java7
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
new file mode 100644
index 000000000..5fa30ceb8
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_zwj_holo.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png
new file mode 100644
index 000000000..91367f3d2
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png
new file mode 100644
index 000000000..70370d83d
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png
new file mode 100644
index 000000000..a69eade17
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png
new file mode 100644
index 000000000..26694274e
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png
new file mode 100644
index 000000000..75a22b65f
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png
Binary files differ
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="&#x200C;"
- latin:moreKeys="&#x200D;"
- latin:keyLabelFlags="hasPopupHint" />
+ latin:code="0x200C"
+ latin:keyIcon="iconZwnjKey"
+ latin:moreKeys="\@icon/zwjKey|&#x200D;"
+ 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="&#x0E48;" />
<!-- U+0E32: "า" THAI CHARACTER SARA AA -->
<Key
- latin:keyLabel="&#x0E46;" />
+ latin:keyLabel="&#x0E32;" />
<!-- U+0E2A: "ส" THAI CHARACTER SO SUA -->
<Key
- latin:keyLabel="&#x0E46;" />
+ latin:keyLabel="&#x0E2A;" />
<!-- U+0E27: "ว" THAI CHARACTER WO WAEN -->
<Key
- latin:keyLabel="&#x0E2F;" />
+ latin:keyLabel="&#x0E27;" />
<!-- U+0E07: "ง" THAI CHARACTER NGO NGU -->
<Key
latin:keyLabel="&#x0E07;" />
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="&#x200C;"
- latin:moreKeys="&#x200D;"
- latin:keyLabelFlags="hasPopupHint" />
+ latin:code="0x200C"
+ latin:keyIcon="iconZwnjKey"
+ latin:moreKeys="\@icon/zwjKey|&#x200D;"
+ 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="&#x200C;"
- latin:moreKeys="&#x200D;"
+ latin:code="0x200C"
+ latin:keyIcon="iconZwnjKey"
+ latin:moreKeys="\@icon/zwjKey|&#x200D;"
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="&#x0E0B;" />
- <!-- U+0E3F: "฿" THAI CURRENCY SYMBOL BAHT -->
+ <!-- U+0E3F: "฿" THAI CURRENCY SYMBOL BAHT
+ U+0E45: "ๅ" THAI CHARACTER LAKKHANGYAO -->
<Key
- latin:keyLabel="&#x0E3F;" />
+ latin:keyLabel="&#x0E3F;"
+ latin:moreKeys="&#x0E45;" />
<!-- 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 {
* &gt;Row row_attributes*&lt;
* &gt;!-- Row Content --&lt;
* &gt;Key key_attributes* /&lt;
- * &gt;Spacer horizontalGap="0.2in" /&lt;
+ * &gt;Spacer horizontalGap="32.0dp" /&lt;
* &gt;include keyboardLayout="@xml/other_keys"&lt;
* ...
* &gt;/Row&lt;
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) {