diff options
Diffstat (limited to 'java/src')
34 files changed, 790 insertions, 291 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java index 2ed4ea98e..cded2cb8c 100644 --- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java @@ -755,7 +755,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack public void onHideWindow() { onDismissMoreKeysPanel(); final MainKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate; - if (accessibilityDelegate != null) { + if (accessibilityDelegate != null + && AccessibilityUtils.getInstance().isAccessibilityEnabled()) { accessibilityDelegate.onHideWindow(); } } @@ -766,7 +767,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack @Override public boolean onHoverEvent(final MotionEvent event) { final MainKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate; - if (accessibilityDelegate != null) { + if (accessibilityDelegate != null + && AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { return accessibilityDelegate.onHoverEvent(event); } return super.onHoverEvent(event); diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java index a9d1239ed..841283b7f 100644 --- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java @@ -105,7 +105,7 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel super.setKeyboard(keyboard); mKeyDetector.setKeyboard( keyboard, -getPaddingLeft(), -getPaddingTop() + getVerticalCorrection()); - if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { + if (AccessibilityUtils.getInstance().isAccessibilityEnabled()) { if (mAccessibilityDelegate == null) { mAccessibilityDelegate = new MoreKeysKeyboardAccessibilityDelegate( this, mKeyDetector); @@ -142,7 +142,8 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel mOriginY = y + container.getPaddingTop(); controller.onShowMoreKeysPanel(this); final MoreKeysKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate; - if (accessibilityDelegate != null) { + if (accessibilityDelegate != null + && AccessibilityUtils.getInstance().isAccessibilityEnabled()) { accessibilityDelegate.onShowMoreKeysKeyboard(); } } @@ -239,7 +240,8 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel return; } final MoreKeysKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate; - if (accessibilityDelegate != null) { + if (accessibilityDelegate != null + && AccessibilityUtils.getInstance().isAccessibilityEnabled()) { accessibilityDelegate.onDismissMoreKeysKeyboard(); } mController.onDismissMoreKeysPanel(); @@ -285,7 +287,8 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel @Override public boolean onHoverEvent(final MotionEvent event) { final MoreKeysKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate; - if (accessibilityDelegate != null) { + if (accessibilityDelegate != null + && AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { return accessibilityDelegate.onHoverEvent(event); } return super.onHoverEvent(event); diff --git a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java index 17dfc9cce..925ec6bfb 100644 --- a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java @@ -104,7 +104,8 @@ final class EmojiPageKeyboardView extends KeyboardView implements public boolean onHoverEvent(final MotionEvent event) { final KeyboardAccessibilityDelegate<EmojiPageKeyboardView> accessibilityDelegate = mAccessibilityDelegate; - if (accessibilityDelegate != null) { + if (accessibilityDelegate != null + && AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { return accessibilityDelegate.onHoverEvent(event); } return super.onHoverEvent(event); diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java index 192011384..a778ee80b 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java @@ -85,19 +85,19 @@ public final class KeyboardTextsTable { // /* index:histogram */ "name", /* 0:32 */ "morekeys_a", /* 1:32 */ "morekeys_o", - /* 2:30 */ "morekeys_e", + /* 2:31 */ "morekeys_e", /* 3:30 */ "morekeys_u", /* 4:30 */ "keylabel_to_alpha", - /* 5:28 */ "morekeys_i", + /* 5:29 */ "morekeys_i", /* 6:24 */ "morekeys_n", - /* 7:23 */ "morekeys_c", + /* 7:24 */ "morekeys_c", /* 8:23 */ "double_quotes", /* 9:22 */ "single_quotes", - /* 10:20 */ "morekeys_s", + /* 10:21 */ "morekeys_s", /* 11:18 */ "keyspec_currency", /* 12:16 */ "morekeys_y", - /* 13:14 */ "morekeys_z", - /* 14:13 */ "morekeys_d", + /* 13:15 */ "morekeys_z", + /* 14:14 */ "morekeys_d", /* 15:10 */ "morekeys_t", /* 16:10 */ "morekeys_l", /* 17: 9 */ "morekeys_g", @@ -193,30 +193,30 @@ public final class KeyboardTextsTable { /* 107: 2 */ "keyspec_symbols_percent", /* 108: 2 */ "morekeys_symbols_semicolon", /* 109: 2 */ "morekeys_symbols_percent", - /* 110: 1 */ "morekeys_v", - /* 111: 1 */ "morekeys_j", - /* 112: 1 */ "morekeys_q", - /* 113: 1 */ "morekeys_x", - /* 114: 1 */ "keyspec_q", - /* 115: 1 */ "keyspec_w", - /* 116: 1 */ "keyspec_y", - /* 117: 1 */ "keyspec_x", - /* 118: 1 */ "morekeys_east_slavic_row2_11", - /* 119: 1 */ "morekeys_cyrillic_ka", - /* 120: 1 */ "morekeys_cyrillic_a", - /* 121: 1 */ "morekeys_currency_dollar", - /* 122: 1 */ "morekeys_plus", - /* 123: 1 */ "morekeys_less_than", - /* 124: 1 */ "morekeys_greater_than", - /* 125: 1 */ "morekeys_exclamation", - /* 126: 1 */ "label_go_key", - /* 127: 1 */ "label_send_key", - /* 128: 1 */ "label_next_key", - /* 129: 1 */ "label_done_key", - /* 130: 1 */ "label_search_key", - /* 131: 1 */ "label_previous_key", - /* 132: 1 */ "label_pause_key", - /* 133: 1 */ "label_wait_key", + /* 110: 2 */ "label_go_key", + /* 111: 2 */ "label_send_key", + /* 112: 2 */ "label_next_key", + /* 113: 2 */ "label_done_key", + /* 114: 2 */ "label_search_key", + /* 115: 2 */ "label_previous_key", + /* 116: 2 */ "label_pause_key", + /* 117: 2 */ "label_wait_key", + /* 118: 1 */ "morekeys_v", + /* 119: 1 */ "morekeys_j", + /* 120: 1 */ "morekeys_q", + /* 121: 1 */ "morekeys_x", + /* 122: 1 */ "keyspec_q", + /* 123: 1 */ "keyspec_w", + /* 124: 1 */ "keyspec_y", + /* 125: 1 */ "keyspec_x", + /* 126: 1 */ "morekeys_east_slavic_row2_11", + /* 127: 1 */ "morekeys_cyrillic_ka", + /* 128: 1 */ "morekeys_cyrillic_a", + /* 129: 1 */ "morekeys_currency_dollar", + /* 130: 1 */ "morekeys_plus", + /* 131: 1 */ "morekeys_less_than", + /* 132: 1 */ "morekeys_greater_than", + /* 133: 1 */ "morekeys_exclamation", /* 134: 0 */ "morekeys_currency_generic", /* 135: 0 */ "morekeys_symbols_1", /* 136: 0 */ "morekeys_symbols_2", @@ -365,6 +365,14 @@ public final class KeyboardTextsTable { /* morekeys_symbols_semicolon */ EMPTY, // U+2030: "‰" PER MILLE SIGN /* morekeys_symbols_percent */ "\u2030", + /* label_go_key */ "!string/label_go_key", + /* label_send_key */ "!string/label_send_key", + /* label_next_key */ "!string/label_next_key", + /* label_done_key */ "!string/label_done_key", + /* label_search_key */ "!string/label_search_key", + /* label_previous_key */ "!string/label_previous_key", + /* label_pause_key */ "!string/label_pause_key", + /* label_wait_key */ "!string/label_wait_key", /* morekeys_v ~ */ EMPTY, EMPTY, EMPTY, EMPTY, /* ~ morekeys_x */ @@ -387,14 +395,6 @@ public final class KeyboardTextsTable { /* morekeys_greater_than */ "!fixedColumnOrder!3,!text/keyspec_right_single_angle_quote,!text/keyspec_greater_than_equal,!text/keyspec_right_double_angle_quote", // U+00A1: "¡" INVERTED EXCLAMATION MARK /* morekeys_exclamation */ "\u00A1", - /* label_go_key */ "!string/label_go_key", - /* label_send_key */ "!string/label_send_key", - /* label_next_key */ "!string/label_next_key", - /* label_done_key */ "!string/label_done_key", - /* label_search_key */ "!string/label_search_key", - /* label_previous_key */ "!string/label_previous_key", - /* label_pause_key */ "!string/label_pause_key", - /* label_wait_key */ "!string/label_wait_key", /* morekeys_currency_generic */ "$,\u00A2,\u20AC,\u00A3,\u00A5,\u20B1", // U+00B9: "¹" SUPERSCRIPT ONE // U+00BD: "½" VULGAR FRACTION ONE HALF @@ -952,20 +952,24 @@ public final class KeyboardTextsTable { /* Locale da: Danish */ private static final String[] TEXTS_da = { + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+00E6: "æ" LATIN SMALL LETTER AE // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON - /* morekeys_a */ "\u00E1,\u00E4,\u00E0,\u00E2,\u00E3,\u0101", + /* morekeys_a */ "\u00E5,\u00E6,\u00E1,\u00E4,\u00E0,\u00E2,\u00E3,\u0101", + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE // U+0153: "œ" LATIN SMALL LIGATURE OE // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON - /* morekeys_o */ "\u00F3,\u00F4,\u00F2,\u00F5,\u0153,\u014D", + /* morekeys_o */ "\u00F8,\u00F6,\u00F3,\u00F4,\u00F2,\u00F5,\u0153,\u014D", // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS /* morekeys_e */ "\u00E9,\u00EB", @@ -1281,8 +1285,9 @@ public final class KeyboardTextsTable { // U+0135: "ĵ" LATIN SMALL LETTER J WITH CIRCUMFLEX /* keyspec_spanish_row2_10 */ "\u0135", /* morekeys_bullet ~ */ - null, null, null, null, null, null, null, null, null, null, null, null, null, null, - /* ~ morekeys_symbols_percent */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, + /* ~ label_wait_key */ // U+0175: "ŵ" LATIN SMALL LETTER W WITH CIRCUMFLEX /* morekeys_v */ "w,\u0175", /* morekeys_j */ null, @@ -1649,8 +1654,9 @@ public final class KeyboardTextsTable { /* morekeys_symbols_semicolon */ ";", // U+2030: "‰" PER MILLE SIGN /* morekeys_symbols_percent */ "\\%,\u2030", - /* morekeys_v ~ */ - null, null, null, null, null, null, null, null, null, null, null, null, null, + /* label_go_key ~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, /* ~ morekeys_plus */ // U+2264: "≤" LESS-THAN OR EQUAL TO // U+2265: "≥" GREATER-THAN EQUAL TO @@ -1664,13 +1670,16 @@ public final class KeyboardTextsTable { /* Locale fi: Finnish */ private static final String[] TEXTS_fi = { + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE // U+00E6: "æ" LATIN SMALL LETTER AE // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON - /* morekeys_a */ "\u00E6,\u00E0,\u00E1,\u00E2,\u00E3,\u0101", + /* morekeys_a */ "\u00E4,\u00E5,\u00E6,\u00E0,\u00E1,\u00E2,\u00E3,\u0101", + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE @@ -1678,7 +1687,7 @@ public final class KeyboardTextsTable { // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE // U+0153: "œ" LATIN SMALL LIGATURE OE // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON - /* morekeys_o */ "\u00F8,\u00F4,\u00F2,\u00F3,\u00F5,\u0153,\u014D", + /* morekeys_o */ "\u00F6,\u00F8,\u00F4,\u00F2,\u00F3,\u00F5,\u0153,\u014D", /* morekeys_e */ null, // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS /* morekeys_u */ "\u00FC", @@ -1908,9 +1917,8 @@ public final class KeyboardTextsTable { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, - /* ~ morekeys_exclamation */ + null, null, null, null, null, null, null, null, + /* ~ morekeys_symbols_percent */ /* label_go_key */ "Go", /* label_send_key */ "Send", /* label_next_key */ "Next", @@ -2063,7 +2071,7 @@ public final class KeyboardTextsTable { /* keyspec_tablet_period */ "\u0589", /* keyhintlabel_tablet_period ~ */ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, /* ~ morekeys_greater_than */ // U+055C: "՜" ARMENIAN EXCLAMATION MARK // U+00A1: "¡" INVERTED EXCLAMATION MARK @@ -2244,6 +2252,7 @@ public final class KeyboardTextsTable { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, /* ~ morekeys_currency_dollar */ // U+00B1: "±" PLUS-MINUS SIGN // U+FB29: "﬩" HEBREW LETTER ALTERNATIVE PLUS SIGN @@ -2315,7 +2324,8 @@ public final class KeyboardTextsTable { /* morekeys_cyrillic_o */ "\u04E9", /* morekeys_cyrillic_i ~ */ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, /* ~ keyspec_x */ // U+04BB: "һ" CYRILLIC SMALL LETTER SHHA /* morekeys_east_slavic_row2_11 */ "\u04BB", @@ -2343,7 +2353,8 @@ public final class KeyboardTextsTable { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, /* ~ morekeys_cyrillic_a */ // U+17DB: "៛" KHMER CURRENCY SYMBOL RIEL /* morekeys_currency_dollar */ "\u17DB,\u00A2,\u00A3,\u20AC,\u00A5,\u20B1", @@ -2780,21 +2791,24 @@ public final class KeyboardTextsTable { /* Locale nb: Norwegian Bokmål */ private static final String[] TEXTS_nb = { - // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+00E6: "æ" LATIN SMALL LETTER AE // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON - /* morekeys_a */ "\u00E0,\u00E4,\u00E1,\u00E2,\u00E3,\u0101", + /* morekeys_a */ "\u00E5,\u00E6,\u00E4,\u00E0,\u00E1,\u00E2,\u00E3,\u0101", + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE - // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE // U+0153: "œ" LATIN SMALL LIGATURE OE // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON - /* morekeys_o */ "\u00F4,\u00F2,\u00F3,\u00F6,\u00F5,\u0153,\u014D", + /* morekeys_o */ "\u00F8,\u00F6,\u00F4,\u00F2,\u00F3,\u00F5,\u0153,\u014D", // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX @@ -3332,20 +3346,69 @@ public final class KeyboardTextsTable { /* keyspec_south_slavic_row3_8 */ "\u0452", }; + /* Locale sr_ZZ: Serbian (ZZ) */ + private static final String[] TEXTS_sr_ZZ = { + /* morekeys_a */ null, + /* morekeys_o */ null, + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + /* morekeys_e */ "\u00E8", + /* morekeys_u */ null, + /* keylabel_to_alpha */ null, + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + /* morekeys_i */ "\u00EC", + /* morekeys_n */ null, + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + /* morekeys_c */ "\u010D,\u0107,%", + /* double_quotes */ null, + /* single_quotes */ null, + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + /* morekeys_s */ "\u0161,%", + /* keyspec_currency */ null, + /* morekeys_y */ null, + // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON + /* morekeys_z */ "\u017E,%", + // U+0111: "đ" LATIN SMALL LETTER D WITH STROKE + /* morekeys_d */ "\u0111,%", + /* morekeys_t ~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, + /* ~ morekeys_symbols_percent */ + /* label_go_key */ "Idi", + /* label_send_key */ "\u0160alji", + /* label_next_key */ "Sled", + /* label_done_key */ "Gotov", + /* label_search_key */ "Tra\u017Ei", + /* label_previous_key */ "Preth", + /* label_pause_key */ "Pauza", + /* label_wait_key */ "\u010Cekaj", + }; + /* Locale sv: Swedish */ private static final String[] TEXTS_sv = { + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E5: "å" LATIN SMALL LETTER A WITH RING + // U+00E6: "æ" LATIN SMALL LETTER AE // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE - /* morekeys_a */ "\u00E1,\u00E0,\u00E2,\u0105,\u00E3", + /* morekeys_a */ "\u00E4,\u00E5,\u00E6,\u00E1,\u00E0,\u00E2,\u0105,\u00E3", + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+0153: "œ" LATIN SMALL LIGATURE OE // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON - /* morekeys_o */ "\u00F3,\u00F2,\u00F4,\u00F5,\u014D", + /* morekeys_o */ "\u00F6,\u00F8,\u0153,\u00F3,\u00F2,\u00F4,\u00F5,\u014D", // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX @@ -3978,7 +4041,8 @@ public final class KeyboardTextsTable { /* morekeys_w */ "\u0175", /* morekeys_east_slavic_row2_2 ~ */ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, /* ~ morekeys_v */ // U+0135: "ĵ" LATIN SMALL LETTER J WITH CIRCUMFLEX /* morekeys_j */ "\u0135", @@ -3999,25 +4063,25 @@ public final class KeyboardTextsTable { "de" , TEXTS_de, /* 16/ 62 German */ "el" , TEXTS_el, /* 1/ 5 Greek */ "en" , TEXTS_en, /* 8/ 11 English */ - "eo" , TEXTS_eo, /* 26/118 Esperanto */ + "eo" , TEXTS_eo, /* 26/126 Esperanto */ "es" , TEXTS_es, /* 8/ 55 Spanish */ "et_EE" , TEXTS_et_EE, /* 22/ 27 Estonian (Estonia) */ "eu_ES" , TEXTS_eu_ES, /* 7/ 8 Basque (Spain) */ - "fa" , TEXTS_fa, /* 58/125 Persian */ + "fa" , TEXTS_fa, /* 58/133 Persian */ "fi" , TEXTS_fi, /* 10/ 54 Finnish */ "fr" , TEXTS_fr, /* 13/ 62 French */ "gl_ES" , TEXTS_gl_ES, /* 7/ 8 Gallegan (Spain) */ "hi" , TEXTS_hi, /* 23/ 53 Hindi */ - "hi_ZZ" , TEXTS_hi_ZZ, /* 9/134 Hindi (ZZ) */ + "hi_ZZ" , TEXTS_hi_ZZ, /* 9/118 Hindi (ZZ) */ "hr" , TEXTS_hr, /* 9/ 20 Croatian */ "hu" , TEXTS_hu, /* 9/ 20 Hungarian */ - "hy_AM" , TEXTS_hy_AM, /* 9/126 Armenian (Armenia) */ + "hy_AM" , TEXTS_hy_AM, /* 9/134 Armenian (Armenia) */ "is" , TEXTS_is, /* 10/ 16 Icelandic */ "it" , TEXTS_it, /* 11/ 62 Italian */ - "iw" , TEXTS_iw, /* 20/123 Hebrew */ + "iw" , TEXTS_iw, /* 20/131 Hebrew */ "ka_GE" , TEXTS_ka_GE, /* 3/ 10 Georgian (Georgia) */ - "kk" , TEXTS_kk, /* 15/121 Kazakh */ - "km_KH" , TEXTS_km_KH, /* 2/122 Khmer (Cambodia) */ + "kk" , TEXTS_kk, /* 15/129 Kazakh */ + "km_KH" , TEXTS_km_KH, /* 2/130 Khmer (Cambodia) */ "kn_IN" , TEXTS_kn_IN, /* 2/ 12 Kannada (India) */ "ky" , TEXTS_ky, /* 10/ 89 Kirghiz */ "lo_LA" , TEXTS_lo_LA, /* 2/ 12 Lao (Laos) */ @@ -4040,6 +4104,7 @@ public final class KeyboardTextsTable { "sk" , TEXTS_sk, /* 20/ 22 Slovak */ "sl" , TEXTS_sl, /* 8/ 20 Slovenian */ "sr" , TEXTS_sr, /* 11/ 94 Serbian */ + "sr_ZZ" , TEXTS_sr_ZZ, /* 14/118 Serbian (ZZ) */ "sv" , TEXTS_sv, /* 21/ 54 Swedish */ "sw" , TEXTS_sw, /* 9/ 18 Swahili */ "ta_IN" , TEXTS_ta_IN, /* 2/ 12 Tamil (India) */ @@ -4052,7 +4117,7 @@ public final class KeyboardTextsTable { "uk" , TEXTS_uk, /* 11/ 88 Ukrainian */ "vi" , TEXTS_vi, /* 8/ 15 Vietnamese */ "zu" , TEXTS_zu, /* 8/ 11 Zulu */ - "zz" , TEXTS_zz, /* 19/112 Alphabet */ + "zz" , TEXTS_zz, /* 19/120 Alphabet */ }; static { diff --git a/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java b/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java index 764159c3d..0cd031e5f 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java +++ b/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java @@ -149,8 +149,13 @@ public final class MoreKeySpec { } } final int size = filteredMoreKeys.size(); - return (moreKeys.length == size) ? moreKeys - : filteredMoreKeys.toArray(new MoreKeySpec[size]); + if (size == moreKeys.length) { + return moreKeys; + } + if (size == 0) { + return null; + } + return filteredMoreKeys.toArray(new MoreKeySpec[size]); } private static final boolean DEBUG = DebugFlags.DEBUG_ENABLED; diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index b164c1779..1da33ed3f 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -255,7 +255,7 @@ public final class BinaryDictionary extends Dictionary { @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, - final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, + final NgramContext ngramContext, final ProximityInfo proximityInfo, final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId, final float weightForLocale, final float[] inOutWeightOfLangModelVsSpatialModel) { @@ -264,7 +264,7 @@ public final class BinaryDictionary extends Dictionary { } final DicTraverseSession session = getTraverseSession(sessionId); Arrays.fill(session.mInputCodePoints, Constants.NOT_A_CODE); - prevWordsInfo.outputToArray(session.mPrevWordCodePointArrays, + ngramContext.outputToArray(session.mPrevWordCodePointArrays, session.mIsBeginningOfSentenceArray); final InputPointers inputPointers = composer.getInputPointers(); final boolean isGesture = composer.isBatchMode(); @@ -299,7 +299,7 @@ public final class BinaryDictionary extends Dictionary { inputPointers.getYCoordinates(), inputPointers.getTimes(), inputPointers.getPointerIds(), session.mInputCodePoints, inputSize, session.mNativeSuggestOptions.getOptions(), session.mPrevWordCodePointArrays, - session.mIsBeginningOfSentenceArray, prevWordsInfo.getPrevWordCount(), + session.mIsBeginningOfSentenceArray, ngramContext.getPrevWordCount(), session.mOutputSuggestionCount, session.mOutputCodePoints, session.mOutputScores, session.mSpaceIndices, session.mOutputTypes, session.mOutputAutoCommitFirstWordConfidence, @@ -357,17 +357,17 @@ public final class BinaryDictionary extends Dictionary { } @UsedForTesting - public boolean isValidNgram(final PrevWordsInfo prevWordsInfo, final String word) { - return getNgramProbability(prevWordsInfo, word) != NOT_A_PROBABILITY; + public boolean isValidNgram(final NgramContext ngramContext, final String word) { + return getNgramProbability(ngramContext, word) != NOT_A_PROBABILITY; } - public int getNgramProbability(final PrevWordsInfo prevWordsInfo, final String word) { - if (!prevWordsInfo.isValid() || TextUtils.isEmpty(word)) { + public int getNgramProbability(final NgramContext ngramContext, final String word) { + if (!ngramContext.isValid() || TextUtils.isEmpty(word)) { return NOT_A_PROBABILITY; } - final int[][] prevWordCodePointArrays = new int[prevWordsInfo.getPrevWordCount()][]; - final boolean[] isBeginningOfSentenceArray = new boolean[prevWordsInfo.getPrevWordCount()]; - prevWordsInfo.outputToArray(prevWordCodePointArrays, isBeginningOfSentenceArray); + final int[][] prevWordCodePointArrays = new int[ngramContext.getPrevWordCount()][]; + final boolean[] isBeginningOfSentenceArray = new boolean[ngramContext.getPrevWordCount()]; + ngramContext.outputToArray(prevWordCodePointArrays, isBeginningOfSentenceArray); final int[] wordCodePoints = StringUtils.toCodePointArray(word); return getNgramProbabilityNative(mNativeDict, prevWordCodePointArrays, isBeginningOfSentenceArray, wordCodePoints); @@ -456,14 +456,14 @@ public final class BinaryDictionary extends Dictionary { } // Add an n-gram entry to the binary dictionary with timestamp in native code. - public boolean addNgramEntry(final PrevWordsInfo prevWordsInfo, final String word, + public boolean addNgramEntry(final NgramContext ngramContext, final String word, final int probability, final int timestamp) { - if (!prevWordsInfo.isValid() || TextUtils.isEmpty(word)) { + if (!ngramContext.isValid() || TextUtils.isEmpty(word)) { return false; } - final int[][] prevWordCodePointArrays = new int[prevWordsInfo.getPrevWordCount()][]; - final boolean[] isBeginningOfSentenceArray = new boolean[prevWordsInfo.getPrevWordCount()]; - prevWordsInfo.outputToArray(prevWordCodePointArrays, isBeginningOfSentenceArray); + final int[][] prevWordCodePointArrays = new int[ngramContext.getPrevWordCount()][]; + final boolean[] isBeginningOfSentenceArray = new boolean[ngramContext.getPrevWordCount()]; + ngramContext.outputToArray(prevWordCodePointArrays, isBeginningOfSentenceArray); final int[] wordCodePoints = StringUtils.toCodePointArray(word); if (!addNgramEntryNative(mNativeDict, prevWordCodePointArrays, isBeginningOfSentenceArray, wordCodePoints, probability, timestamp)) { @@ -474,13 +474,13 @@ public final class BinaryDictionary extends Dictionary { } // Remove an n-gram entry from the binary dictionary in native code. - public boolean removeNgramEntry(final PrevWordsInfo prevWordsInfo, final String word) { - if (!prevWordsInfo.isValid() || TextUtils.isEmpty(word)) { + public boolean removeNgramEntry(final NgramContext ngramContext, final String word) { + if (!ngramContext.isValid() || TextUtils.isEmpty(word)) { return false; } - final int[][] prevWordCodePointArrays = new int[prevWordsInfo.getPrevWordCount()][]; - final boolean[] isBeginningOfSentenceArray = new boolean[prevWordsInfo.getPrevWordCount()]; - prevWordsInfo.outputToArray(prevWordCodePointArrays, isBeginningOfSentenceArray); + final int[][] prevWordCodePointArrays = new int[ngramContext.getPrevWordCount()][]; + final boolean[] isBeginningOfSentenceArray = new boolean[ngramContext.getPrevWordCount()]; + ngramContext.outputToArray(prevWordCodePointArrays, isBeginningOfSentenceArray); final int[] wordCodePoints = StringUtils.toCodePointArray(word); if (!removeNgramEntryNative(mNativeDict, prevWordCodePointArrays, isBeginningOfSentenceArray, wordCodePoints)) { diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java index 162a209e3..78c6cbd24 100644 --- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java @@ -218,7 +218,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { */ private void addNameLocked(final String name) { int len = StringUtils.codePointCount(name); - PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; + NgramContext ngramContext = NgramContext.EMPTY_PREV_WORDS_INFO; // TODO: Better tokenization for non-Latin writing systems for (int i = 0; i < len; i++) { if (Character.isLetter(name.codePointAt(i))) { @@ -233,19 +233,19 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { final int wordLen = StringUtils.codePointCount(word); if (wordLen <= MAX_WORD_LENGTH && wordLen > 1) { if (DEBUG) { - Log.d(TAG, "addName " + name + ", " + word + ", " + prevWordsInfo); + Log.d(TAG, "addName " + name + ", " + word + ", " + ngramContext); } runGCIfRequiredLocked(true /* mindsBlockByGC */); addUnigramLocked(word, FREQUENCY_FOR_CONTACTS, null /* shortcut */, 0 /* shortcutFreq */, false /* isNotAWord */, false /* isBlacklisted */, BinaryDictionary.NOT_A_VALID_TIMESTAMP); - if (!prevWordsInfo.isValid() && mUseFirstLastBigrams) { + if (!ngramContext.isValid() && mUseFirstLastBigrams) { runGCIfRequiredLocked(true /* mindsBlockByGC */); - addNgramEntryLocked(prevWordsInfo, word, FREQUENCY_FOR_CONTACTS_BIGRAM, + addNgramEntryLocked(ngramContext, word, FREQUENCY_FOR_CONTACTS_BIGRAM, BinaryDictionary.NOT_A_VALID_TIMESTAMP); } - prevWordsInfo = prevWordsInfo.getNextPrevWordsInfo( - new PrevWordsInfo.WordInfo(word)); + ngramContext = ngramContext.getNextNgramContext( + new NgramContext.WordInfo(word)); } } } diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java index b58a52b41..43561ba4b 100644 --- a/java/src/com/android/inputmethod/latin/Dictionary.java +++ b/java/src/com/android/inputmethod/latin/Dictionary.java @@ -81,10 +81,9 @@ public abstract class Dictionary { } /** - * Searches for suggestions for a given context. For the moment the context is only the - * previous word. + * Searches for suggestions for a given context. * @param composer the key sequence to match with coordinate info, as a WordComposer - * @param prevWordsInfo the information of previous words. + * @param ngramContext the context for n-gram. * @param proximityInfo the object for key proximity. May be ignored by some implementations. * @param settingsValuesForSuggestion the settings values used for the suggestion. * @param sessionId the session id. @@ -96,7 +95,7 @@ public abstract class Dictionary { * @return the list of suggestions (possibly null if none) */ abstract public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, - final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, + final NgramContext ngramContext, final ProximityInfo proximityInfo, final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId, final float weightForLocale, final float[] inOutWeightOfLangModelVsSpatialModel); @@ -191,7 +190,7 @@ public abstract class Dictionary { @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, - final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, + final NgramContext ngramContext, final ProximityInfo proximityInfo, final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId, final float weightForLocale, final float[] inOutWeightOfLangModelVsSpatialModel) { diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java index b26b37817..a6d7205e2 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java +++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java @@ -60,7 +60,7 @@ public final class DictionaryCollection extends Dictionary { @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, - final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, + final NgramContext ngramContext, final ProximityInfo proximityInfo, final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId, final float weightForLocale, final float[] inOutWeightOfLangModelVsSpatialModel) { @@ -69,13 +69,13 @@ public final class DictionaryCollection extends Dictionary { // To avoid creating unnecessary objects, we get the list out of the first // dictionary and add the rest to it if not null, hence the get(0) ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getSuggestions(composer, - prevWordsInfo, proximityInfo, settingsValuesForSuggestion, sessionId, + ngramContext, proximityInfo, settingsValuesForSuggestion, sessionId, weightForLocale, inOutWeightOfLangModelVsSpatialModel); if (null == suggestions) suggestions = new ArrayList<>(); final int length = dictionaries.size(); for (int i = 1; i < length; ++ i) { final ArrayList<SuggestedWordInfo> sugg = dictionaries.get(i).getSuggestions(composer, - prevWordsInfo, proximityInfo, settingsValuesForSuggestion, sessionId, + ngramContext, proximityInfo, settingsValuesForSuggestion, sessionId, weightForLocale, inOutWeightOfLangModelVsSpatialModel); if (null != sugg) suggestions.addAll(sugg); } diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java index aa15bd6bf..6dc1e8273 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java @@ -25,7 +25,7 @@ import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.ExpandableBinaryDictionary.AddMultipleDictionaryEntriesCallback; -import com.android.inputmethod.latin.PrevWordsInfo.WordInfo; +import com.android.inputmethod.latin.NgramContext.WordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.personalization.ContextualDictionary; import com.android.inputmethod.latin.personalization.PersonalizationDataChunk; @@ -509,23 +509,23 @@ public class DictionaryFacilitator { } public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized, - final PrevWordsInfo prevWordsInfo, final int timeStampInSeconds, + final NgramContext ngramContext, final int timeStampInSeconds, final boolean blockPotentiallyOffensive) { final DictionaryGroup dictionaryGroup = getDictionaryGroupForActiveLanguage(); final String[] words = suggestion.split(Constants.WORD_SEPARATOR); - PrevWordsInfo prevWordsInfoForCurrentWord = prevWordsInfo; + NgramContext ngramContextForCurrentWord = ngramContext; for (int i = 0; i < words.length; i++) { final String currentWord = words[i]; final boolean wasCurrentWordAutoCapitalized = (i == 0) ? wasAutoCapitalized : false; - addWordToUserHistory(dictionaryGroup, prevWordsInfoForCurrentWord, currentWord, + addWordToUserHistory(dictionaryGroup, ngramContextForCurrentWord, currentWord, wasCurrentWordAutoCapitalized, timeStampInSeconds, blockPotentiallyOffensive); - prevWordsInfoForCurrentWord = - prevWordsInfoForCurrentWord.getNextPrevWordsInfo(new WordInfo(currentWord)); + ngramContextForCurrentWord = + ngramContextForCurrentWord.getNextNgramContext(new WordInfo(currentWord)); } } private void addWordToUserHistory(final DictionaryGroup dictionaryGroup, - final PrevWordsInfo prevWordsInfo, final String word, final boolean wasAutoCapitalized, + final NgramContext ngramContext, final String word, final boolean wasAutoCapitalized, final int timeStampInSeconds, final boolean blockPotentiallyOffensive) { final ExpandableBinaryDictionary userHistoryDictionary = dictionaryGroup.getSubDict(Dictionary.TYPE_USER_HISTORY); @@ -571,7 +571,7 @@ public class DictionaryFacilitator { // We demote unrecognized words (frequency < 0, below) by specifying them as "invalid". // We don't add words with 0-frequency (assuming they would be profanity etc.). final boolean isValid = maxFreq > 0; - UserHistoryDictionary.addToDictionary(userHistoryDictionary, prevWordsInfo, secondWord, + UserHistoryDictionary.addToDictionary(userHistoryDictionary, ngramContext, secondWord, isValid, timeStampInSeconds, new DistracterFilterCheckingIsInDictionary( mDistracterFilter, userHistoryDictionary)); @@ -593,12 +593,11 @@ public class DictionaryFacilitator { // TODO: Revise the way to fusion suggestion results. public SuggestionResults getSuggestionResults(final WordComposer composer, - final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, + final NgramContext ngramContext, final ProximityInfo proximityInfo, final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId) { final DictionaryGroup[] dictionaryGroups = mDictionaryGroups; final SuggestionResults suggestionResults = new SuggestionResults( - SuggestedWords.MAX_SUGGESTIONS, - prevWordsInfo.mPrevWordsInfo[0].mIsBeginningOfSentence); + SuggestedWords.MAX_SUGGESTIONS, ngramContext.isBeginningOfSentenceContext()); final float[] weightOfLangModelVsSpatialModel = new float[] { Dictionary.NOT_A_WEIGHT_OF_LANG_MODEL_VS_SPATIAL_MODEL }; for (final DictionaryGroup dictionaryGroup : dictionaryGroups) { @@ -606,7 +605,7 @@ public class DictionaryFacilitator { final Dictionary dictionary = dictionaryGroup.getDict(dictType); if (null == dictionary) continue; final ArrayList<SuggestedWordInfo> dictionarySuggestions = - dictionary.getSuggestions(composer, prevWordsInfo, proximityInfo, + dictionary.getSuggestions(composer, ngramContext, proximityInfo, settingsValuesForSuggestion, sessionId, dictionaryGroup.mWeightForLocale, weightOfLangModelVsSpatialModel); if (null == dictionarySuggestions) continue; @@ -720,7 +719,7 @@ public class DictionaryFacilitator { if (contextualDict == null) { return; } - PrevWordsInfo prevWordsInfo = PrevWordsInfo.BEGINNING_OF_SENTENCE; + NgramContext ngramContext = NgramContext.BEGINNING_OF_SENTENCE; for (int i = 0; i < phrase.length; i++) { final String[] subPhrase = Arrays.copyOfRange(phrase, i /* start */, phrase.length); final String subPhraseStr = TextUtils.join(Constants.WORD_SEPARATOR, subPhrase); @@ -730,7 +729,7 @@ public class DictionaryFacilitator { false /* isNotAWord */, false /* isBlacklisted */, BinaryDictionary.NOT_A_VALID_TIMESTAMP, DistracterFilter.EMPTY_DISTRACTER_FILTER); - contextualDict.addNgramEntry(prevWordsInfo, subPhraseStr, + contextualDict.addNgramEntry(ngramContext, subPhraseStr, bigramProbabilityForPhrases, BinaryDictionary.NOT_A_VALID_TIMESTAMP); if (i < phrase.length - 1) { @@ -740,11 +739,11 @@ public class DictionaryFacilitator { false /* isNotAWord */, false /* isBlacklisted */, BinaryDictionary.NOT_A_VALID_TIMESTAMP, DistracterFilter.EMPTY_DISTRACTER_FILTER); - contextualDict.addNgramEntry(prevWordsInfo, phrase[i], + contextualDict.addNgramEntry(ngramContext, phrase[i], bigramProbabilityForWords, BinaryDictionary.NOT_A_VALID_TIMESTAMP); } - prevWordsInfo = - prevWordsInfo.getNextPrevWordsInfo(new PrevWordsInfo.WordInfo(phrase[i])); + ngramContext = + ngramContext.getNextNgramContext(new NgramContext.WordInfo(phrase[i])); } } diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index 68f2b62f0..1bdadc30b 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -305,7 +305,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { @Override public Boolean call() throws Exception { return !distracterFilter.isDistracterToWordsInDictionaries( - PrevWordsInfo.EMPTY_PREV_WORDS_INFO, word, mLocale); + NgramContext.EMPTY_PREV_WORDS_INFO, word, mLocale); } }, new Runnable() { @@ -354,7 +354,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { /** * Adds n-gram information of a word to the dictionary. May overwrite an existing entry. */ - public void addNgramEntry(final PrevWordsInfo prevWordsInfo, final String word, + public void addNgramEntry(final NgramContext ngramContext, final String word, final int frequency, final int timestamp) { reloadDictionaryIfRequired(); asyncExecuteTaskWithWriteLock(new Runnable() { @@ -364,17 +364,17 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { return; } runGCIfRequiredLocked(true /* mindsBlockByGC */); - addNgramEntryLocked(prevWordsInfo, word, frequency, timestamp); + addNgramEntryLocked(ngramContext, word, frequency, timestamp); } }); } - protected void addNgramEntryLocked(final PrevWordsInfo prevWordsInfo, final String word, + protected void addNgramEntryLocked(final NgramContext ngramContext, final String word, final int frequency, final int timestamp) { - if (!mBinaryDictionary.addNgramEntry(prevWordsInfo, word, frequency, timestamp)) { + if (!mBinaryDictionary.addNgramEntry(ngramContext, word, frequency, timestamp)) { if (DEBUG) { Log.i(TAG, "Cannot add n-gram entry."); - Log.i(TAG, " PrevWordsInfo: " + prevWordsInfo + ", word: " + word); + Log.i(TAG, " NgramContext: " + ngramContext + ", word: " + word); } } } @@ -383,7 +383,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { * Dynamically remove the n-gram entry in the dictionary. */ @UsedForTesting - public void removeNgramDynamically(final PrevWordsInfo prevWordsInfo, final String word) { + public void removeNgramDynamically(final NgramContext ngramContext, final String word) { reloadDictionaryIfRequired(); asyncExecuteTaskWithWriteLock(new Runnable() { @Override @@ -392,10 +392,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { return; } runGCIfRequiredLocked(true /* mindsBlockByGC */); - if (!mBinaryDictionary.removeNgramEntry(prevWordsInfo, word)) { + if (!mBinaryDictionary.removeNgramEntry(ngramContext, word)) { if (DEBUG) { Log.i(TAG, "Cannot remove n-gram entry."); - Log.i(TAG, " PrevWordsInfo: " + prevWordsInfo + ", word: " + word); + Log.i(TAG, " NgramContext: " + ngramContext + ", word: " + word); } } } @@ -434,7 +434,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, - final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, + final NgramContext ngramContext, final ProximityInfo proximityInfo, final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId, final float weightForLocale, final float[] inOutWeightOfLangModelVsSpatialModel) { reloadDictionaryIfRequired(); @@ -447,7 +447,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { return null; } final ArrayList<SuggestedWordInfo> suggestions = - mBinaryDictionary.getSuggestions(composer, prevWordsInfo, proximityInfo, + mBinaryDictionary.getSuggestions(composer, ngramContext, proximityInfo, settingsValuesForSuggestion, sessionId, weightForLocale, inOutWeightOfLangModelVsSpatialModel); if (mBinaryDictionary.isCorrupted()) { @@ -519,9 +519,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { } - protected boolean isValidNgramLocked(final PrevWordsInfo prevWordsInfo, final String word) { + protected boolean isValidNgramLocked(final NgramContext ngramContext, final String word) { if (mBinaryDictionary == null) return false; - return mBinaryDictionary.isValidNgram(prevWordsInfo, word); + return mBinaryDictionary.isValidNgram(ngramContext, word); } /** diff --git a/java/src/com/android/inputmethod/latin/LastComposedWord.java b/java/src/com/android/inputmethod/latin/LastComposedWord.java index 8cbf8379b..f3f736fbc 100644 --- a/java/src/com/android/inputmethod/latin/LastComposedWord.java +++ b/java/src/com/android/inputmethod/latin/LastComposedWord.java @@ -48,7 +48,7 @@ public final class LastComposedWord { public final String mTypedWord; public final CharSequence mCommittedWord; public final String mSeparatorString; - public final PrevWordsInfo mPrevWordsInfo; + public final NgramContext mNgramContext; public final int mCapitalizedMode; public final InputPointers mInputPointers = new InputPointers(Constants.DICTIONARY_MAX_WORD_LENGTH); @@ -64,7 +64,7 @@ public final class LastComposedWord { public LastComposedWord(final ArrayList<Event> events, final InputPointers inputPointers, final String typedWord, final CharSequence committedWord, final String separatorString, - final PrevWordsInfo prevWordsInfo, final int capitalizedMode) { + final NgramContext ngramContext, final int capitalizedMode) { if (inputPointers != null) { mInputPointers.copy(inputPointers); } @@ -73,7 +73,7 @@ public final class LastComposedWord { mCommittedWord = committedWord; mSeparatorString = separatorString; mActive = true; - mPrevWordsInfo = prevWordsInfo; + mNgramContext = ngramContext; mCapitalizedMode = capitalizedMode; } diff --git a/java/src/com/android/inputmethod/latin/PrevWordsInfo.java b/java/src/com/android/inputmethod/latin/NgramContext.java index 1b7e8f96d..c35c6e2c8 100644 --- a/java/src/com/android/inputmethod/latin/PrevWordsInfo.java +++ b/java/src/com/android/inputmethod/latin/NgramContext.java @@ -18,6 +18,7 @@ package com.android.inputmethod.latin; import android.text.TextUtils; +import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.utils.StringUtils; import java.util.Arrays; @@ -26,11 +27,11 @@ import java.util.Arrays; * Class to represent information of previous words. This class is used to add n-gram entries * into binary dictionaries, to get predictions, and to get suggestions. */ -public class PrevWordsInfo { - public static final PrevWordsInfo EMPTY_PREV_WORDS_INFO = - new PrevWordsInfo(WordInfo.EMPTY_WORD_INFO); - public static final PrevWordsInfo BEGINNING_OF_SENTENCE = - new PrevWordsInfo(WordInfo.BEGINNING_OF_SENTENCE); +public class NgramContext { + public static final NgramContext EMPTY_PREV_WORDS_INFO = + new NgramContext(WordInfo.EMPTY_WORD_INFO); + public static final NgramContext BEGINNING_OF_SENTENCE = + new NgramContext(WordInfo.BEGINNING_OF_SENTENCE); /** * Word information used to represent previous words information. @@ -86,35 +87,66 @@ public class PrevWordsInfo { // For simplicity of implementation, elements may also be EMPTY_WORD_INFO transiently after the // WordComposer was reset and before starting a new composing word, but we should never be // calling getSuggetions* in this situation. - public final WordInfo[] mPrevWordsInfo; + private final WordInfo[] mPrevWordsInfo; + private final int mPrevWordsCount; // Construct from the previous word information. - public PrevWordsInfo(final WordInfo prevWordInfo) { - mPrevWordsInfo = new WordInfo[] { prevWordInfo }; + public NgramContext(final WordInfo... prevWordsInfo) { + mPrevWordsInfo = prevWordsInfo; + mPrevWordsCount = prevWordsInfo.length; } - // Construct from WordInfo array. n-th element represents (n+1)-th previous word's information. - public PrevWordsInfo(final WordInfo[] prevWordsInfo) { - mPrevWordsInfo = prevWordsInfo; + // Construct from WordInfo array and size. The caller shouldn't change prevWordsInfo after + // calling this method. + private NgramContext(final NgramContext ngramContext, final int prevWordsCount) { + if (ngramContext.mPrevWordsCount < prevWordsCount) { + throw new IndexOutOfBoundsException("ngramContext.mPrevWordsCount (" + + ngramContext.mPrevWordsCount + ") is smaller than prevWordsCount (" + + prevWordsCount + ")"); + } + mPrevWordsInfo = ngramContext.mPrevWordsInfo; + mPrevWordsCount = prevWordsCount; } // Create next prevWordsInfo using current prevWordsInfo. - public PrevWordsInfo getNextPrevWordsInfo(final WordInfo wordInfo) { + public NgramContext getNextNgramContext(final WordInfo wordInfo) { final int nextPrevWordCount = Math.min(Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM, - mPrevWordsInfo.length + 1); + mPrevWordsCount + 1); final WordInfo[] prevWordsInfo = new WordInfo[nextPrevWordCount]; prevWordsInfo[0] = wordInfo; - System.arraycopy(mPrevWordsInfo, 0, prevWordsInfo, 1, prevWordsInfo.length - 1); - return new PrevWordsInfo(prevWordsInfo); + System.arraycopy(mPrevWordsInfo, 0, prevWordsInfo, 1, nextPrevWordCount - 1); + return new NgramContext(prevWordsInfo); } public boolean isValid() { - return mPrevWordsInfo.length > 0 && mPrevWordsInfo[0].isValid(); + return mPrevWordsCount > 0 && mPrevWordsInfo[0].isValid(); + } + + public boolean isBeginningOfSentenceContext() { + return mPrevWordsCount > 0 && mPrevWordsInfo[0].mIsBeginningOfSentence; + } + + // n is 1-indexed. + // TODO: Remove + public CharSequence getNthPrevWord(final int n) { + if (n <= 0 || n > mPrevWordsCount) { + return null; + } + return mPrevWordsInfo[n - 1].mWord; + } + + // n is 1-indexed. + @UsedForTesting + public boolean isNthPrevWordBeginningOfSontence(final int n) { + if (n <= 0 || n > mPrevWordsCount) { + return false; + } + return mPrevWordsInfo[n - 1].mIsBeginningOfSentence; } public void outputToArray(final int[][] codePointArrays, final boolean[] isBeginningOfSentenceArray) { - for (int i = 0; i < mPrevWordsInfo.length; i++) { + for (int i = 0; i < mPrevWordsCount; i++) { final WordInfo wordInfo = mPrevWordsInfo[i]; if (wordInfo == null || !wordInfo.isValid()) { codePointArrays[i] = new int[0]; @@ -126,15 +158,13 @@ public class PrevWordsInfo { } } - public PrevWordsInfo getTrimmedPrevWordsInfo(final int maxPrevWordCount) { - final int newSize = Math.min(maxPrevWordCount, mPrevWordsInfo.length); - // TODO: Quit creating a new array. - final WordInfo[] prevWordsInfo = Arrays.copyOf(mPrevWordsInfo, newSize); - return new PrevWordsInfo(prevWordsInfo); + public NgramContext getTrimmedNgramContext(final int maxPrevWordCount) { + final int newSize = Math.min(maxPrevWordCount, mPrevWordsCount); + return new NgramContext(this /* prevWordsInfo */, newSize); } public int getPrevWordCount() { - return mPrevWordsInfo.length; + return mPrevWordsCount; } @Override @@ -146,19 +176,25 @@ public class PrevWordsInfo { @Override public boolean equals(Object o) { if (this == o) return true; - if (!(o instanceof PrevWordsInfo)) return false; - final PrevWordsInfo prevWordsInfo = (PrevWordsInfo)o; + if (!(o instanceof NgramContext)) return false; + final NgramContext prevWordsInfo = (NgramContext)o; - final int minLength = Math.min(mPrevWordsInfo.length, prevWordsInfo.mPrevWordsInfo.length); + final int minLength = Math.min(mPrevWordsCount, prevWordsInfo.mPrevWordsCount); for (int i = 0; i < minLength; i++) { if (!mPrevWordsInfo[i].equals(prevWordsInfo.mPrevWordsInfo[i])) { return false; } } - final WordInfo[] longerWordsInfo = - (mPrevWordsInfo.length > prevWordsInfo.mPrevWordsInfo.length) ? - mPrevWordsInfo : prevWordsInfo.mPrevWordsInfo; - for (int i = minLength; i < longerWordsInfo.length; i++) { + final WordInfo[] longerWordsInfo; + final int longerWordsInfoCount; + if (mPrevWordsCount > prevWordsInfo.mPrevWordsCount) { + longerWordsInfo = mPrevWordsInfo; + longerWordsInfoCount = mPrevWordsCount; + } else { + longerWordsInfo = prevWordsInfo.mPrevWordsInfo; + longerWordsInfoCount = prevWordsInfo.mPrevWordsCount; + } + for (int i = minLength; i < longerWordsInfoCount; i++) { if (longerWordsInfo[i] != null && !WordInfo.EMPTY_WORD_INFO.equals(longerWordsInfo[i])) { return false; @@ -170,7 +206,7 @@ public class PrevWordsInfo { @Override public String toString() { final StringBuffer builder = new StringBuffer(); - for (int i = 0; i < mPrevWordsInfo.length; i++) { + for (int i = 0; i < mPrevWordsCount; i++) { final WordInfo wordInfo = mPrevWordsInfo[i]; builder.append("PrevWord["); builder.append(i); diff --git a/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java index 827367bb4..bc8bd831c 100644 --- a/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java @@ -51,13 +51,13 @@ public final class ReadOnlyBinaryDictionary extends Dictionary { @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, - final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, + final NgramContext ngramContext, final ProximityInfo proximityInfo, final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId, final float weightForLocale, final float[] inOutWeightOfLangModelVsSpatialModel) { if (mLock.readLock().tryLock()) { try { - return mBinaryDictionary.getSuggestions(composer, prevWordsInfo, proximityInfo, + return mBinaryDictionary.getSuggestions(composer, ngramContext, proximityInfo, settingsValuesForSuggestion, sessionId, weightForLocale, inOutWeightOfLangModelVsSpatialModel); } finally { diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index d672430a1..750706113 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -36,7 +36,7 @@ import com.android.inputmethod.compat.InputConnectionCompatUtils; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import com.android.inputmethod.latin.utils.CapsModeUtils; import com.android.inputmethod.latin.utils.DebugLogUtils; -import com.android.inputmethod.latin.utils.PrevWordsInfoUtils; +import com.android.inputmethod.latin.utils.NgramContextUtils; import com.android.inputmethod.latin.utils.ScriptUtils; import com.android.inputmethod.latin.utils.SpannableStringUtils; import com.android.inputmethod.latin.utils.StringUtils; @@ -593,11 +593,11 @@ public final class RichInputConnection { } @SuppressWarnings("unused") - public PrevWordsInfo getPrevWordsInfoFromNthPreviousWord( + public NgramContext getNgramContextFromNthPreviousWord( final SpacingAndPunctuations spacingAndPunctuations, final int n) { mIC = mParent.getCurrentInputConnection(); if (null == mIC) { - return PrevWordsInfo.EMPTY_PREV_WORDS_INFO; + return NgramContext.EMPTY_PREV_WORDS_INFO; } final CharSequence prev = getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0); if (DEBUG_PREVIOUS_TEXT && null != prev) { @@ -618,7 +618,7 @@ public final class RichInputConnection { } } } - return PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( + return NgramContextUtils.getNgramContextFromNthPreviousWord( prev, spacingAndPunctuations, n); } diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 1ecc995b2..d2d9b9b1e 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -68,15 +68,15 @@ public final class Suggest { } public void getSuggestedWords(final WordComposer wordComposer, - final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, + final NgramContext ngramContext, final ProximityInfo proximityInfo, final SettingsValuesForSuggestion settingsValuesForSuggestion, final boolean isCorrectionEnabled, final int inputStyle, final int sequenceNumber, final OnGetSuggestedWordsCallback callback) { if (wordComposer.isBatchMode()) { - getSuggestedWordsForBatchInput(wordComposer, prevWordsInfo, proximityInfo, + getSuggestedWordsForBatchInput(wordComposer, ngramContext, proximityInfo, settingsValuesForSuggestion, inputStyle, sequenceNumber, callback); } else { - getSuggestedWordsForNonBatchInput(wordComposer, prevWordsInfo, proximityInfo, + getSuggestedWordsForNonBatchInput(wordComposer, ngramContext, proximityInfo, settingsValuesForSuggestion, inputStyle, isCorrectionEnabled, sequenceNumber, callback); } @@ -121,7 +121,7 @@ public final class Suggest { // Retrieves suggestions for non-batch input (typing, recorrection, predictions...) // and calls the callback function with the suggestions. private void getSuggestedWordsForNonBatchInput(final WordComposer wordComposer, - final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, + final NgramContext ngramContext, final ProximityInfo proximityInfo, final SettingsValuesForSuggestion settingsValuesForSuggestion, final int inputStyleIfNotPrediction, final boolean isCorrectionEnabled, final int sequenceNumber, final OnGetSuggestedWordsCallback callback) { @@ -132,7 +132,7 @@ public final class Suggest { : typedWord; final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults( - wordComposer, prevWordsInfo, proximityInfo, settingsValuesForSuggestion, + wordComposer, ngramContext, proximityInfo, settingsValuesForSuggestion, SESSION_ID_TYPING); final ArrayList<SuggestedWordInfo> suggestionsContainer = getTransformedSuggestedWordInfoList(wordComposer, suggestionResults, @@ -209,12 +209,12 @@ public final class Suggest { // Retrieves suggestions for the batch input // and calls the callback function with the suggestions. private void getSuggestedWordsForBatchInput(final WordComposer wordComposer, - final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, + final NgramContext ngramContext, final ProximityInfo proximityInfo, final SettingsValuesForSuggestion settingsValuesForSuggestion, final int inputStyle, final int sequenceNumber, final OnGetSuggestedWordsCallback callback) { final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults( - wordComposer, prevWordsInfo, proximityInfo, settingsValuesForSuggestion, + wordComposer, ngramContext, proximityInfo, settingsValuesForSuggestion, SESSION_ID_GESTURE); final Locale defaultLocale = mDictionaryFacilitator.getLocale(); final ArrayList<SuggestedWordInfo> suggestionsContainer = diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index 567aa07f1..f85b34b5e 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -448,13 +448,13 @@ public final class WordComposer { // `type' should be one of the LastComposedWord.COMMIT_TYPE_* constants above. // committedWord should contain suggestion spans if applicable. public LastComposedWord commitWord(final int type, final CharSequence committedWord, - final String separatorString, final PrevWordsInfo prevWordsInfo) { + final String separatorString, final NgramContext ngramContext) { // Note: currently, we come here whenever we commit a word. If it's a MANUAL_PICK // or a DECIDED_WORD we may cancel the commit later; otherwise, we should deactivate // the last composed word to ensure this does not happen. final LastComposedWord lastComposedWord = new LastComposedWord(mEvents, mInputPointers, mTypedWordCache.toString(), committedWord, separatorString, - prevWordsInfo, mCapitalizedMode); + ngramContext, mCapitalizedMode); mInputPointers.reset(); if (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD && type != LastComposedWord.COMMIT_TYPE_MANUAL_PICK) { diff --git a/java/src/com/android/inputmethod/latin/accounts/AuthUtils.java b/java/src/com/android/inputmethod/latin/accounts/AuthUtils.java new file mode 100644 index 000000000..31aba3631 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/accounts/AuthUtils.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin.accounts; + +import android.accounts.Account; +import android.accounts.AccountManager; +import android.accounts.AccountManagerCallback; +import android.accounts.AccountManagerFuture; +import android.accounts.AuthenticatorException; +import android.accounts.OperationCanceledException; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; + +import java.io.IOException; + +/** + * Utility class that handles generation/invalidation of auth tokens in the app. + */ +public class AuthUtils { + private final AccountManager mAccountManager; + + public AuthUtils(Context context) { + mAccountManager = AccountManager.get(context); + } + + /** + * @see AccountManager#invalidateAuthToken(String, String) + */ + public void invalidateAuthToken(final String accountType, final String authToken) { + mAccountManager.invalidateAuthToken(accountType, authToken); + } + + /** + * @see AccountManager#getAuthToken( + * Account, String, Bundle, boolean, AccountManagerCallback, Handler) + */ + public AccountManagerFuture<Bundle> getAuthToken(final Account account, + final String authTokenType, final Bundle options, final boolean notifyAuthFailure, + final AccountManagerCallback<Bundle> callback, final Handler handler) { + return mAccountManager.getAuthToken(account, authTokenType, options, notifyAuthFailure, + callback, handler); + } + + /** + * @see AccountManager#blockingGetAuthToken(Account, String, boolean) + */ + public String blockingGetAuthToken(final Account account, final String authTokenType, + final boolean notifyAuthFailure) throws OperationCanceledException, + AuthenticatorException, IOException { + return mAccountManager.blockingGetAuthToken(account, authTokenType, notifyAuthFailure); + } +} diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index 46427e5ca..27af1611a 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -45,7 +45,7 @@ import com.android.inputmethod.latin.DictionaryFacilitator; import com.android.inputmethod.latin.InputPointers; import com.android.inputmethod.latin.LastComposedWord; import com.android.inputmethod.latin.LatinIME; -import com.android.inputmethod.latin.PrevWordsInfo; +import com.android.inputmethod.latin.NgramContext; import com.android.inputmethod.latin.RichInputConnection; import com.android.inputmethod.latin.Suggest; import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback; @@ -1376,7 +1376,7 @@ public final class InputLogic { } private void performAdditionToUserHistoryDictionary(final SettingsValues settingsValues, - final String suggestion, final PrevWordsInfo prevWordsInfo) { + final String suggestion, final NgramContext ngramContext) { // If correction is not enabled, we don't add words to the user history dictionary. // That's to avoid unintended additions in some sensitive fields, or fields that // expect to receive non-words. @@ -1388,7 +1388,7 @@ public final class InputLogic { final int timeStampInSeconds = (int)TimeUnit.MILLISECONDS.toSeconds( System.currentTimeMillis()); mDictionaryFacilitator.addToUserHistory(suggestion, wasAutoCapitalized, - prevWordsInfo, timeStampInSeconds, settingsValues.mBlockPotentiallyOffensive); + ngramContext, timeStampInSeconds, settingsValues.mBlockPotentiallyOffensive); } public void performUpdateSuggestionStripSync(final SettingsValues settingsValues, @@ -1519,10 +1519,10 @@ public final class InputLogic { } } final int[] codePoints = StringUtils.toCodePointArray(typedWord); - // We want the previous word for suggestion. If we have chars in the word + // We want the context of preceding words for suggestion. If we have chars in the word // before the cursor, then we want the word before that, hence 2; otherwise, // we want the word immediately before the cursor, hence 1. - final PrevWordsInfo prevWordsInfo = getPrevWordsInfoFromNthPreviousWordForSuggestion( + final NgramContext ngramContext = getNgramContextFromNthPreviousWordForSuggestion( settingsValues.mSpacingAndPunctuations, 0 == numberOfCharsInWordBeforeCursor ? 1 : 2); mWordComposer.setComposingWord(codePoints, @@ -1760,24 +1760,24 @@ public final class InputLogic { } /** - * Get information fo previous words from the nth previous word before the cursor as context + * Get n-gram context from the nth previous word before the cursor as context * for the suggestion process. * @param spacingAndPunctuations the current spacing and punctuations settings. * @param nthPreviousWord reverse index of the word to get (1-indexed) * @return the information of previous words */ // TODO: Make this private - public PrevWordsInfo getPrevWordsInfoFromNthPreviousWordForSuggestion( + public NgramContext getNgramContextFromNthPreviousWordForSuggestion( final SpacingAndPunctuations spacingAndPunctuations, final int nthPreviousWord) { if (spacingAndPunctuations.mCurrentLanguageHasSpaces) { // If we are typing in a language with spaces we can just look up the previous // word information from textview. - return mConnection.getPrevWordsInfoFromNthPreviousWord( + return mConnection.getNgramContextFromNthPreviousWord( spacingAndPunctuations, nthPreviousWord); } else { return LastComposedWord.NOT_A_COMPOSED_WORD == mLastComposedWord ? - PrevWordsInfo.BEGINNING_OF_SENTENCE : - new PrevWordsInfo(new PrevWordsInfo.WordInfo( + NgramContext.BEGINNING_OF_SENTENCE : + new NgramContext(new NgramContext.WordInfo( mLastComposedWord.mCommittedWord.toString())); } } @@ -2140,20 +2140,20 @@ public final class InputLogic { final CharSequence chosenWordWithSuggestions = SuggestionSpanUtils.getTextWithSuggestionSpan(mLatinIME, chosenWord, suggestedWords); - // When we are composing word, get previous words information from the 2nd previous word - // because the 1st previous word is the word to be committed. Otherwise get previous words - // information from the 1st previous word. - final PrevWordsInfo prevWordsInfo = mConnection.getPrevWordsInfoFromNthPreviousWord( + // When we are composing word, get n-gram context from the 2nd previous word because the + // 1st previous word is the word to be committed. Otherwise get n-gram context from the 1st + // previous word. + final NgramContext ngramContext = mConnection.getNgramContextFromNthPreviousWord( settingsValues.mSpacingAndPunctuations, mWordComposer.isComposingWord() ? 2 : 1); mConnection.commitText(chosenWordWithSuggestions, 1); // Add the word to the user history dictionary - performAdditionToUserHistoryDictionary(settingsValues, chosenWord, prevWordsInfo); + performAdditionToUserHistoryDictionary(settingsValues, chosenWord, ngramContext); // TODO: figure out here if this is an auto-correct or if the best word is actually // what user typed. Note: currently this is done much later in // LastComposedWord#didCommitTypedWord by string equality of the remembered // strings. mLastComposedWord = mWordComposer.commitWord(commitType, - chosenWordWithSuggestions, separatorString, prevWordsInfo); + chosenWordWithSuggestions, separatorString, ngramContext); } /** @@ -2200,7 +2200,7 @@ public final class InputLogic { mWordComposer.adviseCapitalizedModeBeforeFetchingSuggestions( getActualCapsMode(settingsValues, keyboardShiftMode)); mSuggest.getSuggestedWords(mWordComposer, - getPrevWordsInfoFromNthPreviousWordForSuggestion( + getNgramContextFromNthPreviousWordForSuggestion( settingsValues.mSpacingAndPunctuations, // Get the word on which we should search the bigrams. If we are composing // a word, it's whatever is *before* the half-committed word in the buffer, diff --git a/java/src/com/android/inputmethod/latin/network/BlockingHttpClient.java b/java/src/com/android/inputmethod/latin/network/BlockingHttpClient.java new file mode 100644 index 000000000..0d0cbe169 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/network/BlockingHttpClient.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin.network; + +import com.android.inputmethod.annotations.UsedForTesting; + +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * A client for executing HTTP requests synchronously. + * This must never be called from the main thread. + * + * TODO: Remove @UsedForTesting after this is actually used. + */ +@UsedForTesting +public class BlockingHttpClient { + private final HttpURLConnection mConnection; + + /** + * Interface that handles processing the response for a request. + */ + public interface ResponseProcessor { + /** + * Called when the HTTP request fails with an error. + * + * @param httpStatusCode The status code of the HTTP response. + * @param message The HTTP response message, if any, or null. + */ + void onError(int httpStatusCode, @Nullable String message); + + /** + * Called when the HTTP request finishes successfully. + * The {@link InputStream} is closed by the client after the method finishes, + * so any processing must be done in this method itself. + * + * @param response An input stream that can be used to read the HTTP response. + */ + void onSuccess(InputStream response); + } + + /** + * TODO: Remove @UsedForTesting after this is actually used. + */ + @UsedForTesting + public BlockingHttpClient(HttpURLConnection connection) { + mConnection = connection; + } + + /** + * Executes the request on the underlying {@link HttpURLConnection}. + * + * TODO: Remove @UsedForTesting after this is actually used. + * + * @param request The request payload, if any, or null. + * @param responeProcessor A processor for the HTTP response. + */ + @UsedForTesting + public void execute(@Nullable byte[] request, @Nonnull ResponseProcessor responseProcessor) + throws IOException { + try { + if (request != null) { + OutputStream out = new BufferedOutputStream(mConnection.getOutputStream()); + out.write(request); + out.flush(); + out.close(); + } + + final int responseCode = mConnection.getResponseCode(); + if (responseCode != HttpURLConnection.HTTP_OK) { + responseProcessor.onError(responseCode, mConnection.getResponseMessage()); + } else { + responseProcessor.onSuccess(mConnection.getInputStream()); + } + } finally { + mConnection.disconnect(); + } + } +} diff --git a/java/src/com/android/inputmethod/latin/network/HttpUrlConnectionBuilder.java b/java/src/com/android/inputmethod/latin/network/HttpUrlConnectionBuilder.java new file mode 100644 index 000000000..35b65be56 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/network/HttpUrlConnectionBuilder.java @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin.network; + +import android.text.TextUtils; + +import com.android.inputmethod.annotations.UsedForTesting; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map.Entry; + +/** + * Builder for {@link HttpURLConnection}s. + * + * TODO: Remove @UsedForTesting after this is actually used. + */ +@UsedForTesting +public class HttpUrlConnectionBuilder { + private static final int DEFAULT_TIMEOUT_MILLIS = 5 * 1000; + + /** + * Request header key for cache control. + */ + public static final String KEY_CACHE_CONTROL = "Cache-Control"; + /** + * Request header value for cache control indicating no caching. + * @see #KEY_CACHE_CONTROL + */ + public static final String VALUE_NO_CACHE = "no-cache"; + + /** + * Indicates that the request is unidirectional - upload-only. + * TODO: Remove @UsedForTesting after this is actually used. + */ + @UsedForTesting + public static final int MODE_UPLOAD_ONLY = 1; + /** + * Indicates that the request is unidirectional - download only. + * TODO: Remove @UsedForTesting after this is actually used. + */ + @UsedForTesting + public static final int MODE_DOWNLOAD_ONLY = 2; + /** + * Indicates that the request is bi-directional. + * TODO: Remove @UsedForTesting after this is actually used. + */ + @UsedForTesting + public static final int MODE_BI_DIRECTIONAL = 3; + + private final HashMap<String, String> mHeaderMap = new HashMap<>(); + + private URL mUrl; + private int mConnectTimeoutMillis = DEFAULT_TIMEOUT_MILLIS; + private int mReadTimeoutMillis = DEFAULT_TIMEOUT_MILLIS; + private int mContentLength = -1; + private boolean mUseCache; + private int mMode; + + /** + * Sets the URL that'll be used for the request. + * This *must* be set before calling {@link #build()} + * + * TODO: Remove @UsedForTesting after this is actually used. + */ + @UsedForTesting + public HttpUrlConnectionBuilder setUrl(String url) throws MalformedURLException { + if (TextUtils.isEmpty(url)) { + throw new IllegalArgumentException("URL must not be empty"); + } + mUrl = new URL(url); + return this; + } + + /** + * Sets the connect timeout. Defaults to {@value #DEFAULT_TIMEOUT} milliseconds. + * + * TODO: Remove @UsedForTesting after this is actually used. + */ + @UsedForTesting + public HttpUrlConnectionBuilder setConnectTimeout(int timeoutMillis) { + if (timeoutMillis < 0) { + throw new IllegalArgumentException("connect-timeout must be >= 0, but was " + + timeoutMillis); + } + mConnectTimeoutMillis = timeoutMillis; + return this; + } + + /** + * Sets the read timeout. Defaults to {@value #DEFAULT_TIMEOUT} milliseconds. + * + * TODO: Remove @UsedForTesting after this is actually used. + */ + @UsedForTesting + public HttpUrlConnectionBuilder setReadTimeout(int timeoutMillis) { + if (timeoutMillis < 0) { + throw new IllegalArgumentException("read-timeout must be >= 0, but was " + + timeoutMillis); + } + mReadTimeoutMillis = timeoutMillis; + return this; + } + + /** + * Adds an entry to the request header. + * + * TODO: Remove @UsedForTesting after this is actually used. + */ + @UsedForTesting + public HttpUrlConnectionBuilder addHeader(String key, String value) { + mHeaderMap.put(key, value); + return this; + } + + /** + * Sets the request to be executed such that the input is not buffered. + * This may be set when the request size is known beforehand. + * + * TODO: Remove @UsedForTesting after this is actually used. + */ + @UsedForTesting + public HttpUrlConnectionBuilder setFixedLengthForStreaming(int length) { + mContentLength = length; + return this; + } + + /** + * Indicates if the request can use cached responses or not. + * + * TODO: Remove @UsedForTesting after this is actually used. + */ + @UsedForTesting + public HttpUrlConnectionBuilder setUseCache(boolean useCache) { + mUseCache = useCache; + return this; + } + + /** + * The request mode. + * Sets the request mode to be one of: upload-only, download-only or bidirectional. + * + * @see #MODE_UPLOAD_ONLY + * @see #MODE_DOWNLOAD_ONLY + * @see #MODE_BI_DIRECTIONAL + * + * TODO: Remove @UsedForTesting after this is actually used. + */ + @UsedForTesting + public HttpUrlConnectionBuilder setMode(int mode) { + if (mode != MODE_UPLOAD_ONLY + && mode != MODE_DOWNLOAD_ONLY + && mode != MODE_BI_DIRECTIONAL) { + throw new IllegalArgumentException("Invalid mode specified:" + mode); + } + mMode = mode; + return this; + } + + /** + * Builds the {@link HttpURLConnection} instance that can be used to execute the request. + * + * TODO: Remove @UsedForTesting after this is actually used. + */ + @UsedForTesting + public HttpURLConnection build() throws IOException { + if (mUrl == null) { + throw new IllegalArgumentException("A URL must be specified!"); + } + final HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); + connection.setConnectTimeout(mConnectTimeoutMillis); + connection.setReadTimeout(mReadTimeoutMillis); + connection.setUseCaches(mUseCache); + switch (mMode) { + case MODE_UPLOAD_ONLY: + connection.setDoInput(true); + connection.setDoOutput(false); + break; + case MODE_DOWNLOAD_ONLY: + connection.setDoInput(false); + connection.setDoOutput(true); + break; + case MODE_BI_DIRECTIONAL: + connection.setDoInput(true); + connection.setDoOutput(true); + break; + } + for (final Entry<String, String> entry : mHeaderMap.entrySet()) { + connection.addRequestProperty(entry.getKey(), entry.getValue()); + } + if (mContentLength >= 0) { + connection.setFixedLengthStreamingMode(mContentLength); + } + return connection; + } +} diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java index d1486f630..d61684698 100644 --- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java +++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java @@ -23,7 +23,7 @@ import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.ExpandableBinaryDictionary; -import com.android.inputmethod.latin.PrevWordsInfo; +import com.android.inputmethod.latin.NgramContext; import com.android.inputmethod.latin.utils.DistracterFilter; import java.io.File; @@ -53,14 +53,14 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas * Add a word to the user history dictionary. * * @param userHistoryDictionary the user history dictionary - * @param prevWordsInfo the information of previous words + * @param ngramContext the n-gram context * @param word the word the user inputted * @param isValid whether the word is valid or not * @param timestamp the timestamp when the word has been inputted * @param distracterFilter the filter to check whether the word is a distracter */ public static void addToDictionary(final ExpandableBinaryDictionary userHistoryDictionary, - final PrevWordsInfo prevWordsInfo, final String word, final boolean isValid, + final NgramContext ngramContext, final String word, final boolean isValid, final int timestamp, final DistracterFilter distracterFilter) { if (word.length() > Constants.DICTIONARY_MAX_WORD_LENGTH) { return; @@ -71,12 +71,11 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas null /* shortcutTarget */, 0 /* shortcutFreq */, false /* isNotAWord */, false /* isBlacklisted */, timestamp, distracterFilter); - final boolean isBeginningOfSentenceContext = - prevWordsInfo.mPrevWordsInfo[0].mIsBeginningOfSentence; - final PrevWordsInfo prevWordsInfoToBeSaved = - prevWordsInfo.getTrimmedPrevWordsInfo(SUPPORTED_NGRAM - 1); - for (int i = 0; i < prevWordsInfoToBeSaved.getPrevWordCount(); i++) { - final CharSequence prevWord = prevWordsInfoToBeSaved.mPrevWordsInfo[i].mWord; + final boolean isBeginningOfSentenceContext = ngramContext.isBeginningOfSentenceContext(); + final NgramContext ngramContextToBeSaved = + ngramContext.getTrimmedNgramContext(SUPPORTED_NGRAM - 1); + for (int i = 0; i < ngramContextToBeSaved.getPrevWordCount(); i++) { + final CharSequence prevWord = ngramContextToBeSaved.getNthPrevWord(1 /* n */); if (prevWord == null || (prevWord.length() > Constants.DICTIONARY_MAX_WORD_LENGTH)) { return; } @@ -87,11 +86,11 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas if (isBeginningOfSentenceContext) { // Beginning-of-Sentence n-gram entry is added as an n-gram entry of an OOV word. userHistoryDictionary.addNgramEntry( - prevWordsInfoToBeSaved.getTrimmedPrevWordsInfo(i + 1), word, + ngramContextToBeSaved.getTrimmedNgramContext(i + 1), word, FREQUENCY_FOR_WORDS_NOT_IN_DICTS, timestamp); } else { userHistoryDictionary.addNgramEntry( - prevWordsInfoToBeSaved.getTrimmedPrevWordsInfo(i + 1), word, frequency, + ngramContextToBeSaved.getTrimmedNgramContext(i + 1), word, frequency, timestamp); } } diff --git a/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java index 9bc398654..2174f5224 100644 --- a/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java @@ -32,6 +32,7 @@ import android.preference.PreferenceFragment; import android.preference.PreferenceGroup; import android.support.v4.view.ViewCompat; import android.text.TextUtils; +import android.util.Log; import android.util.Pair; import android.view.LayoutInflater; import android.view.Menu; @@ -59,6 +60,12 @@ import java.util.ArrayList; import java.util.TreeSet; public final class CustomInputStyleSettingsFragment extends PreferenceFragment { + private static final String TAG = CustomInputStyleSettingsFragment.class.getSimpleName(); + private static final boolean DEBUG_SUBTYPE_ID = false; + // Note: We would like to turn this debug flag true in order to see what input styles are + // defined in a bug-report. + private static final boolean DEBUG_CUSTOM_INPUT_STYLES = true; + private RichInputMethodManager mRichImm; private SharedPreferences mPrefs; private SubtypeLocaleAdapter mSubtypeLocaleAdapter; @@ -96,8 +103,7 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment { } static final class SubtypeLocaleAdapter extends ArrayAdapter<SubtypeLocaleItem> { - private static final String TAG = SubtypeLocaleAdapter.class.getSimpleName(); - private static final boolean DEBUG_SUBTYPE_ID = false; + private static final String TAG_SUBTYPE = SubtypeLocaleAdapter.class.getSimpleName(); public SubtypeLocaleAdapter(final Context context) { super(context, android.R.layout.simple_spinner_item); @@ -110,7 +116,7 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment { for (int i = 0; i < count; i++) { final InputMethodSubtype subtype = imi.getSubtypeAt(i); if (DEBUG_SUBTYPE_ID) { - android.util.Log.d(TAG, String.format("%-6s 0x%08x %11d %s", + Log.d(TAG_SUBTYPE, String.format("%-6s 0x%08x %11d %s", subtype.getLocale(), subtype.hashCode(), subtype.hashCode(), SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype))); } @@ -445,6 +451,9 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment { final String prefSubtypes = Settings.readPrefAdditionalSubtypes(mPrefs, getResources()); + if (DEBUG_CUSTOM_INPUT_STYLES) { + Log.i(TAG, "Load custom input styles: " + prefSubtypes); + } setPrefSubtypes(prefSubtypes, context); mIsAddingNewSubtype = (savedInstanceState != null) @@ -611,6 +620,9 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment { final String oldSubtypes = Settings.readPrefAdditionalSubtypes(mPrefs, getResources()); final InputMethodSubtype[] subtypes = getSubtypes(); final String prefSubtypes = AdditionalSubtypeUtils.createPrefSubtypes(subtypes); + if (DEBUG_CUSTOM_INPUT_STYLES) { + Log.i(TAG, "Save custom input styles: " + prefSubtypes); + } if (prefSubtypes.equals(oldSubtypes)) { return; } diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java index 352391611..2a4e14ca7 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java @@ -31,7 +31,7 @@ import com.android.inputmethod.keyboard.KeyboardLayoutSet; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.DictionaryFacilitator; import com.android.inputmethod.latin.DictionaryFacilitatorLruCache; -import com.android.inputmethod.latin.PrevWordsInfo; +import com.android.inputmethod.latin.NgramContext; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.RichInputMethodSubtype; import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion; @@ -163,14 +163,14 @@ public final class AndroidSpellCheckerService extends SpellCheckerService } public SuggestionResults getSuggestionResults(final Locale locale, final WordComposer composer, - final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo) { + final NgramContext ngramContext, final ProximityInfo proximityInfo) { Integer sessionId = null; mSemaphore.acquireUninterruptibly(); try { sessionId = mSessionIdPool.poll(); DictionaryFacilitator dictionaryFacilitatorForLocale = mDictionaryFacilitatorCache.get(locale); - return dictionaryFacilitatorForLocale.getSuggestionResults(composer, prevWordsInfo, + return dictionaryFacilitatorForLocale.getSuggestionResults(composer, ngramContext, proximityInfo, mSettingsValuesForSuggestion, sessionId); } finally { if (sessionId != null) { diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java index 34e01197a..8393b306c 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java @@ -25,7 +25,7 @@ import android.view.textservice.SuggestionsInfo; import android.view.textservice.TextInfo; import com.android.inputmethod.compat.TextInfoCompatUtils; -import com.android.inputmethod.latin.PrevWordsInfo; +import com.android.inputmethod.latin.NgramContext; import com.android.inputmethod.latin.utils.StringUtils; import java.util.ArrayList; @@ -62,8 +62,8 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck final int offset = ssi.getOffsetAt(i); final int length = ssi.getLengthAt(i); final CharSequence subText = typedText.subSequence(offset, offset + length); - final PrevWordsInfo prevWordsInfo = - new PrevWordsInfo(new PrevWordsInfo.WordInfo(currentWord)); + final NgramContext ngramContext = + new NgramContext(new NgramContext.WordInfo(currentWord)); currentWord = subText; if (!subText.toString().contains(AndroidSpellCheckerService.SINGLE_QUOTE)) { continue; @@ -80,7 +80,7 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck if (TextUtils.isEmpty(splitText)) { continue; } - if (mSuggestionsCache.getSuggestionsFromCache(splitText.toString(), prevWordsInfo) + if (mSuggestionsCache.getSuggestionsFromCache(splitText.toString(), ngramContext) == null) { continue; } @@ -208,10 +208,10 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck } else { prevWord = null; } - final PrevWordsInfo prevWordsInfo = - new PrevWordsInfo(new PrevWordsInfo.WordInfo(prevWord)); + final NgramContext ngramContext = + new NgramContext(new NgramContext.WordInfo(prevWord)); final TextInfo textInfo = textInfos[i]; - retval[i] = onGetSuggestionsInternal(textInfo, prevWordsInfo, suggestionsLimit); + retval[i] = onGetSuggestionsInternal(textInfo, ngramContext, suggestionsLimit); retval[i].setCookieAndSequence(textInfo.getCookie(), textInfo.getSequence()); } return retval; diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java index d668672aa..7b6aacd15 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java @@ -31,7 +31,7 @@ import com.android.inputmethod.compat.SuggestionsInfoCompatUtils; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.PrevWordsInfo; +import com.android.inputmethod.latin.NgramContext; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.WordComposer; import com.android.inputmethod.latin.utils.BinaryDictionaryUtils; @@ -73,27 +73,25 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { private final LruCache<String, SuggestionsParams> mUnigramSuggestionsInfoCache = new LruCache<>(MAX_CACHE_SIZE); - // TODO: Support n-gram input - private static String generateKey(final String query, final PrevWordsInfo prevWordsInfo) { - if (TextUtils.isEmpty(query) || !prevWordsInfo.isValid()) { + private static String generateKey(final String query, final NgramContext ngramContext) { + if (TextUtils.isEmpty(query) || !ngramContext.isValid()) { return query; } - return query + CHAR_DELIMITER + prevWordsInfo; + return query + CHAR_DELIMITER + ngramContext; } public SuggestionsParams getSuggestionsFromCache(String query, - final PrevWordsInfo prevWordsInfo) { - return mUnigramSuggestionsInfoCache.get(generateKey(query, prevWordsInfo)); + final NgramContext ngramContext) { + return mUnigramSuggestionsInfoCache.get(generateKey(query, ngramContext)); } - public void putSuggestionsToCache( - final String query, final PrevWordsInfo prevWordsInfo, + public void putSuggestionsToCache(final String query, final NgramContext ngramContext, final String[] suggestions, final int flags) { if (suggestions == null || TextUtils.isEmpty(query)) { return; } mUnigramSuggestionsInfoCache.put( - generateKey(query, prevWordsInfo), new SuggestionsParams(suggestions, flags)); + generateKey(query, ngramContext), new SuggestionsParams(suggestions, flags)); } public void clearCache() { @@ -223,12 +221,11 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { } protected SuggestionsInfo onGetSuggestionsInternal( - final TextInfo textInfo, final PrevWordsInfo prevWordsInfo, - final int suggestionsLimit) { + final TextInfo textInfo, final NgramContext ngramContext, final int suggestionsLimit) { try { final String inText = textInfo.getText(); final SuggestionsParams cachedSuggestionsParams = - mSuggestionsCache.getSuggestionsFromCache(inText, prevWordsInfo); + mSuggestionsCache.getSuggestionsFromCache(inText, ngramContext); if (cachedSuggestionsParams != null) { if (DBG) { Log.d(TAG, "Cache hit: " + inText + ", " + cachedSuggestionsParams.mFlags); @@ -283,7 +280,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { composer.setComposingWord(codePoints, coordinates); // TODO: Don't gather suggestions if the limit is <= 0 unless necessary final SuggestionResults suggestionResults = mService.getSuggestionResults( - mLocale, composer, prevWordsInfo, proximityInfo); + mLocale, composer, ngramContext, proximityInfo); final Result result = getResult(capitalizeType, mLocale, suggestionsLimit, mService.getRecommendedThreshold(), text, suggestionResults); isInDict = isInDictForAnyCapitalization(text, capitalizeType); @@ -308,7 +305,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { .getValueOf_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS() : 0); final SuggestionsInfo retval = new SuggestionsInfo(flags, result.mSuggestions); - mSuggestionsCache.putSuggestionsToCache(text, prevWordsInfo, result.mSuggestions, + mSuggestionsCache.putSuggestionsToCache(text, ngramContext, result.mSuggestions, flags); return retval; } catch (RuntimeException e) { diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java index 43f6175ca..b421a7eb5 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java @@ -418,8 +418,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick // Decided to be in the sliding suggestion mode only when the touch point has been moved // upward. Further {@link MotionEvent}s will be delivered to // {@link #onTouchEvent(MotionEvent)}. - mNeedsToTransformTouchEventToHoverEvent = AccessibilityUtils.getInstance() - .isTouchExplorationEnabled(); + mNeedsToTransformTouchEventToHoverEvent = + AccessibilityUtils.getInstance().isTouchExplorationEnabled(); mIsDispatchingHoverEventToMoreSuggestions = false; return true; } diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java index 6fd241ee9..355d00dac 100644 --- a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java +++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java @@ -22,23 +22,23 @@ import java.util.Locale; import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.PrevWordsInfo; +import com.android.inputmethod.latin.NgramContext; public interface DistracterFilter { /** * Determine whether a word is a distracter to words in dictionaries. * - * @param prevWordsInfo the information of previous words. + * @param ngramContext the n-gram context * @param testedWord the word that will be tested to see whether it is a distracter to words * in dictionaries. * @param locale the locale of word. * @return true if testedWord is a distracter, otherwise false. */ - public boolean isDistracterToWordsInDictionaries(final PrevWordsInfo prevWordsInfo, + public boolean isDistracterToWordsInDictionaries(final NgramContext ngramContext, final String testedWord, final Locale locale); @UsedForTesting - public int getWordHandlingType(final PrevWordsInfo prevWordsInfo, final String testedWord, + public int getWordHandlingType(final NgramContext ngramContext, final String testedWord, final Locale locale); public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes); @@ -72,13 +72,13 @@ public interface DistracterFilter { public static final DistracterFilter EMPTY_DISTRACTER_FILTER = new DistracterFilter() { @Override - public boolean isDistracterToWordsInDictionaries(PrevWordsInfo prevWordsInfo, + public boolean isDistracterToWordsInDictionaries(NgramContext ngramContext, String testedWord, Locale locale) { return false; } @Override - public int getWordHandlingType(final PrevWordsInfo prevWordsInfo, + public int getWordHandlingType(final NgramContext ngramContext, final String testedWord, final Locale locale) { return HandlingType.REQUIRE_NO_SPECIAL_HANDLINGS; } diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java index f8a845304..8f0f9bb44 100644 --- a/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java +++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java @@ -36,7 +36,7 @@ import com.android.inputmethod.keyboard.KeyboardId; import com.android.inputmethod.keyboard.KeyboardLayoutSet; import com.android.inputmethod.latin.DictionaryFacilitator; import com.android.inputmethod.latin.DictionaryFacilitatorLruCache; -import com.android.inputmethod.latin.PrevWordsInfo; +import com.android.inputmethod.latin.NgramContext; import com.android.inputmethod.latin.RichInputMethodSubtype; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.WordComposer; @@ -156,14 +156,14 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr /** * Determine whether a word is a distracter to words in dictionaries. * - * @param prevWordsInfo the information of previous words. Not used for now. + * @param ngramContext the n-gram context. Not used for now. * @param testedWord the word that will be tested to see whether it is a distracter to words * in dictionaries. * @param locale the locale of word. * @return true if testedWord is a distracter, otherwise false. */ @Override - public boolean isDistracterToWordsInDictionaries(final PrevWordsInfo prevWordsInfo, + public boolean isDistracterToWordsInDictionaries(final NgramContext ngramContext, final String testedWord, final Locale locale) { if (locale == null) { return false; @@ -250,7 +250,7 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr final SuggestionResults suggestionResults; synchronized (mLock) { suggestionResults = dictionaryFacilitator.getSuggestionResults( - composer, PrevWordsInfo.EMPTY_PREV_WORDS_INFO, keyboard.getProximityInfo(), + composer, NgramContext.EMPTY_PREV_WORDS_INFO, keyboard.getProximityInfo(), settingsValuesForSuggestion, 0 /* sessionId */); } if (suggestionResults.isEmpty()) { @@ -283,7 +283,7 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr return false; } - private boolean shouldBeLowerCased(final PrevWordsInfo prevWordsInfo, final String testedWord, + private boolean shouldBeLowerCased(final NgramContext ngramContext, final String testedWord, final Locale locale) { final DictionaryFacilitator dictionaryFacilitator = mDictionaryFacilitatorLruCache.get(locale); @@ -298,7 +298,7 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr return true; } if (StringUtils.getCapitalizationType(testedWord) == StringUtils.CAPITALIZE_FIRST - && !prevWordsInfo.isValid()) { + && !ngramContext.isValid()) { // TODO: Check beginning-of-sentence. return true; } @@ -306,13 +306,13 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr } @Override - public int getWordHandlingType(final PrevWordsInfo prevWordsInfo, final String testedWord, + public int getWordHandlingType(final NgramContext ngramContext, final String testedWord, final Locale locale) { // TODO: Use this method for user history dictionary. if (testedWord == null|| locale == null) { return HandlingType.getHandlingType(false /* shouldBeLowerCased */, false /* isOov */); } - final boolean shouldBeLowerCased = shouldBeLowerCased(prevWordsInfo, testedWord, locale); + final boolean shouldBeLowerCased = shouldBeLowerCased(ngramContext, testedWord, locale); final String caseModifiedWord = shouldBeLowerCased ? testedWord.toLowerCase(locale) : testedWord; final boolean isOov = !mDictionaryFacilitatorLruCache.get(locale).isValidWord( diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingIsInDictionary.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingIsInDictionary.java index 349236f18..df6e97028 100644 --- a/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingIsInDictionary.java +++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingIsInDictionary.java @@ -22,7 +22,7 @@ import java.util.Locale; import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.latin.Dictionary; -import com.android.inputmethod.latin.PrevWordsInfo; +import com.android.inputmethod.latin.NgramContext; public class DistracterFilterCheckingIsInDictionary implements DistracterFilter { private final DistracterFilter mDistracterFilter; @@ -35,7 +35,7 @@ public class DistracterFilterCheckingIsInDictionary implements DistracterFilter } @Override - public boolean isDistracterToWordsInDictionaries(PrevWordsInfo prevWordsInfo, + public boolean isDistracterToWordsInDictionaries(NgramContext ngramContext, String testedWord, Locale locale) { if (mDictionary.isInDictionary(testedWord)) { // This filter treats entries that are already in the dictionary as non-distracters @@ -43,14 +43,14 @@ public class DistracterFilterCheckingIsInDictionary implements DistracterFilter return false; } else { return mDistracterFilter.isDistracterToWordsInDictionaries( - prevWordsInfo, testedWord, locale); + ngramContext, testedWord, locale); } } @Override - public int getWordHandlingType(final PrevWordsInfo prevWordsInfo, final String testedWord, + public int getWordHandlingType(final NgramContext ngramContext, final String testedWord, final Locale locale) { - return mDistracterFilter.getWordHandlingType(prevWordsInfo, testedWord, locale); + return mDistracterFilter.getWordHandlingType(ngramContext, testedWord, locale); } @Override diff --git a/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java b/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java index ea406fa75..142548b25 100644 --- a/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java @@ -53,7 +53,8 @@ public final class ImportantNoticeUtils { // This utility class is not publicly instantiable. } - private static boolean isInSystemSetupWizard(final Context context) { + @UsedForTesting + static boolean isInSystemSetupWizard(final Context context) { try { final int userSetupComplete = Settings.Secure.getInt( context.getContentResolver(), Settings_Secure_USER_SETUP_COMPLETE); @@ -84,7 +85,8 @@ public final class ImportantNoticeUtils { return getLastImportantNoticeVersion(context) + 1; } - private static boolean hasNewImportantNotice(final Context context) { + @UsedForTesting + static boolean hasNewImportantNotice(final Context context) { final int lastVersion = getLastImportantNoticeVersion(context); return getCurrentImportantNoticeVersion(context) > lastVersion; } diff --git a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java index 7955541aa..73aefb821 100644 --- a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java +++ b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java @@ -21,7 +21,7 @@ import android.util.Log; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.DictionaryFacilitator; -import com.android.inputmethod.latin.PrevWordsInfo; +import com.android.inputmethod.latin.NgramContext; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import com.android.inputmethod.latin.utils.DistracterFilter.HandlingType; @@ -89,7 +89,7 @@ public final class LanguageModelParam { final DistracterFilter distracterFilter) { final ArrayList<LanguageModelParam> languageModelParams = new ArrayList<>(); final int N = tokens.size(); - PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; + NgramContext ngramContext = NgramContext.EMPTY_PREV_WORDS_INFO; for (int i = 0; i < N; ++i) { final String tempWord = tokens.get(i); if (StringUtils.isEmptyStringOrWhiteSpaces(tempWord)) { @@ -106,7 +106,7 @@ public final class LanguageModelParam { + tempWord + "\""); } // Sentence terminator found. Split. - prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; + ngramContext = NgramContext.EMPTY_PREV_WORDS_INFO; continue; } if (DEBUG_TOKEN) { @@ -114,41 +114,41 @@ public final class LanguageModelParam { } final LanguageModelParam languageModelParam = detectWhetherVaildWordOrNotAndGetLanguageModelParam( - prevWordsInfo, tempWord, timestamp, locale, distracterFilter); + ngramContext, tempWord, timestamp, locale, distracterFilter); if (languageModelParam == null) { continue; } languageModelParams.add(languageModelParam); - prevWordsInfo = prevWordsInfo.getNextPrevWordsInfo( - new PrevWordsInfo.WordInfo(tempWord)); + ngramContext = ngramContext.getNextNgramContext( + new NgramContext.WordInfo(tempWord)); } return languageModelParams; } private static LanguageModelParam detectWhetherVaildWordOrNotAndGetLanguageModelParam( - final PrevWordsInfo prevWordsInfo, final String targetWord, final int timestamp, + final NgramContext ngramContext, final String targetWord, final int timestamp, final Locale locale, final DistracterFilter distracterFilter) { if (locale == null) { return null; } - final int wordHandlingType = distracterFilter.getWordHandlingType(prevWordsInfo, + final int wordHandlingType = distracterFilter.getWordHandlingType(ngramContext, targetWord, locale); final String word = HandlingType.shouldBeLowerCased(wordHandlingType) ? targetWord.toLowerCase(locale) : targetWord; - if (distracterFilter.isDistracterToWordsInDictionaries(prevWordsInfo, targetWord, locale)) { + if (distracterFilter.isDistracterToWordsInDictionaries(ngramContext, targetWord, locale)) { // The word is a distracter. return null; } - return createAndGetLanguageModelParamOfWord(prevWordsInfo, word, timestamp, + return createAndGetLanguageModelParamOfWord(ngramContext, word, timestamp, !HandlingType.shouldBeHandledAsOov(wordHandlingType)); } private static LanguageModelParam createAndGetLanguageModelParamOfWord( - final PrevWordsInfo prevWordsInfo, final String word, final int timestamp, + final NgramContext ngramContext, final String word, final int timestamp, final boolean isValidWord) { final int unigramProbability = isValidWord ? UNIGRAM_PROBABILITY_FOR_VALID_WORD : UNIGRAM_PROBABILITY_FOR_OOV_WORD; - if (!prevWordsInfo.isValid()) { + if (!ngramContext.isValid()) { if (DEBUG) { Log.d(TAG, "--- add unigram: current(" + (isValidWord ? "Valid" : "OOV") + ") = " + word); @@ -156,12 +156,12 @@ public final class LanguageModelParam { return new LanguageModelParam(word, unigramProbability, timestamp); } if (DEBUG) { - Log.d(TAG, "--- add bigram: prev = " + prevWordsInfo + ", current(" + Log.d(TAG, "--- add bigram: prev = " + ngramContext + ", current(" + (isValidWord ? "Valid" : "OOV") + ") = " + word); } final int bigramProbability = isValidWord ? BIGRAM_PROBABILITY_FOR_VALID_WORD : BIGRAM_PROBABILITY_FOR_OOV_WORD; - return new LanguageModelParam(prevWordsInfo.mPrevWordsInfo[0].mWord, word, + return new LanguageModelParam(ngramContext.getNthPrevWord(1 /* n */), word, unigramProbability, bigramProbability, timestamp); } } diff --git a/java/src/com/android/inputmethod/latin/utils/PrevWordsInfoUtils.java b/java/src/com/android/inputmethod/latin/utils/NgramContextUtils.java index 5720d9388..34eeac2c2 100644 --- a/java/src/com/android/inputmethod/latin/utils/PrevWordsInfoUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/NgramContextUtils.java @@ -20,12 +20,12 @@ import java.util.Arrays; import java.util.regex.Pattern; import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.PrevWordsInfo; -import com.android.inputmethod.latin.PrevWordsInfo.WordInfo; +import com.android.inputmethod.latin.NgramContext; +import com.android.inputmethod.latin.NgramContext.WordInfo; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; -public final class PrevWordsInfoUtils { - private PrevWordsInfoUtils() { +public final class NgramContextUtils { + private NgramContextUtils() { // Intentional empty constructor for utility class. } @@ -44,7 +44,7 @@ public final class PrevWordsInfoUtils { // (n = 2) "abc def|" -> beginning-of-sentence, abc // (n = 2) "abc def |" -> beginning-of-sentence, abc // (n = 2) "abc 'def|" -> empty. The context is different from "abc def", but we cannot - // represent this situation using PrevWordsInfo. See TODO in the method. + // represent this situation using NgramContext. See TODO in the method. // TODO: The next example's result should be "abc, def". This have to be fixed before we // retrieve the prior context of Beginning-of-Sentence. // (n = 2) "abc def. |" -> beginning-of-sentence, abc @@ -52,9 +52,9 @@ public final class PrevWordsInfoUtils { // (n = 2) "abc|" -> beginning-of-sentence // (n = 2) "abc |" -> beginning-of-sentence // (n = 2) "abc. def|" -> beginning-of-sentence - public static PrevWordsInfo getPrevWordsInfoFromNthPreviousWord(final CharSequence prev, + public static NgramContext getNgramContextFromNthPreviousWord(final CharSequence prev, final SpacingAndPunctuations spacingAndPunctuations, final int n) { - if (prev == null) return PrevWordsInfo.EMPTY_PREV_WORDS_INFO; + if (prev == null) return NgramContext.EMPTY_PREV_WORDS_INFO; final String[] w = SPACE_REGEX.split(prev); final WordInfo[] prevWordsInfo = new WordInfo[Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM]; Arrays.fill(prevWordsInfo, WordInfo.EMPTY_WORD_INFO); @@ -98,6 +98,6 @@ public final class PrevWordsInfoUtils { } prevWordsInfo[i] = new WordInfo(focusedWord); } - return new PrevWordsInfo(prevWordsInfo); + return new NgramContext(prevWordsInfo); } } diff --git a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java index d6f644228..4e2e396c2 100644 --- a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java +++ b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java @@ -31,7 +31,7 @@ import java.util.TreeSet; public final class SuggestionResults extends TreeSet<SuggestedWordInfo> { public final ArrayList<SuggestedWordInfo> mRawSuggestions; // TODO: Instead of a boolean , we may want to include the context of this suggestion results, - // such as {@link PrevWordsInfo}. + // such as {@link NgramContext}. public final boolean mIsBeginningOfSentence; private final int mCapacity; |