aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.pngbin462 -> 474 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.pngbin435 -> 463 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.pngbin547 -> 578 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.pngbin587 -> 639 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.pngbin553 -> 537 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.pngbin668 -> 655 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.pngbin707 -> 670 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.pngbin468 -> 474 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.pngbin547 -> 517 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.pngbin282 -> 272 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_light.pngbin1820 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/ic_ime_light.pngbin933 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/ic_ime_switcher_dark.pngbin0 -> 947 bytes
-rw-r--r--java/res/drawable-hdpi/ic_subtype_keyboard.pngbin812 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/ic_subtype_mic_dark.pngbin0 -> 1005 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_background_holo.9.png (renamed from java/res/drawable-hdpi/keyboard_background_ics.9.png)bin227 -> 227 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_background_holo.9.pngbin2080 -> 2138 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_left_background_holo.9.pngbin1990 -> 2105 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_left_more_background_holo.9.pngbin2152 -> 2164 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_more_background_holo.9.pngbin2256 -> 2225 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_right_background_holo.9.pngbin1993 -> 2061 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_right_more_background_holo.9.pngbin2163 -> 2133 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_popup_panel_background_holo.9.pngbin856 -> 874 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.pngbin160 -> 156 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_delete.pngbin4003 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_delete_holo.pngbin1248 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_delete_holo_dark.pngbin0 -> 1024 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_label_mic.pngbin1417 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_label_mic_holo.pngbin771 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_language_switch.pngbin1788 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_language_switch_dark.pngbin0 -> 1773 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_mic.pngbin3893 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.pngbin0 -> 778 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_return.pngbin4024 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_return_holo.pngbin1216 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_return_holo_dark.pngbin0 -> 1011 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_search.pngbin4248 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_search_holo.pngbin1607 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_search_holo_dark.pngbin0 -> 1220 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_settings.pngbin4015 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_settings_holo.pngbin787 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_settings_holo_dark.pngbin0 -> 889 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift.pngbin3740 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift_holo.pngbin1290 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift_holo_dark.pngbin0 -> 936 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift_locked.pngbin3686 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.pngbin1036 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift_locked_holo_dark.pngbin0 -> 730 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_space_holo.pngbin630 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_space_holo_dark.pngbin0 -> 593 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_tab.pngbin3792 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_tab_holo.pngbin1142 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_tab_holo_dark.pngbin0 -> 937 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_voice_holo.pngbin1889 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.pngbin0 -> 1083 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_voice_off_holo.pngbin1741 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_voice_off_holo_dark.pngbin0 -> 941 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_zwj_holo.pngbin973 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_zwj_holo_dark.pngbin0 -> 973 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_zwnj_holo.pngbin961 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_zwnj_holo_dark.pngbin0 -> 975 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.pngbin345 -> 338 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.pngbin334 -> 355 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.pngbin407 -> 428 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.pngbin411 -> 453 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.pngbin394 -> 380 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.pngbin505 -> 468 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.pngbin489 -> 458 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.pngbin332 -> 339 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.pngbin381 -> 368 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.pngbin236 -> 222 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_light.pngbin1132 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/ic_ime_light.pngbin753 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/ic_ime_switcher_dark.pngbin0 -> 784 bytes
-rw-r--r--java/res/drawable-mdpi/ic_subtype_keyboard.pngbin644 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_background_holo.9.png (renamed from java/res/drawable-mdpi/keyboard_background_ics.9.png)bin204 -> 204 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_background_holo.9.pngbin1313 -> 1383 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_left_background_holo.9.pngbin1297 -> 1305 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_left_more_background_holo.9.pngbin1437 -> 1425 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_more_background_holo.9.pngbin1457 -> 1454 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_right_background_holo.9.pngbin1288 -> 1314 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_right_more_background_holo.9.pngbin1423 -> 1427 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_popup_panel_background_holo.9.pngbin571 -> 590 bytes
-rw-r--r--java/res/drawable-mdpi/suggestions_strip_divider.pngbin264 -> 324 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_delete.pngbin3432 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_delete_holo.pngbin813 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_delete_holo_dark.pngbin0 -> 773 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_label_mic.pngbin542 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_label_mic_holo.pngbin576 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_label_mic_holo_dark.pngbin0 -> 498 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_language_switch.pngbin1113 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_language_switch_dark.pngbin0 -> 1121 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_mic.pngbin3439 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.pngbin0 -> 590 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_mic_holo_light.pngbin0 -> 525 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_return.pngbin3380 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_return_holo.pngbin870 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_return_holo_dark.pngbin0 -> 796 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_search.pngbin3535 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_search_holo.pngbin991 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_search_holo_dark.pngbin0 -> 861 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_settings.pngbin3448 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_settings_holo.pngbin585 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_settings_holo_dark.pngbin0 -> 708 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift.pngbin3217 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift_holo.pngbin940 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift_holo_dark.pngbin0 -> 756 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift_locked.pngbin3188 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.pngbin850 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift_locked_holo_dark.pngbin0 -> 668 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_smiley_holo_dark.pngbin0 -> 897 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_space_holo.pngbin505 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_space_holo_dark.pngbin0 -> 505 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_tab.pngbin3269 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_tab_holo.pngbin801 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_tab_holo_dark.pngbin0 -> 752 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_voice_holo.pngbin1166 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.pngbin0 -> 781 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_voice_off_holo.pngbin1105 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_voice_off_holo_dark.pngbin0 -> 699 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_zwj_holo.pngbin733 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_zwj_holo_dark.pngbin0 -> 746 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_zwnj_holo.pngbin704 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_zwnj_holo_dark.pngbin0 -> 721 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.pngbin601 -> 603 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.pngbin568 -> 589 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.pngbin722 -> 732 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.pngbin745 -> 787 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.pngbin737 -> 657 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.pngbin953 -> 848 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.pngbin945 -> 867 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.pngbin591 -> 594 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.pngbin668 -> 634 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.pngbin351 -> 323 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_light.pngbin2526 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_ime_light.pngbin1272 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_ime_switcher_dark.pngbin0 -> 1276 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_subtype_keyboard.pngbin1056 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_subtype_mic_dark.pngbin0 -> 1259 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_background_holo.9.png (renamed from java/res/drawable-xhdpi/keyboard_background_ics.9.png)bin267 -> 267 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_background_holo.9.pngbin2916 -> 3326 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_left_background_holo.9.pngbin2873 -> 3169 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_left_more_background_holo.9.pngbin3176 -> 3374 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_more_background_holo.9.pngbin3184 -> 3525 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_right_background_holo.9.pngbin2818 -> 3218 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_right_more_background_holo.9.pngbin3102 -> 3424 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_popup_panel_background_holo.9.pngbin1178 -> 1249 bytes
-rw-r--r--java/res/drawable-xhdpi/suggestions_strip_divider.pngbin267 -> 330 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_delete.pngbin4589 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_delete_holo.pngbin1584 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_delete_holo_dark.pngbin0 -> 1318 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_label_mic.pngbin2086 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_label_mic_holo.pngbin929 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_language_switch.pngbin2512 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_language_switch_dark.pngbin0 -> 2505 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_mic.pngbin4487 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.pngbin0 -> 942 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_return.pngbin4559 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_return_holo.pngbin1452 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_return_holo_dark.pngbin0 -> 1206 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_search.pngbin4990 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_search_holo.pngbin2070 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_search_holo_dark.pngbin0 -> 1576 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_settings.pngbin4639 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_settings_holo.pngbin1062 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_settings_holo_dark.pngbin0 -> 1309 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift.pngbin4186 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift_holo.pngbin1592 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift_holo_dark.pngbin0 -> 1090 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift_locked.pngbin4119 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.pngbin1295 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo_dark.pngbin0 -> 860 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_smiley_holo_dark.pngbin0 -> 1851 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_space_holo.pngbin675 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_space_holo_dark.pngbin0 -> 646 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_tab.pngbin4157 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_tab_holo.pngbin1336 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_tab_holo_dark.pngbin0 -> 1179 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_voice_holo.pngbin2393 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.pngbin0 -> 1421 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.pngbin2196 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_voice_off_holo_dark.pngbin0 -> 1248 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_zwj_holo.pngbin1185 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_zwj_holo_dark.pngbin0 -> 1184 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.pngbin1148 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_zwnj_holo_dark.pngbin0 -> 1171 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_holo.9.pngbin1805 -> 1803 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_holo.9.pngbin1693 -> 1718 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_off_holo.9.pngbin1913 -> 1905 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_on_holo.9.pngbin2039 -> 1998 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_holo.9.pngbin1863 -> 1861 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_off_holo.9.pngbin2196 -> 2073 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_on_holo.9.pngbin2210 -> 2091 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_light_normal_holo.9.pngbin1775 -> 1787 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_light_pressed_holo.9.pngbin1840 -> 1799 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_popup_selected_holo.9.pngbin1293 -> 1261 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_light.pngbin3060 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_ime_light.pngbin1349 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_ime_switcher_dark.pngbin0 -> 1309 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_subtype_keyboard.pngbin1218 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_subtype_mic_dark.pngbin0 -> 1846 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_background_holo.9.png (renamed from java/res/drawable-xxhdpi/keyboard_background_ics.9.png)bin1151 -> 1151 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_background_holo.9.pngbin5212 -> 7452 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_left_background_holo.9.pngbin4941 -> 7089 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_left_more_background_holo.9.pngbin5188 -> 7197 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_holo.9.pngbin5373 -> 5450 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_right_background_holo.9.pngbin4964 -> 7023 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_right_more_background_holo.9.pngbin5118 -> 7153 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_popup_panel_background_holo.9.pngbin2712 -> 2722 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_delete_holo.pngbin2860 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_delete_holo_dark.pngbin0 -> 1729 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_label_mic_holo.pngbin615 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_language_switch.pngbin3031 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_language_switch_dark.pngbin0 -> 3251 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.pngbin0 -> 1566 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_return_holo.pngbin2788 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_return_holo_dark.pngbin0 -> 1717 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_search_holo.pngbin4210 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_search_holo_dark.pngbin0 -> 2208 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_settings_holo.pngbin1455 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_settings_holo_dark.pngbin0 -> 1471 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_shift_holo.pngbin2855 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_shift_holo_dark.pngbin0 -> 1427 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo.pngbin2346 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo_dark.pngbin0 -> 1367 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_smiley_holo_dark.pngbin0 -> 2571 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_space_holo.pngbin1499 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_space_holo_dark.pngbin0 -> 1186 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_tab_holo.pngbin2671 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_tab_holo_dark.pngbin0 -> 1577 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_voice_holo.pngbin3102 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.pngbin0 -> 1907 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo.pngbin2749 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo_dark.pngbin0 -> 1791 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_zwj_holo.pngbin1436 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_zwj_holo_dark.pngbin0 -> 1589 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo.pngbin1452 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo_dark.pngbin0 -> 1591 bytes
-rw-r--r--java/res/layout/emoji_keyboard_view.xml18
-rw-r--r--java/res/values-hy/donottranslate.xml29
-rw-r--r--java/res/values-km/donottranslate.xml23
-rw-r--r--java/res/values/colors.xml13
-rw-r--r--java/res/values/dimens.xml3
-rw-r--r--java/res/values/donottranslate.xml42
-rw-r--r--java/res/values/keypress-vibration-durations.xml4
-rw-r--r--java/res/values/themes-gb.xml30
-rw-r--r--java/res/values/themes-ics.xml46
-rw-r--r--java/res/xml-sw600dp/row_pcqwerty5.xml2
-rw-r--r--java/res/xml-sw600dp/rows_khmer.xml72
-rw-r--r--java/res/xml-sw600dp/rows_lao.xml13
-rw-r--r--java/res/xml-sw600dp/rows_thai.xml13
-rw-r--r--java/res/xml/kbd_khmer.xml31
-rw-r--r--java/res/xml/key_styles_common.xml7
-rw-r--r--java/res/xml/key_styles_currency.xml2
-rw-r--r--java/res/xml/keyboard_layout_set_khmer.xml58
-rw-r--r--java/res/xml/keys_comma_period.xml14
-rw-r--r--java/res/xml/method.xml271
-rw-r--r--java/res/xml/row_pcqwerty5.xml10
-rw-r--r--java/res/xml/row_qwerty4.xml8
-rw-r--r--java/res/xml/rowkeys_khmer1.xml194
-rw-r--r--java/res/xml/rowkeys_khmer2.xml144
-rw-r--r--java/res/xml/rowkeys_khmer3.xml138
-rw-r--r--java/res/xml/rowkeys_khmer4.xml113
-rw-r--r--java/res/xml/rows_khmer.xml56
-rw-r--r--java/src/com/android/inputmethod/compat/ActivityManagerCompatUtils.java46
-rw-r--r--java/src/com/android/inputmethod/keyboard/EmojiCategoryPageIndicatorView.java67
-rw-r--r--java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java161
-rw-r--r--java/src/com/android/inputmethod/keyboard/EmojiLayoutParams.java20
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java9
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardView.java11
-rw-r--r--java/src/com/android/inputmethod/keyboard/MainKeyboardView.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/ProximityInfo.java12
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java56
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java40
-rw-r--r--java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java2
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java43
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java3
-rw-r--r--java/src/com/android/inputmethod/latin/Constants.java14
-rw-r--r--java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java25
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java167
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java158
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputConnection.java72
-rw-r--r--java/src/com/android/inputmethod/latin/SubtypeSwitcher.java17
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java15
-rw-r--r--java/src/com/android/inputmethod/latin/UserBinaryDictionary.java16
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java4
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java15
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java4
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/DictDecoder.java206
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FormatSpec.java18
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java178
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Ver3DictEncoder.java2
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java259
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java31
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java10
-rw-r--r--java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java8
-rw-r--r--java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java11
-rw-r--r--java/src/com/android/inputmethod/latin/utils/StringUtils.java165
-rw-r--r--java/src/com/android/inputmethod/latin/utils/TextRange.java4
-rw-r--r--java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java5
300 files changed, 2645 insertions, 585 deletions
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.png
index 9aa8db60e..87211a502 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_active_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png
index 5e6a9d6a4..fa2cb8542 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png
index a3ba2230d..b1af23b6c 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png
index 9f4587b4a..814e40235 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png
index 7ec33dd20..90abe3940 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
index 655bc01b1..48eeb3f54 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
index 138e915d9..71e0683cd 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png
index baff85873..6da273b09 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png
index 5612c51a1..6768241a7 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.png
index c2e8b3779..10f8e97e4 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_popup_selected_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_light.png b/java/res/drawable-hdpi/ic_emoji_light.png
deleted file mode 100644
index 2e3638bf3..000000000
--- a/java/res/drawable-hdpi/ic_emoji_light.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_ime_light.png b/java/res/drawable-hdpi/ic_ime_light.png
deleted file mode 100644
index 4fd3ba126..000000000
--- a/java/res/drawable-hdpi/ic_ime_light.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_ime_switcher_dark.png b/java/res/drawable-hdpi/ic_ime_switcher_dark.png
new file mode 100644
index 000000000..7506af5a3
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_ime_switcher_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_subtype_keyboard.png b/java/res/drawable-hdpi/ic_subtype_keyboard.png
deleted file mode 100644
index 484305655..000000000
--- a/java/res/drawable-hdpi/ic_subtype_keyboard.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_subtype_mic_dark.png b/java/res/drawable-hdpi/ic_subtype_mic_dark.png
new file mode 100644
index 000000000..eacbcd255
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_subtype_mic_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_background_ics.9.png b/java/res/drawable-hdpi/keyboard_background_holo.9.png
index 73868751c..73868751c 100644
--- a/java/res/drawable-hdpi/keyboard_background_ics.9.png
+++ b/java/res/drawable-hdpi/keyboard_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_background_holo.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_background_holo.9.png
index 28b406a5c..50ed568ff 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_background_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_left_background_holo.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_left_background_holo.9.png
index e42cd88dc..9fa6d0003 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_left_background_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_left_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_left_more_background_holo.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_left_more_background_holo.9.png
index 160344073..c73269b7e 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_left_more_background_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_left_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_more_background_holo.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_more_background_holo.9.png
index a40d4277c..fffd4021e 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_more_background_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_right_background_holo.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_right_background_holo.9.png
index 1f6807376..61c23c19b 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_right_background_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_right_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_right_more_background_holo.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_right_more_background_holo.9.png
index ec53593d9..827d74363 100644
--- a/java/res/drawable-hdpi/keyboard_key_feedback_right_more_background_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_right_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_popup_panel_background_holo.9.png b/java/res/drawable-hdpi/keyboard_popup_panel_background_holo.9.png
index 53d7b6fb3..dc2fc7dfc 100644
--- a/java/res/drawable-hdpi/keyboard_popup_panel_background_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_popup_panel_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.png b/java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.png
index e173beb73..32f426402 100644
--- a/java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.png
+++ b/java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_delete.png b/java/res/drawable-hdpi/sym_keyboard_delete.png
deleted file mode 100644
index 0591b82cd..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_delete.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_delete_holo.png b/java/res/drawable-hdpi/sym_keyboard_delete_holo.png
deleted file mode 100644
index d3e108846..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_delete_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_delete_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_delete_holo_dark.png
new file mode 100644
index 000000000..d2d3560a3
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_delete_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_label_mic.png b/java/res/drawable-hdpi/sym_keyboard_label_mic.png
deleted file mode 100644
index 4e0a8ed8e..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_label_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-hdpi/sym_keyboard_label_mic_holo.png
deleted file mode 100644
index f8df44741..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_label_mic_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_language_switch.png b/java/res/drawable-hdpi/sym_keyboard_language_switch.png
deleted file mode 100644
index 7b980a0c8..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_language_switch.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_language_switch_dark.png b/java/res/drawable-hdpi/sym_keyboard_language_switch_dark.png
new file mode 100644
index 000000000..78d3a1fc5
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_language_switch_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_mic.png b/java/res/drawable-hdpi/sym_keyboard_mic.png
deleted file mode 100644
index 520a40f09..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.png
new file mode 100644
index 000000000..3c5469403
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_return.png b/java/res/drawable-hdpi/sym_keyboard_return.png
deleted file mode 100644
index 9743c7f2f..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_return.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_return_holo.png b/java/res/drawable-hdpi/sym_keyboard_return_holo.png
deleted file mode 100644
index 8978934b8..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_return_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_return_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_return_holo_dark.png
new file mode 100644
index 000000000..60d893cf3
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_return_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_search.png b/java/res/drawable-hdpi/sym_keyboard_search.png
deleted file mode 100644
index 8cd28c64a..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_search.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_search_holo.png b/java/res/drawable-hdpi/sym_keyboard_search_holo.png
deleted file mode 100644
index b987a20f1..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_search_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_search_holo_dark.png
new file mode 100644
index 000000000..fa0d1bde1
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_search_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_settings.png b/java/res/drawable-hdpi/sym_keyboard_settings.png
deleted file mode 100644
index 1e5bf939e..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_settings.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_settings_holo.png b/java/res/drawable-hdpi/sym_keyboard_settings_holo.png
deleted file mode 100644
index 5af09ad8c..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_settings_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_settings_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_settings_holo_dark.png
new file mode 100644
index 000000000..c76008ab3
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_settings_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift.png b/java/res/drawable-hdpi/sym_keyboard_shift.png
deleted file mode 100644
index 8e3d0320c..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_shift.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_holo.png b/java/res/drawable-hdpi/sym_keyboard_shift_holo.png
deleted file mode 100644
index c58f9ab5c..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_shift_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_shift_holo_dark.png
new file mode 100644
index 000000000..544b7e141
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_shift_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_locked.png b/java/res/drawable-hdpi/sym_keyboard_shift_locked.png
deleted file mode 100644
index d345634a6..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_shift_locked.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.png
deleted file mode 100644
index 7a5c03713..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo_dark.png
new file mode 100644
index 000000000..9b1d6a015
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_space_holo.png b/java/res/drawable-hdpi/sym_keyboard_space_holo.png
deleted file mode 100644
index e8bc3902d..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_space_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_space_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_space_holo_dark.png
new file mode 100644
index 000000000..12e27ade7
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_space_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_tab.png b/java/res/drawable-hdpi/sym_keyboard_tab.png
deleted file mode 100644
index 3d1c5c0ea..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_tab.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_tab_holo.png b/java/res/drawable-hdpi/sym_keyboard_tab_holo.png
deleted file mode 100644
index 8d10d057c..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_tab_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_tab_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_tab_holo_dark.png
new file mode 100644
index 000000000..2e5f811f3
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_tab_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_holo.png b/java/res/drawable-hdpi/sym_keyboard_voice_holo.png
deleted file mode 100644
index 8a6336a57..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_voice_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.png
new file mode 100644
index 000000000..c1e16a651
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-hdpi/sym_keyboard_voice_off_holo.png
deleted file mode 100644
index edf1379ab..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_voice_off_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_off_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_voice_off_holo_dark.png
new file mode 100644
index 000000000..26d068490
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_voice_off_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-hdpi/sym_keyboard_zwj_holo.png
deleted file mode 100644
index 5fa30ceb8..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_zwj_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_zwj_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_zwj_holo_dark.png
new file mode 100644
index 000000000..9f9bc173b
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_zwj_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png
deleted file mode 100644
index 91367f3d2..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_zwnj_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_zwnj_holo_dark.png
new file mode 100644
index 000000000..f0f832e13
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_zwnj_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.png
index e810c7789..f98653ea1 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_active_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png
index d449d7600..8e9a34957 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
index fa24d5987..58a316fba 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
index f3fc64114..b7b2dca43 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
index 8f340d355..4a92b80dd 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
index 53ea5f894..72125a065 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
index 69c84e7ec..82413d4cc 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png
index 976083fdf..2915588bf 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png
index c39dd4a94..049385984 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.png
index 93a6e7921..ee0aae28b 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_popup_selected_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_light.png b/java/res/drawable-mdpi/ic_emoji_light.png
deleted file mode 100644
index a3195041a..000000000
--- a/java/res/drawable-mdpi/ic_emoji_light.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_ime_light.png b/java/res/drawable-mdpi/ic_ime_light.png
deleted file mode 100644
index d94ad6f7e..000000000
--- a/java/res/drawable-mdpi/ic_ime_light.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_ime_switcher_dark.png b/java/res/drawable-mdpi/ic_ime_switcher_dark.png
new file mode 100644
index 000000000..152f65300
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_ime_switcher_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_subtype_keyboard.png b/java/res/drawable-mdpi/ic_subtype_keyboard.png
deleted file mode 100644
index d28efc106..000000000
--- a/java/res/drawable-mdpi/ic_subtype_keyboard.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_background_ics.9.png b/java/res/drawable-mdpi/keyboard_background_holo.9.png
index fbe97f7a2..fbe97f7a2 100644
--- a/java/res/drawable-mdpi/keyboard_background_ics.9.png
+++ b/java/res/drawable-mdpi/keyboard_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_background_holo.9.png
index 7a9f640d1..564f5460c 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_background_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_left_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_left_background_holo.9.png
index 5b06f09bb..427c87061 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_left_background_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_left_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_left_more_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_left_more_background_holo.9.png
index fd992d6f4..ea757296d 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_left_more_background_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_left_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_more_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_more_background_holo.9.png
index 128dcd6ad..1911c429f 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_more_background_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_right_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_right_background_holo.9.png
index 0b08d1747..cdef116d2 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_right_background_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_right_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_right_more_background_holo.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_right_more_background_holo.9.png
index cf0b33c1d..dea5d076c 100644
--- a/java/res/drawable-mdpi/keyboard_key_feedback_right_more_background_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_right_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_popup_panel_background_holo.9.png b/java/res/drawable-mdpi/keyboard_popup_panel_background_holo.9.png
index 61988a8e1..441edc30b 100644
--- a/java/res/drawable-mdpi/keyboard_popup_panel_background_holo.9.png
+++ b/java/res/drawable-mdpi/keyboard_popup_panel_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/suggestions_strip_divider.png b/java/res/drawable-mdpi/suggestions_strip_divider.png
index 2dbe2f94b..21e904939 100644
--- a/java/res/drawable-mdpi/suggestions_strip_divider.png
+++ b/java/res/drawable-mdpi/suggestions_strip_divider.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_delete.png b/java/res/drawable-mdpi/sym_keyboard_delete.png
deleted file mode 100644
index 1b0f3f836..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_delete.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_delete_holo.png b/java/res/drawable-mdpi/sym_keyboard_delete_holo.png
deleted file mode 100644
index 86be35185..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_delete_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_delete_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_delete_holo_dark.png
new file mode 100644
index 000000000..edd9d164e
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_delete_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_label_mic.png b/java/res/drawable-mdpi/sym_keyboard_label_mic.png
deleted file mode 100644
index a354d5321..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_label_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-mdpi/sym_keyboard_label_mic_holo.png
deleted file mode 100644
index 15606e95f..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_label_mic_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_label_mic_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_label_mic_holo_dark.png
new file mode 100644
index 000000000..537f39b02
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_label_mic_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_language_switch.png b/java/res/drawable-mdpi/sym_keyboard_language_switch.png
deleted file mode 100644
index f840a631d..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_language_switch.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_language_switch_dark.png b/java/res/drawable-mdpi/sym_keyboard_language_switch_dark.png
new file mode 100644
index 000000000..828929bc8
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_language_switch_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_mic.png b/java/res/drawable-mdpi/sym_keyboard_mic.png
deleted file mode 100644
index e926b3fa6..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.png
new file mode 100644
index 000000000..5e58866a7
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_mic_holo_light.png b/java/res/drawable-mdpi/sym_keyboard_mic_holo_light.png
new file mode 100644
index 000000000..84a63dc7f
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_mic_holo_light.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_return.png b/java/res/drawable-mdpi/sym_keyboard_return.png
deleted file mode 100644
index 0c10f004a..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_return.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_return_holo.png b/java/res/drawable-mdpi/sym_keyboard_return_holo.png
deleted file mode 100644
index bfcb91328..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_return_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_return_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_return_holo_dark.png
new file mode 100644
index 000000000..e10103caf
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_return_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_search.png b/java/res/drawable-mdpi/sym_keyboard_search.png
deleted file mode 100644
index 614f85f5e..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_search.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_search_holo.png b/java/res/drawable-mdpi/sym_keyboard_search_holo.png
deleted file mode 100644
index dd3c83a84..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_search_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_search_holo_dark.png
new file mode 100644
index 000000000..290cde41b
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_search_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_settings.png b/java/res/drawable-mdpi/sym_keyboard_settings.png
deleted file mode 100644
index ad7618fa0..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_settings.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_settings_holo.png b/java/res/drawable-mdpi/sym_keyboard_settings_holo.png
deleted file mode 100644
index 36c8c9623..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_settings_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_settings_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_settings_holo_dark.png
new file mode 100644
index 000000000..a76a976c5
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_settings_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift.png b/java/res/drawable-mdpi/sym_keyboard_shift.png
deleted file mode 100644
index 5109b0471..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_shift.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_holo.png b/java/res/drawable-mdpi/sym_keyboard_shift_holo.png
deleted file mode 100644
index 621946455..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_shift_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_shift_holo_dark.png
new file mode 100644
index 000000000..37375d935
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_shift_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_locked.png b/java/res/drawable-mdpi/sym_keyboard_shift_locked.png
deleted file mode 100644
index 244179c2d..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_shift_locked.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.png
deleted file mode 100644
index fb3a020d8..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo_dark.png
new file mode 100644
index 000000000..3654868dc
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_smiley_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_smiley_holo_dark.png
new file mode 100644
index 000000000..71272bb88
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_smiley_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_space_holo.png b/java/res/drawable-mdpi/sym_keyboard_space_holo.png
deleted file mode 100644
index 1f787d573..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_space_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_space_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_space_holo_dark.png
new file mode 100644
index 000000000..a38f99496
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_space_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_tab.png b/java/res/drawable-mdpi/sym_keyboard_tab.png
deleted file mode 100644
index eddb9a592..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_tab.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_tab_holo.png b/java/res/drawable-mdpi/sym_keyboard_tab_holo.png
deleted file mode 100644
index 8d20153ee..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_tab_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_tab_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_tab_holo_dark.png
new file mode 100644
index 000000000..f883807f2
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_tab_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_holo.png b/java/res/drawable-mdpi/sym_keyboard_voice_holo.png
deleted file mode 100644
index 0795fcc9b..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_voice_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.png
new file mode 100644
index 000000000..16be37d05
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-mdpi/sym_keyboard_voice_off_holo.png
deleted file mode 100644
index f76da5797..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_voice_off_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_off_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_voice_off_holo_dark.png
new file mode 100644
index 000000000..95d718a46
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_voice_off_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png
deleted file mode 100644
index 70370d83d..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_zwj_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_zwj_holo_dark.png
new file mode 100644
index 000000000..8957e282b
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_zwj_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png
deleted file mode 100644
index a69eade17..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_zwnj_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_zwnj_holo_dark.png
new file mode 100644
index 000000000..5f49e64aa
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_zwnj_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.png
index d990c0258..738316d66 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png
index d2cd029bb..a2f6ac0e2 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
index bca39cf17..2f00fc623 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
index ab8fb2e86..20251a000 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png
index 3871689ef..84d173967 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
index 912506368..ee4490eac 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
index 35ce67fdc..e8124776c 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png
index b26f1d27a..0ef4a4b5f 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png
index c23a4b225..f770962c3 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.png
index 0c7bfdace..891d00024 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_popup_selected_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_light.png b/java/res/drawable-xhdpi/ic_emoji_light.png
deleted file mode 100644
index 21bc9090d..000000000
--- a/java/res/drawable-xhdpi/ic_emoji_light.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_ime_light.png b/java/res/drawable-xhdpi/ic_ime_light.png
deleted file mode 100644
index 9d2caeda6..000000000
--- a/java/res/drawable-xhdpi/ic_ime_light.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_ime_switcher_dark.png b/java/res/drawable-xhdpi/ic_ime_switcher_dark.png
new file mode 100644
index 000000000..c567077e5
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_ime_switcher_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_subtype_keyboard.png b/java/res/drawable-xhdpi/ic_subtype_keyboard.png
deleted file mode 100644
index a79bb3458..000000000
--- a/java/res/drawable-xhdpi/ic_subtype_keyboard.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_subtype_mic_dark.png b/java/res/drawable-xhdpi/ic_subtype_mic_dark.png
new file mode 100644
index 000000000..17581ba89
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_subtype_mic_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_background_ics.9.png b/java/res/drawable-xhdpi/keyboard_background_holo.9.png
index f5c9df3e5..f5c9df3e5 100644
--- a/java/res/drawable-xhdpi/keyboard_background_ics.9.png
+++ b/java/res/drawable-xhdpi/keyboard_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_background_holo.9.png
index d999127f2..e8c65f677 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_background_holo.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_left_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_left_background_holo.9.png
index c4d694136..543bc763e 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_left_background_holo.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_left_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_left_more_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_left_more_background_holo.9.png
index 5429c1785..ec42aadb6 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_left_more_background_holo.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_left_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_holo.9.png
index 5135a0869..319e9d7cf 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_holo.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_right_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_right_background_holo.9.png
index 19a77a29f..052032be7 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_right_background_holo.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_right_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_right_more_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_right_more_background_holo.9.png
index ae2ffff8e..c7e9d1c9e 100644
--- a/java/res/drawable-xhdpi/keyboard_key_feedback_right_more_background_holo.9.png
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_right_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_popup_panel_background_holo.9.png b/java/res/drawable-xhdpi/keyboard_popup_panel_background_holo.9.png
index 1dee699f4..dde1856e3 100644
--- a/java/res/drawable-xhdpi/keyboard_popup_panel_background_holo.9.png
+++ b/java/res/drawable-xhdpi/keyboard_popup_panel_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/suggestions_strip_divider.png b/java/res/drawable-xhdpi/suggestions_strip_divider.png
index 0d8b98437..4101ebc59 100644
--- a/java/res/drawable-xhdpi/suggestions_strip_divider.png
+++ b/java/res/drawable-xhdpi/suggestions_strip_divider.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_delete.png b/java/res/drawable-xhdpi/sym_keyboard_delete.png
deleted file mode 100644
index 3c0b8b186..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_delete.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_delete_holo.png b/java/res/drawable-xhdpi/sym_keyboard_delete_holo.png
deleted file mode 100644
index 354c09ee6..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_delete_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_delete_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_delete_holo_dark.png
new file mode 100644
index 000000000..e3e37d5ff
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_delete_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_label_mic.png b/java/res/drawable-xhdpi/sym_keyboard_label_mic.png
deleted file mode 100644
index 49810a02f..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_label_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-xhdpi/sym_keyboard_label_mic_holo.png
deleted file mode 100644
index 8eeb179f5..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_label_mic_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_language_switch.png b/java/res/drawable-xhdpi/sym_keyboard_language_switch.png
deleted file mode 100644
index 6c2fb53ec..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_language_switch.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_language_switch_dark.png b/java/res/drawable-xhdpi/sym_keyboard_language_switch_dark.png
new file mode 100644
index 000000000..b8687f550
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_language_switch_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_mic.png b/java/res/drawable-xhdpi/sym_keyboard_mic.png
deleted file mode 100644
index 1323b6d1e..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.png
new file mode 100644
index 000000000..566ba1fcd
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_return.png b/java/res/drawable-xhdpi/sym_keyboard_return.png
deleted file mode 100644
index ad061227e..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_return.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_return_holo.png b/java/res/drawable-xhdpi/sym_keyboard_return_holo.png
deleted file mode 100644
index ba424adfd..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_return_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_return_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_return_holo_dark.png
new file mode 100644
index 000000000..7b7ad1747
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_return_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_search.png b/java/res/drawable-xhdpi/sym_keyboard_search.png
deleted file mode 100644
index aa785a221..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_search.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_search_holo.png b/java/res/drawable-xhdpi/sym_keyboard_search_holo.png
deleted file mode 100644
index f2fb2a2b5..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_search_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_search_holo_dark.png
new file mode 100644
index 000000000..36b1646bb
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_search_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_settings.png b/java/res/drawable-xhdpi/sym_keyboard_settings.png
deleted file mode 100644
index 50704255d..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_settings.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_settings_holo.png b/java/res/drawable-xhdpi/sym_keyboard_settings_holo.png
deleted file mode 100644
index 99ee97dbf..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_settings_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_settings_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_settings_holo_dark.png
new file mode 100644
index 000000000..05eaffe2e
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_settings_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift.png b/java/res/drawable-xhdpi/sym_keyboard_shift.png
deleted file mode 100644
index 290170619..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_shift.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_holo.png b/java/res/drawable-xhdpi/sym_keyboard_shift_holo.png
deleted file mode 100644
index 1046b4545..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_shift_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_shift_holo_dark.png
new file mode 100644
index 000000000..5ab549114
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_shift_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_locked.png b/java/res/drawable-xhdpi/sym_keyboard_shift_locked.png
deleted file mode 100644
index a5deb60e9..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_shift_locked.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.png
deleted file mode 100644
index 6acb565d9..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo_dark.png
new file mode 100644
index 000000000..b820eaabb
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_smiley_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_smiley_holo_dark.png
new file mode 100644
index 000000000..686831fd3
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_smiley_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_space_holo.png b/java/res/drawable-xhdpi/sym_keyboard_space_holo.png
deleted file mode 100644
index 504a3ed45..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_space_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_space_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_space_holo_dark.png
new file mode 100644
index 000000000..7114b740f
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_space_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_tab.png b/java/res/drawable-xhdpi/sym_keyboard_tab.png
deleted file mode 100644
index 0ef2ab5b9..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_tab.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_tab_holo.png b/java/res/drawable-xhdpi/sym_keyboard_tab_holo.png
deleted file mode 100644
index ff380eeab..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_tab_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_tab_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_tab_holo_dark.png
new file mode 100644
index 000000000..73ebfe525
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_tab_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_holo.png b/java/res/drawable-xhdpi/sym_keyboard_voice_holo.png
deleted file mode 100644
index b2bb9b803..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_voice_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.png
new file mode 100644
index 000000000..944a8524d
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.png
deleted file mode 100644
index 23e75bfe7..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo_dark.png
new file mode 100644
index 000000000..2016caf40
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png
deleted file mode 100644
index 26694274e..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwj_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_zwj_holo_dark.png
new file mode 100644
index 000000000..2f9607add
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_zwj_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png
deleted file mode 100644
index 75a22b65f..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo_dark.png
new file mode 100644
index 000000000..ab07f7549
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_holo.9.png
index 680421eaf..b35c29fe6 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_holo.9.png
index ae2675053..17f0a7a58 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
index c92a669f9..b0e815eb2 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_on_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
index 40f5011c0..97f96258e 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_holo.9.png
index 6ff6319d3..dfb16a76b 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
index 818ea70fd..bf1d34686 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_off_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
index a476d2a9e..962277165 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_on_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_light_normal_holo.9.png
index 9c280a655..4ddfdcb6c 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_light_normal_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_light_normal_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_light_pressed_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_light_pressed_holo.9.png
index 3c17c5eec..17144b673 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_light_pressed_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_light_pressed_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_popup_selected_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_popup_selected_holo.9.png
index 6d2af5942..0cbb2ec84 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_popup_selected_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_popup_selected_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_light.png b/java/res/drawable-xxhdpi/ic_emoji_light.png
deleted file mode 100644
index 7480e5294..000000000
--- a/java/res/drawable-xxhdpi/ic_emoji_light.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_ime_light.png b/java/res/drawable-xxhdpi/ic_ime_light.png
deleted file mode 100644
index 0309635d2..000000000
--- a/java/res/drawable-xxhdpi/ic_ime_light.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_ime_switcher_dark.png b/java/res/drawable-xxhdpi/ic_ime_switcher_dark.png
new file mode 100644
index 000000000..f99f7d0c7
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_ime_switcher_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_subtype_keyboard.png b/java/res/drawable-xxhdpi/ic_subtype_keyboard.png
deleted file mode 100644
index 0bb4283b0..000000000
--- a/java/res/drawable-xxhdpi/ic_subtype_keyboard.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_subtype_mic_dark.png b/java/res/drawable-xxhdpi/ic_subtype_mic_dark.png
new file mode 100644
index 000000000..811103a56
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_subtype_mic_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_background_ics.9.png b/java/res/drawable-xxhdpi/keyboard_background_holo.9.png
index bcef0f839..bcef0f839 100644
--- a/java/res/drawable-xxhdpi/keyboard_background_ics.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_background_holo.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_background_holo.9.png
index bd1ef3cd9..11eee94f3 100644
--- a/java/res/drawable-xxhdpi/keyboard_key_feedback_background_holo.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_left_background_holo.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_left_background_holo.9.png
index 65af4b569..2079e0462 100644
--- a/java/res/drawable-xxhdpi/keyboard_key_feedback_left_background_holo.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_left_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_left_more_background_holo.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_left_more_background_holo.9.png
index ac6750dcb..c4178d9a8 100644
--- a/java/res/drawable-xxhdpi/keyboard_key_feedback_left_more_background_holo.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_left_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_holo.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_holo.9.png
index cea7c05f6..121411a06 100644
--- a/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_holo.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_right_background_holo.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_right_background_holo.9.png
index 520fa7c6b..d3d8733fd 100644
--- a/java/res/drawable-xxhdpi/keyboard_key_feedback_right_background_holo.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_right_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_right_more_background_holo.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_right_more_background_holo.9.png
index eee221758..d7ec8bcb2 100644
--- a/java/res/drawable-xxhdpi/keyboard_key_feedback_right_more_background_holo.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_right_more_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_popup_panel_background_holo.9.png b/java/res/drawable-xxhdpi/keyboard_popup_panel_background_holo.9.png
index 721c24400..ca576deaf 100644
--- a/java/res/drawable-xxhdpi/keyboard_popup_panel_background_holo.9.png
+++ b/java/res/drawable-xxhdpi/keyboard_popup_panel_background_holo.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_delete_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_delete_holo.png
deleted file mode 100644
index be3cb7ce7..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_delete_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_delete_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_delete_holo_dark.png
new file mode 100644
index 000000000..92be79241
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_delete_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_label_mic_holo.png
deleted file mode 100644
index b6d4477bd..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_label_mic_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_language_switch.png b/java/res/drawable-xxhdpi/sym_keyboard_language_switch.png
deleted file mode 100644
index 7cd0684a0..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_language_switch.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_language_switch_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_language_switch_dark.png
new file mode 100644
index 000000000..88b55bb37
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_language_switch_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.png
new file mode 100644
index 000000000..f55af308c
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_return_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_return_holo.png
deleted file mode 100644
index 7d9580796..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_return_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_return_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_return_holo_dark.png
new file mode 100644
index 000000000..46ee50eba
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_return_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_search_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_search_holo.png
deleted file mode 100644
index 6b09d8e57..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_search_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_search_holo_dark.png
new file mode 100644
index 000000000..f518748ce
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_search_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_settings_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_settings_holo.png
deleted file mode 100644
index 7041bb6ce..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_settings_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_settings_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_settings_holo_dark.png
new file mode 100644
index 000000000..e4358463b
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_settings_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_shift_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_shift_holo.png
deleted file mode 100644
index 2b4fbbba6..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_shift_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_shift_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_shift_holo_dark.png
new file mode 100644
index 000000000..523286e6e
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_shift_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo.png
deleted file mode 100644
index 91c8603fd..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo_dark.png
new file mode 100644
index 000000000..87926d9a6
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_smiley_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_smiley_holo_dark.png
new file mode 100644
index 000000000..04b721617
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_smiley_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_space_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_space_holo.png
deleted file mode 100644
index 65aa5ea9b..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_space_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_space_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_space_holo_dark.png
new file mode 100644
index 000000000..1dab1f431
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_space_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_tab_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_tab_holo.png
deleted file mode 100644
index 1f4ae3df7..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_tab_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_tab_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_tab_holo_dark.png
new file mode 100644
index 000000000..6eb3eb0b3
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_tab_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_holo.png
deleted file mode 100644
index f04cadf6f..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_voice_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.png
new file mode 100644
index 000000000..6809f0711
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo.png
deleted file mode 100644
index e74d523bc..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo_dark.png
new file mode 100644
index 000000000..6bd506a11
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo.png
deleted file mode 100644
index 85289b2a3..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo_dark.png
new file mode 100644
index 000000000..5e225b837
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo.png
deleted file mode 100644
index e610678b1..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo_dark.png
new file mode 100644
index 000000000..cdfc0295b
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo_dark.png
Binary files differ
diff --git a/java/res/layout/emoji_keyboard_view.xml b/java/res/layout/emoji_keyboard_view.xml
index 5fee419d0..4566a5a1f 100644
--- a/java/res/layout/emoji_keyboard_view.xml
+++ b/java/res/layout/emoji_keyboard_view.xml
@@ -40,7 +40,7 @@
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent"
android:background="@drawable/tab_selected"
android:divider="@null"
android:tabStripEnabled="true"
@@ -61,17 +61,27 @@
android:visibility="gone" />
</FrameLayout>
</TabHost>
+ <View
+ android:layout_width="2dip"
+ android:layout_height="match_parent"
+ android:background="@drawable/suggestions_strip_divider" />
<ImageButton
android:id="@+id/emoji_keyboard_delete"
android:layout_width="0dip"
android:layout_weight="12.5"
android:layout_height="match_parent"
- android:src="@drawable/sym_keyboard_delete_holo" />
+ android:background="@color/emoji_key_background_color"
+ android:src="@drawable/sym_keyboard_delete_holo_dark" />
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="@+id/emoji_keyboard_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
+ <com.android.inputmethod.keyboard.EmojiCategoryPageIndicatorView
+ android:id="@+id/emoji_category_page_id_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@color/emoji_category_page_id_view_background" />
<LinearLayout
android:id="@+id/emoji_action_bar"
android:orientation="horizontal"
@@ -84,7 +94,7 @@
android:layout_width="0dip"
android:layout_weight="0.15"
android:layout_height="match_parent"
- android:src="@drawable/ic_ime_light" />
+ android:src="@drawable/ic_ime_switcher_dark" />
<ImageButton
android:id="@+id/emoji_keyboard_space"
android:layout_width="0dip"
@@ -95,6 +105,6 @@
android:layout_width="0dip"
android:layout_weight="0.15"
android:layout_height="match_parent"
- android:src="@drawable/sym_keyboard_return_holo" />
+ android:src="@drawable/sym_keyboard_return_holo_dark" />
</LinearLayout>
</com.android.inputmethod.keyboard.EmojiKeyboardView>
diff --git a/java/res/values-hy/donottranslate.xml b/java/res/values-hy/donottranslate.xml
new file mode 100644
index 000000000..4a6d188fb
--- /dev/null
+++ b/java/res/values-hy/donottranslate.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Same list as in English, but add armenian period and comma: -->
+ <!-- U+055D: "՝" ARMENIAN COMMA -->
+ <!-- U+0589: "։" ARMENIAN FULL STOP -->
+ <!-- Symbols that are normally followed by a space (used to add an auto-space after these) -->
+ <string name="symbols_followed_by_space">.,;:!?)]}&amp;&#x0589;&#x055D;</string>
+ <!-- Symbols that separate words. Adding armenian period and comma. -->
+ <!-- Don't remove the enclosing double quotes, they protect whitespace (not just U+0020) -->
+ <string name="symbols_word_separators">"&#x0009;&#x0020;\n"()[]{}*&amp;&lt;&gt;+=|.,;:!?/_\"&#x0589;&#x055D;</string>
+</resources>
diff --git a/java/res/values-km/donottranslate.xml b/java/res/values-km/donottranslate.xml
new file mode 100644
index 000000000..a9893feec
--- /dev/null
+++ b/java/res/values-km/donottranslate.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Whether this language uses spaces between words -->
+ <bool name="current_language_has_spaces">false</bool>
+</resources>
diff --git a/java/res/values/colors.xml b/java/res/values/colors.xml
index ea762f977..3803cb776 100644
--- a/java/res/values/colors.xml
+++ b/java/res/values/colors.xml
@@ -33,7 +33,7 @@
<color name="spacebar_text_color_gb">#FFC0C0C0</color>
<color name="spacebar_text_shadow_color_gb">#80000000</color>
<color name="gesture_floating_preview_color_gb">#C0000000</color>
- <!-- Color resources for IceCreamSandwich theme. -->
+ <!-- Color resources for IceCreamSandwich theme. Base color = 33B5E5 -->
<!-- android:color/holo_blue_light value is #FF33B5E5 -->
<color name="highlight_color_ics">#FF33B5E5</color>
<color name="typed_word_color_ics">#D833B5E5</color>
@@ -49,10 +49,21 @@
<color name="spacebar_text_color_ics">#FFC0C0C0</color>
<color name="spacebar_text_shadow_color_ics">#80000000</color>
<color name="gesture_floating_preview_color_ics">#C0000000</color>
+ <!-- Color resources for KLP theme. Base color = F0F0F0 -->
+ <color name="highlight_color_holo">#FFF0F0F0</color>
+ <color name="typed_word_color_holo">#D8F0F0F0</color>
+ <color name="suggested_word_color_holo">#B2F0F0F0</color>
+ <color name="highlight_translucent_color_holo">#99E0E0E0</color>
<!-- Color resources for setup wizard and tutorial -->
<color name="setup_background">#FFEBEBEB</color>
<color name="setup_text_dark">#FF707070</color>
<color name="setup_text_action">@android:color/holo_blue_light</color>
<color name="setup_step_background">@android:color/background_light</color>
<color name="setup_welcome_video_margin_color">#FFCCCCCC</color>
+ <color name="emoji_category_page_id_view_background">#FF000000</color>
+ <color name="emoji_category_page_id_view_foreground">#80FFFFFF</color>
+
+ <!-- TODO: Color which should be included in the theme -->
+ <color name="emoji_key_background_color">#00000000</color>
+ <color name="emoji_key_pressed_background_color">#30FFFFFF</color>
</resources>
diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml
index 88e327f26..4e3b2f567 100644
--- a/java/res/values/dimens.xml
+++ b/java/res/values/dimens.xml
@@ -113,13 +113,14 @@
<dimen name="gesture_floating_preview_text_offset">73dp</dimen>
<dimen name="gesture_floating_preview_horizontal_padding">24dp</dimen>
<dimen name="gesture_floating_preview_vertical_padding">16dp</dimen>
- <dimen name="gesture_floating_preview_round_radius">3dp</dimen>
+ <dimen name="gesture_floating_preview_round_radius">2dp</dimen>
<!-- Emoji keyboard -->
<fraction name="emoji_keyboard_key_width">14.2857%p</fraction>
<fraction name="emoji_keyboard_row_height">33%p</fraction>
<fraction name="emoji_keyboard_key_letter_size">90%p</fraction>
<integer name="emoji_keyboard_max_key_count">21</integer>
+ <dimen name="emoji_category_page_id_height">3dp</dimen>
<!-- Inset used in Accessibility mode to avoid accidental key presses when a finger slides off the screen. -->
<dimen name="accessibility_edge_slop">8dp</dimen>
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index 82c5ce456..42e692d2f 100644
--- a/java/res/values/donottranslate.xml
+++ b/java/res/values/donottranslate.xml
@@ -158,47 +158,47 @@
<!-- Compatibility map from subtypeLocale:subtypeExtraValue to keyboardLayoutSet -->
<string-array name="locale_and_extra_value_to_keyboard_layout_set_map">
- <item>en_US:TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>en_US:TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwerty</item>
- <item>en_GB:TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>en_GB:TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwerty</item>
- <item>ar:SupportTouchPositionCorrection</item>
+ <item>ar:SupportTouchPositionCorrection,EmojiCapable</item>
<item>arabic</item>
- <item>cs:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>cs:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwertz</item>
- <item>da:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>da:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>nordic</item>
- <item>de:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>de:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwertz</item>
- <item>es:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>es:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>spanish</item>
- <item>fi:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>fi:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>nordic</item>
- <item>fr:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>fr:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>azerty</item>
- <item>fr_CA:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>fr_CA:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwerty</item>
- <item>hr:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>hr:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwertz</item>
- <item>hu:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>hu:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwertz</item>
- <item>it:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>it:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwerty</item>
- <item>iw:SupportTouchPositionCorrection</item>
+ <item>iw:SupportTouchPositionCorrection,EmojiCapable</item>
<item>hebrew</item>
- <item>nb:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>nb:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>nordic</item>
- <item>nl:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>nl:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwerty</item>
- <item>pl:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>pl:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwerty</item>
- <item>ru:SupportTouchPositionCorrection</item>
+ <item>ru:SupportTouchPositionCorrection,EmojiCapable</item>
<item>east_slavic</item>
- <item>sr:SupportTouchPositionCorrection</item>
+ <item>sr:SupportTouchPositionCorrection,EmojiCapable</item>
<item>south_slavic</item>
- <item>sv:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>sv:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>nordic</item>
- <item>tr:AsciiCapable,SupportTouchPositionCorrection</item>
+ <item>tr:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwerty</item>
</string-array>
diff --git a/java/res/values/keypress-vibration-durations.xml b/java/res/values/keypress-vibration-durations.xml
index 53448c3e1..ee0ac003c 100644
--- a/java/res/values/keypress-vibration-durations.xml
+++ b/java/res/values/keypress-vibration-durations.xml
@@ -55,8 +55,8 @@
<item>MODEL=HTL22:MANUFACTURER=HTC,15</item>
<!-- Motorola Razor M -->
<item>MODEL=XT907:MANUFACTURER=motorola,30</item>
- <!-- Sony Xperia Z -->
- <item>MODEL=C6603:MANUFACTURER=Sony,35</item>
+ <!-- Sony Xperia Z, Z Ultra -->
+ <item>MODEL=C6603|C6806:MANUFACTURER=Sony,35</item>
<!-- Default value for unknown device. The negative value means system default. -->
<item>,-1</item>
</string-array>
diff --git a/java/res/values/themes-gb.xml b/java/res/values/themes-gb.xml
index 7f8dd235b..d9ac4acb2 100644
--- a/java/res/values/themes-gb.xml
+++ b/java/res/values/themes-gb.xml
@@ -32,25 +32,25 @@
</style>
<style name="KeyboardIcons.GB">
<!-- Keyboard icons -->
- <item name="iconShiftKey">@drawable/sym_keyboard_shift</item>
- <item name="iconDeleteKey">@drawable/sym_keyboard_delete</item>
- <item name="iconSettingsKey">@drawable/sym_keyboard_settings</item>
- <item name="iconSpaceKey">@drawable/sym_keyboard_space</item>
- <item name="iconEnterKey">@drawable/sym_keyboard_return</item>
- <item name="iconSearchKey">@drawable/sym_keyboard_search</item>
- <item name="iconTabKey">@drawable/sym_keyboard_tab</item>
- <item name="iconShortcutKey">@drawable/sym_keyboard_mic</item>
- <item name="iconShortcutForLabel">@drawable/sym_keyboard_label_mic</item>
+ <item name="iconShiftKey">@drawable/sym_keyboard_shift_holo_dark</item>
+ <item name="iconDeleteKey">@drawable/sym_keyboard_delete_holo_dark</item>
+ <item name="iconSettingsKey">@drawable/sym_keyboard_settings_holo_dark</item>
+ <item name="iconSpaceKey">@drawable/sym_keyboard_space_holo_dark</item>
+ <item name="iconEnterKey">@drawable/sym_keyboard_return_holo_dark</item>
+ <item name="iconSearchKey">@drawable/sym_keyboard_search_holo_dark</item>
+ <item name="iconTabKey">@drawable/sym_keyboard_tab_holo_dark</item>
+ <item name="iconShortcutKey">@drawable/sym_keyboard_mic_holo_dark</item>
+ <item name="iconShortcutForLabel">@drawable/sym_keyboard_label_mic_holo_dark</item>
<item name="iconSpaceKeyForNumberLayout">@drawable/sym_keyboard_space</item>
- <item name="iconShiftKeyShifted">@drawable/sym_keyboard_shift_locked</item>
+ <item name="iconShiftKeyShifted">@drawable/sym_keyboard_shift_locked_holo_dark</item>
<!-- TODO: Needs non-holo disabled shortcut icon drawable -->
- <item name="iconShortcutKeyDisabled">@drawable/sym_keyboard_voice_off_holo</item>
+ <item name="iconShortcutKeyDisabled">@drawable/sym_keyboard_voice_off_holo_dark</item>
<item name="iconTabKeyPreview">@drawable/sym_keyboard_feedback_tab</item>
- <item name="iconLanguageSwitchKey">@drawable/sym_keyboard_language_switch</item>
+ <item name="iconLanguageSwitchKey">@drawable/sym_keyboard_language_switch_dark</item>
<!-- TODO: Needs dedicated black theme ZWNJ and ZWJ icons -->
- <item name="iconZwnjKey">@drawable/sym_keyboard_zwnj_holo</item>
- <item name="iconZwjKey">@drawable/sym_keyboard_zwj_holo</item>
- <item name="iconEmojiKey">@drawable/ic_emoji_light</item>
+ <item name="iconZwnjKey">@drawable/sym_keyboard_zwnj_holo_dark</item>
+ <item name="iconZwjKey">@drawable/sym_keyboard_zwj_holo_dark</item>
+ <item name="iconEmojiKey">@drawable/sym_keyboard_smiley_holo_dark</item>
</style>
<style
name="Keyboard.GB"
diff --git a/java/res/values/themes-ics.xml b/java/res/values/themes-ics.xml
index 19fb4fd27..33dd50c2c 100644
--- a/java/res/values/themes-ics.xml
+++ b/java/res/values/themes-ics.xml
@@ -35,23 +35,23 @@
<!-- TODO: The following holo icon for phone (drawable-hdpi and drawable-xhdpi) are missing.
sym_keyboard_123_mic_holo
-->
- <item name="iconShiftKey">@drawable/sym_keyboard_shift_holo</item>
- <item name="iconDeleteKey">@drawable/sym_keyboard_delete_holo</item>
- <item name="iconSettingsKey">@drawable/sym_keyboard_settings_holo</item>
+ <item name="iconShiftKey">@drawable/sym_keyboard_shift_holo_dark</item>
+ <item name="iconDeleteKey">@drawable/sym_keyboard_delete_holo_dark</item>
+ <item name="iconSettingsKey">@drawable/sym_keyboard_settings_holo_dark</item>
<item name="iconSpaceKey">@null</item>
- <item name="iconEnterKey">@drawable/sym_keyboard_return_holo</item>
- <item name="iconSearchKey">@drawable/sym_keyboard_search_holo</item>
- <item name="iconTabKey">@drawable/sym_keyboard_tab_holo</item>
- <item name="iconShortcutKey">@drawable/sym_keyboard_voice_holo</item>
- <item name="iconShortcutForLabel">@drawable/sym_keyboard_label_mic_holo</item>
- <item name="iconSpaceKeyForNumberLayout">@drawable/sym_keyboard_space_holo</item>
- <item name="iconShiftKeyShifted">@drawable/sym_keyboard_shift_locked_holo</item>
- <item name="iconShortcutKeyDisabled">@drawable/sym_keyboard_voice_off_holo</item>
+ <item name="iconEnterKey">@drawable/sym_keyboard_return_holo_dark</item>
+ <item name="iconSearchKey">@drawable/sym_keyboard_search_holo_dark</item>
+ <item name="iconTabKey">@drawable/sym_keyboard_tab_holo_dark</item>
+ <item name="iconShortcutKey">@drawable/sym_keyboard_voice_holo_dark</item>
+ <item name="iconShortcutForLabel">@drawable/sym_keyboard_label_mic_holo_dark</item>
+ <item name="iconSpaceKeyForNumberLayout">@drawable/sym_keyboard_space_holo_dark</item>
+ <item name="iconShiftKeyShifted">@drawable/sym_keyboard_shift_locked_holo_dark</item>
+ <item name="iconShortcutKeyDisabled">@drawable/sym_keyboard_voice_off_holo_dark</item>
<item name="iconTabKeyPreview">@drawable/sym_keyboard_feedback_tab</item>
- <item name="iconLanguageSwitchKey">@drawable/sym_keyboard_language_switch</item>
- <item name="iconZwnjKey">@drawable/sym_keyboard_zwnj_holo</item>
- <item name="iconZwjKey">@drawable/sym_keyboard_zwj_holo</item>
- <item name="iconEmojiKey">@drawable/ic_emoji_light</item>
+ <item name="iconLanguageSwitchKey">@drawable/sym_keyboard_language_switch_dark</item>
+ <item name="iconZwnjKey">@drawable/sym_keyboard_zwnj_holo_dark</item>
+ <item name="iconZwjKey">@drawable/sym_keyboard_zwj_holo_dark</item>
+ <item name="iconEmojiKey">@drawable/sym_keyboard_smiley_holo_dark</item>
</style>
<style
name="Keyboard.ICS"
@@ -69,7 +69,7 @@
name="KeyboardView.ICS"
parent="KeyboardView"
>
- <item name="android:background">@drawable/keyboard_background_ics</item>
+ <item name="android:background">@drawable/keyboard_background_holo</item>
<item name="keyBackground">@drawable/btn_keyboard_key_ics</item>
<item name="keyTypeface">bold</item>
<item name="keyTextColor">@color/key_text_color_ics</item>
@@ -88,10 +88,10 @@
>
<item name="keyPreviewLayout">@layout/key_preview_ics</item>
<item name="keyPreviewOffset">@dimen/key_preview_offset_ics</item>
- <item name="gestureFloatingPreviewTextColor">@color/highlight_color_ics</item>
+ <item name="gestureFloatingPreviewTextColor">@color/highlight_color_holo</item>
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_ics</item>
- <item name="gestureTrailColor">@color/highlight_color_ics</item>
- <item name="slidingKeyInputPreviewColor">@color/highlight_translucent_color_ics</item>
+ <item name="gestureTrailColor">@color/highlight_color_holo</item>
+ <item name="slidingKeyInputPreviewColor">@color/highlight_translucent_color_holo</item>
<item name="autoCorrectionSpacebarLedEnabled">false</item>
<item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led_holo</item>
<item name="spacebarTextColor">@color/spacebar_text_color_ics</item>
@@ -135,10 +135,10 @@
>
<item name="android:background">@drawable/keyboard_suggest_strip_holo</item>
<item name="suggestionStripOption">autoCorrectBold|validTypedWordBold</item>
- <item name="colorValidTypedWord">@color/typed_word_color_ics</item>
- <item name="colorTypedWord">@color/typed_word_color_ics</item>
- <item name="colorAutoCorrect">@color/highlight_color_ics</item>
- <item name="colorSuggested">@color/suggested_word_color_ics</item>
+ <item name="colorValidTypedWord">@color/typed_word_color_holo</item>
+ <item name="colorTypedWord">@color/typed_word_color_holo</item>
+ <item name="colorAutoCorrect">@color/highlight_color_holo</item>
+ <item name="colorSuggested">@color/suggested_word_color_holo</item>
<item name="alphaObsoleted">70%</item>
</style>
<style name="SuggestionWord.ICS">
diff --git a/java/res/xml-sw600dp/row_pcqwerty5.xml b/java/res/xml-sw600dp/row_pcqwerty5.xml
index a79d2a87f..b854f1051 100644
--- a/java/res/xml-sw600dp/row_pcqwerty5.xml
+++ b/java/res/xml-sw600dp/row_pcqwerty5.xml
@@ -53,7 +53,7 @@
latin:keyXPos="-9.0%p"
latin:keyWidth="9.0%p"
latin:backgroundType="functional"
- latin:keyboardLayout="@xml/key_symbols_period" />
+ latin:keyboardLayout="@xml/key_f2" />
</default>
</switch>
</Row>
diff --git a/java/res/xml-sw600dp/rows_khmer.xml b/java/res/xml-sw600dp/rows_khmer.xml
new file mode 100644
index 000000000..2824a5c2f
--- /dev/null
+++ b/java/res/xml-sw600dp/rows_khmer.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <include
+ latin:keyboardLayout="@xml/key_styles_common" />
+ <Row
+ latin:keyWidth="7.5%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_khmer1" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row
+ latin:keyWidth="7.5%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_khmer2" />
+ </Row>
+ <Row
+ latin:keyWidth="7.5%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_khmer3" />
+ <Key
+ latin:keyStyle="enterKeyStyle"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row
+ latin:keyWidth="7.5%p"
+ >
+ <Key
+ latin:keyStyle="shiftKeyStyle"
+ latin:keyWidth="10.0%p" />
+ <include
+ latin:keyboardLayout="@xml/rowkeys_khmer4" />
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <Spacer />
+ </case>
+ <default>
+ <include
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
+ </default>
+ </switch>
+ </Row>
+ <include
+ latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/res/xml-sw600dp/rows_lao.xml b/java/res/xml-sw600dp/rows_lao.xml
index cfe8db98e..446d9bd5a 100644
--- a/java/res/xml-sw600dp/rows_lao.xml
+++ b/java/res/xml-sw600dp/rows_lao.xml
@@ -55,8 +55,17 @@
latin:keyWidth="10.0%p" />
<include
latin:keyboardLayout="@xml/rowkeys_lao4" />
- <include
- latin:keyboardLayout="@xml/keys_exclamation_question" />
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <Spacer />
+ </case>
+ <default>
+ <include
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
+ </default>
+ </switch>
</Row>
<include
latin:keyboardLayout="@xml/row_qwerty4" />
diff --git a/java/res/xml-sw600dp/rows_thai.xml b/java/res/xml-sw600dp/rows_thai.xml
index cfcaf6815..7738c7f04 100644
--- a/java/res/xml-sw600dp/rows_thai.xml
+++ b/java/res/xml-sw600dp/rows_thai.xml
@@ -59,8 +59,17 @@
latin:keyWidth="10.0%p" />
<include
latin:keyboardLayout="@xml/rowkeys_thai4" />
- <include
- latin:keyboardLayout="@xml/keys_exclamation_question" />
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <Spacer />
+ </case>
+ <default>
+ <include
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
+ </default>
+ </switch>
</Row>
<include
latin:keyboardLayout="@xml/row_qwerty4" />
diff --git a/java/res/xml/kbd_khmer.xml b/java/res/xml/kbd_khmer.xml
new file mode 100644
index 000000000..7a2337a48
--- /dev/null
+++ b/java/res/xml/kbd_khmer.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<Keyboard
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+ latin:rowHeight="20%p"
+ latin:verticalGap="@fraction/key_bottom_gap_5row"
+ latin:keyLetterSize="@fraction/key_letter_ratio_5row"
+ latin:keyShiftedLetterHintRatio="@fraction/key_uppercase_letter_ratio_5row"
+ latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
+>
+ <include
+ latin:keyboardLayout="@xml/rows_khmer" />
+</Keyboard>
diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml
index 6b3dc9a0d..67ed9620d 100644
--- a/java/res/xml/key_styles_common.xml
+++ b/java/res/xml/key_styles_common.xml
@@ -184,4 +184,11 @@
latin:keyLabelFlags="hasPopupHint"
latin:moreKeys="!text/more_keys_for_punctuation"
latin:backgroundType="functional" />
+ <key-style
+ latin:styleName="comKeyStyle"
+ latin:keyLabel="!text/keylabel_for_popular_domain"
+ latin:keyLabelFlags="autoXScale|fontNormal|hasPopupHint|preserveCase"
+ latin:keyOutputText="!text/keylabel_for_popular_domain"
+ latin:moreKeys="!text/more_keys_for_popular_domain"
+ latin:backgroundType="functional" />
</merge>
diff --git a/java/res/xml/key_styles_currency.xml b/java/res/xml/key_styles_currency.xml
index b7677a20d..84c2abc08 100644
--- a/java/res/xml/key_styles_currency.xml
+++ b/java/res/xml/key_styles_currency.xml
@@ -103,6 +103,8 @@
vi: Vietnamese (Dong) -->
<!-- TODO: The currency sign of Turkish Lira was created in 2012 and assigned U+20BA for
its unicode, although there is no font glyph for it as of November 2012. -->
+ <!-- TODO: The currency sign of Armenian Dram was created in 2012 and assigned U+058F for
+ its unicode, although there is no font glyph for it as of September 2013. -->
<case
latin:languageCode="fa|hi|iw|lo|mn|ne|th|uk|vi"
>
diff --git a/java/res/xml/keyboard_layout_set_khmer.xml b/java/res/xml/keyboard_layout_set_khmer.xml
new file mode 100644
index 000000000..181f98b3d
--- /dev/null
+++ b/java/res/xml/keyboard_layout_set_khmer.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<KeyboardLayoutSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_khmer"
+ latin:enableProximityCharsCorrection="true" />
+ <Element
+ latin:elementName="alphabetAutomaticShifted"
+ latin:elementKeyboard="@xml/kbd_khmer"
+ latin:enableProximityCharsCorrection="true" />
+ <!-- On these shifted alphabet layouts the proximity characters correction should be disabled
+ because the letters on these layouts aren't the ones in different case of the above
+ unshifted layouts. -->
+ <Element
+ latin:elementName="alphabetManualShifted"
+ latin:elementKeyboard="@xml/kbd_khmer" />
+ <Element
+ latin:elementName="alphabetShiftLocked"
+ latin:elementKeyboard="@xml/kbd_khmer" />
+ <Element
+ latin:elementName="alphabetShiftLockShifted"
+ latin:elementKeyboard="@xml/kbd_khmer" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardLayoutSet>
diff --git a/java/res/xml/keys_comma_period.xml b/java/res/xml/keys_comma_period.xml
index 7e7c7282e..02b46c23a 100644
--- a/java/res/xml/keys_comma_period.xml
+++ b/java/res/xml/keys_comma_period.xml
@@ -73,6 +73,20 @@
latin:backgroundType="functional"
latin:keyStyle="hasShiftedLetterHintStyle" />
</case>
+ <case
+ latin:languageCode="hy"
+ >
+ <!-- U+0589: "։" ARMENIAN FULL STOP -->
+ <Key
+ latin:keyLabel="&#x0589;"
+ latin:keyLabelFlags="hasPopupHint"
+ latin:backgroundType="functional"
+ latin:moreKeys="!text/more_keys_for_punctuation" />
+ <!-- U+055D: "՝" ARMENIAN COMMA -->
+ <Key
+ latin:keyLabel="&#x055D;"
+ latin:backgroundType="functional" />
+ </case>
<default>
<Key
latin:keyLabel="."
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index 6014646bb..f0e04c220 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -54,6 +54,7 @@
iw: Hebrew/hebrew # "he" is official language code of Hebrew.
ka: Georgian/georgian
(kk: Kazakh/east_slavic) # disabled temporarily. waiting for strnig resources.
+ km: Khmer/khmer
ky: Kyrgyz/east_slavic
lo: Lao/lao
lt: Lithuanian/qwerty
@@ -62,8 +63,8 @@
mn: Mongolian/mongolian
ms: Malay/qwerty
nb: Norwegian Bokmål/nordic
- ne: Nepali Romanized/nepali_romanized
- ne: Nepali Traditional/nepali_traditional
+ ne: Nepali Romanized/nepali_romanized # disabled temporarily
+ ne: Nepali Traditional/nepali_traditional # disabled temporarily
nl: Dutch/qwerty
nl_BE: Dutch Belgium/azerty
pl: Polish/qwerty
@@ -94,464 +95,474 @@
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="com.android.inputmethod.latin.settings.SettingsActivity"
android:isDefault="@bool/im_is_default">
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_en_US"
android:subtypeId="0xc9194f98"
android:imeSubtypeLocale="en_US"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_en_GB"
android:subtypeId="0xb045e755"
android:imeSubtypeLocale="en_GB"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x6f972360"
android:imeSubtypeLocale="af"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x590dde40"
android:imeSubtypeLocale="ar"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x70b0f974"
android:imeSubtypeLocale="az"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x1dc3a859"
android:imeSubtypeLocale="be"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x0ba9c0e8"
android:imeSubtypeLocale="bg"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=bulgarian"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=bulgarian,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_bulgarian_bds"
android:subtypeId="0x5f51ba9a"
android:imeSubtypeLocale="bg"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=bulgarian_bds"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=bulgarian_bds,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xd2e520d5"
android:imeSubtypeLocale="ca"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x2d3d2ed0"
android:imeSubtypeLocale="cs"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x2df4605d"
android:imeSubtypeLocale="da"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x2e2cbe61"
android:imeSubtypeLocale="de"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x0e7802d3"
android:imeSubtypeLocale="el"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=greek"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=greek,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x4090554a"
android:imeSubtypeLocale="eo"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x30a6e00e"
android:imeSubtypeLocale="es"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_es_US"
android:subtypeId="0x84d2efc6"
android:imeSubtypeLocale="es_US"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable,EmojiCapable"
/>
<!--
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x623f9286"
android:imeSubtypeLocale="es_419"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable,EmojiCapable"
/>
-->
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xec2d3955"
android:imeSubtypeLocale="et"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=nordic,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=nordic,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xbe66c254"
android:imeSubtypeLocale="fa"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=farsi"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=farsi,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x31cecda3"
android:imeSubtypeLocale="fi"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x324da12c"
android:imeSubtypeLocale="fr"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xeadbb691"
android:imeSubtypeLocale="fr_CA"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x39753b7f"
android:imeSubtypeLocale="hi"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=hindi"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=hindi,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x35b7526a"
android:imeSubtypeLocale="hr"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x35e198ed"
android:imeSubtypeLocale="hu"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xe39ac3ca"
android:imeSubtypeLocale="hy"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=armenian_phonetic"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=armenian_phonetic,EmojiCapable"
/>
<!-- Java uses the deprecated "in" code instead of the standard "id" code for Indonesian. -->
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x7daea460"
android:imeSubtypeLocale="in"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x7df519e5"
android:imeSubtypeLocale="is"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x37885a0b"
android:imeSubtypeLocale="it"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
<!-- Java uses the deprecated "iw" code instead of the standard "he" code for Hebrew. -->
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x66fb18bd"
android:imeSubtypeLocale="iw"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x6e119e6a"
android:imeSubtypeLocale="ka"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=georgian"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=georgian,EmojiCapable"
/>
<!--
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x2d73d2f6"
android:imeSubtypeLocale="kk"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic,EmojiCapable"
/>
-->
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
+ android:label="@string/subtype_generic"
+ android:subtypeId="0x1365683a"
+ android:imeSubtypeLocale="km"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=khmer,EmojiCapable"
+ />
+ <!-- android:subtypeId="Need this for km" -->
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x2e391c04"
android:imeSubtypeLocale="ky"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x8315772c"
android:imeSubtypeLocale="lo"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=lao"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=lao,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x8321bb43"
android:imeSubtypeLocale="lt"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x833dea45"
android:imeSubtypeLocale="lv"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xaf50ab7c"
android:imeSubtypeLocale="mk"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=south_slavic"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=south_slavic,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xcdcfc3ab"
android:imeSubtypeLocale="mn"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=mongolian"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=mongolian,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x84c87c61"
android:imeSubtypeLocale="ms"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x3f12ee14"
android:imeSubtypeLocale="nb"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <!--
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xd80a4cee"
android:imeSubtypeLocale="ne"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=nepali_romanized"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=nepali_romanized,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_nepali_traditional"
android:subtypeId="0x5fafea88"
android:imeSubtypeLocale="ne"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=nepali_traditional"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=nepali_traditional,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ -->
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x3f9fd91e"
android:imeSubtypeLocale="nl"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x500ca92c"
android:imeSubtypeLocale="nl_BE"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=azerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=azerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x43098a5c"
android:imeSubtypeLocale="pl"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xcafff4a6"
android:imeSubtypeLocale="pt_BR"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xe2fffc5a"
android:imeSubtypeLocale="pt_PT"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x8d185978"
android:imeSubtypeLocale="ro"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x763a8752"
android:imeSubtypeLocale="ru"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x8e94d413"
android:imeSubtypeLocale="sk"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x8ea2eb94"
android:imeSubtypeLocale="sl"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x77c5196e"
android:imeSubtypeLocale="sr"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="SupportTouchPositionCorrection,EmojiCapable"
/>
<!-- TODO: Uncomment once we can handle IETF language tag with script name specified.
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_serbian_cyrillic"
android:subtypeId="0xXXXXXXXX"
android:imeSubtypeLocale="sr"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_serbian_latin"
android:subtypeId="0xXXXXXXXX"
android:imeSubtypeLocale="sr-Latn"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
-->
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x48b4ff43"
android:imeSubtypeLocale="sv"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x8f3dee1f"
android:imeSubtypeLocale="sw"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x1f94d5d4"
android:imeSubtypeLocale="th"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=thai"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=thai,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xf08285ef"
android:imeSubtypeLocale="tl"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=spanish,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x4a3179de"
android:imeSubtypeLocale="tr"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
+ android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x3e84492c"
android:imeSubtypeLocale="uk"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=east_slavic,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x93972eee"
android:imeSubtypeLocale="vi"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x9b13ab76"
android:imeSubtypeLocale="zu"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EmojiCapable"
/>
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_no_language_qwerty"
android:subtypeId="0xa239ebad"
android:imeSubtypeLocale="zz"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EnabledWhenDefaultIsNotAsciiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EnabledWhenDefaultIsNotAsciiCapable,EmojiCapable"
/>
<!-- Emoji subtype has to be an addtional subtype added at boot time because ICS doesn't
support Emoji. -->
<!--
- <subtype android:icon="@drawable/ic_subtype_keyboard"
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_emoji"
android:subtypeId="0xc14d88b2"
android:imeSubtypeLocale="zz"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=emoji"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=emoji,EmojiCapable"
/>
-->
</input-method>
diff --git a/java/res/xml/row_pcqwerty5.xml b/java/res/xml/row_pcqwerty5.xml
index 0e618059e..4ec908ba1 100644
--- a/java/res/xml/row_pcqwerty5.xml
+++ b/java/res/xml/row_pcqwerty5.xml
@@ -51,13 +51,13 @@
latin:keyWidth="11.538%p" />
<Key
latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="42.310%p" />
+ latin:keyWidth="38.464%p" />
</case>
<!-- languageSwitchKeyEnabled="false" -->
<default>
<Key
latin:keyStyle="spaceKeyStyle"
- latin:keyWidth="53.848%p" />
+ latin:keyWidth="50.002%p" />
</default>
</switch>
<Key
@@ -71,9 +71,9 @@
</case>
<!-- keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted" -->
<default>
- <include
- latin:keyboardLayout="@xml/key_symbols_period"
- latin:backgroundType="functional" />
+ <Key
+ latin:keyStyle="emojiKeyStyle"
+ latin:keyWidth="fillRight" />
</default>
</switch>
</Row>
diff --git a/java/res/xml/row_qwerty4.xml b/java/res/xml/row_qwerty4.xml
index 340beb99b..578bc1234 100644
--- a/java/res/xml/row_qwerty4.xml
+++ b/java/res/xml/row_qwerty4.xml
@@ -49,6 +49,14 @@
<include
latin:keyboardLayout="@xml/key_nepali_traditional_period" />
</case>
+ <case
+ latin:languageCode="hy"
+ >
+ <!-- U+0589: "։" ARMENIAN FULL STOP -->
+ <Key
+ latin:keyLabel="&#x0589;"
+ latin:keyStyle="punctuationKeyStyle" />
+ </case>
<default>
<Key
latin:keyStyle="punctuationKeyStyle" />
diff --git a/java/res/xml/rowkeys_khmer1.xml b/java/res/xml/rowkeys_khmer1.xml
new file mode 100644
index 000000000..25da66400
--- /dev/null
+++ b/java/res/xml/rowkeys_khmer1.xml
@@ -0,0 +1,194 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+200D: ZERO WIDTH JOINER -->
+ <Key
+ latin:keyLabel="!"
+ latin:moreKeys="!icon/zwj_key|&#x200D;" />
+ <!-- U+17D7: "ៗ" KHMER SIGN LEK TOO
+ U+200C: ZERO WIDTH NON-JOINER -->
+ <Key
+ latin:keyLabel="&#x17D7;"
+ latin:moreKeys="!icon/zwnj_key|&#x200C;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17D1: "៑" KHMER SIGN VIRIAM -->
+ <Key
+ latin:keyLabel="&quot;"
+ latin:keyHintLabel="&#x17D1;"
+ latin:moreKeys="&#x17D1;" />
+ <!-- U+17DB: "៛" KHMER CURRENCY SYMBOL RIEL
+ U+20AC: "€" EURO SIGN -->
+ <Key
+ latin:keyLabel="&#x17DB;"
+ latin:keyHintLabel="$"
+ latin:moreKeys="$,&#x20AC;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17D6: "៖" KHMER SIGN CAMNUC PII KUUH -->
+ <Key
+ latin:keyLabel="%"
+ latin:keyHintLabel="&#x17D6;"
+ latin:moreKeys="&#x17D6;" />
+ <!-- U+17CD: "៍" KHMER SIGN TOANDAKHIAT
+ U+17D9: "៙" KHMER SIGN PHNAEK MUAN -->
+ <Key
+ latin:keyLabel="&#x17CD;"
+ latin:keyHintLabel="&#x17D9;"
+ latin:moreKeys="&#x17D9;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17D0: "័" KHMER SIGN SAMYOK SANNYA
+ U+17DA: "៚" KHMER SIGN KOOMUUT -->
+ <Key
+ latin:keyLabel="&#x17D0;"
+ latin:keyHintLabel="&#x17DA;"
+ latin:moreKeys="&#x17DA;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17CF: "៏" KHMER SIGN AHSDA -->
+ <Key
+ latin:keyLabel="&#x17CF;"
+ latin:keyHintLabel="*"
+ latin:moreKeys="*"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK -->
+ <Key
+ latin:keyLabel="("
+ latin:keyHintLabel="{"
+ latin:moreKeys="{,&#x00AB;" />
+ <!-- U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -->
+ <Key
+ latin:keyLabel=")"
+ latin:keyHintLabel="}"
+ latin:moreKeys="},&#x00BB;" />
+ <!-- U+17CC: "៌" KHMER SIGN ROBAT
+ U+00D7: "×" MULTIPLICATION SIGN -->
+ <Key
+ latin:keyLabel="&#x17CC;"
+ latin:keyHintLabel="&#x00D7;"
+ latin:moreKeys="&#x00D7;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17CE: "៎" KHMER SIGN KAKABAT -->
+ <Key
+ latin:keyLabel="&#x17CE;"
+ latin:keyLabelFlags="fontNormal" />
+ </case>
+ <default>
+ <!-- U+17E1: "១" KHMER DIGIT ONE
+ U+17F1: "៱" KHMER SYMBOL LEK ATTAK MUOY -->
+ <Key
+ latin:keyLabel="&#x17E1;"
+ latin:keyHintLabel="1"
+ latin:additionalMoreKeys="1"
+ latin:moreKeys="&#x17F1;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E2: "២" KHMER DIGIT TWO
+ U+17F2: "៲" KHMER SYMBOL LEK ATTAK PII -->
+ <Key
+ latin:keyLabel="&#x17E2;"
+ latin:keyHintLabel="2"
+ latin:additionalMoreKeys="2"
+ latin:moreKeys="&#x17F2;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E3: "៣" KHMER DIGIT THREE
+ U+17F3: "៳" KHMER SYMBOL LEK ATTAK BEI -->
+ <Key
+ latin:keyLabel="&#x17E3;"
+ latin:keyHintLabel="3"
+ latin:additionalMoreKeys="3"
+ latin:moreKeys="&#x17F3;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E4: "៤" KHMER DIGIT FOUR
+ U+17F4: "៴" KHMER SYMBOL LEK ATTAK BUON -->
+ <Key
+ latin:keyLabel="&#x17E4;"
+ latin:keyHintLabel="4"
+ latin:additionalMoreKeys="4"
+ latin:moreKeys="&#x17F4;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E5: "៥" KHMER DIGIT FIVE
+ U+17F5: "៵" KHMER SYMBOL LEK ATTAK PRAM -->
+ <Key
+ latin:keyLabel="&#x17E5;"
+ latin:keyHintLabel="5"
+ latin:additionalMoreKeys="5"
+ latin:moreKeys="&#x17F5;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E6: "៦" KHMER DIGIT SIX
+ U+17F6: "៶" KHMER SYMBOL LEK ATTAK PRAM-MUOY -->
+ <Key
+ latin:keyLabel="&#x17E6;"
+ latin:keyHintLabel="6"
+ latin:additionalMoreKeys="6"
+ latin:moreKeys="&#x17F6;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E7: "៧" KHMER DIGIT SEVEN
+ U+17F7: "៷" KHMER SYMBOL LEK ATTAK PRAM-PII -->
+ <Key
+ latin:keyLabel="&#x17E7;"
+ latin:keyHintLabel="7"
+ latin:additionalMoreKeys="7"
+ latin:moreKeys="&#x17F7;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E8: "៨" KHMER DIGIT EIGHT
+ U+17F8: "៸" KHMER SYMBOL LEK ATTAK PRAM-BEI -->
+ <Key
+ latin:keyLabel="&#x17E8;"
+ latin:keyHintLabel="8"
+ latin:additionalMoreKeys="8"
+ latin:moreKeys="&#x17F8;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E9: "៩" KHMER DIGIT NINE
+ U+17F9: "៹" KHMER SYMBOL LEK ATTAK PRAM-BUON -->
+ <Key
+ latin:keyLabel="&#x17E9;"
+ latin:keyHintLabel="9"
+ latin:additionalMoreKeys="9"
+ latin:moreKeys="&#x17F9;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17E0: "០" KHMER DIGIT ZERO
+ U+17F0: "៰" KHMER SYMBOL LEK ATTAK SON -->
+ <Key
+ latin:keyLabel="&#x17E0;"
+ latin:keyHintLabel="0"
+ latin:additionalMoreKeys="0"
+ latin:moreKeys="&#x17F0;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17A5: "ឥ" KHMER INDEPENDENT VOWEL QI
+ U+17A6: "ឦ" KHMER INDEPENDENT VOWEL QII -->
+ <Key
+ latin:keyLabel="&#x17A5;"
+ latin:keyHintLabel="&#x17A6;"
+ latin:moreKeys=",&#x17A6;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17B2: "ឲ" KHMER INDEPENDENT VOWEL QOO TYPE TWO
+ U+17B1: "ឱ" KHMER INDEPENDENT VOWEL QOO TYPE ONE -->
+ <Key
+ latin:keyLabel="&#x17B2;"
+ latin:keyHintLabel="&#x17B1;"
+ latin:moreKeys="&#x17B1;"
+ latin:keyLabelFlags="fontNormal" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_khmer2.xml b/java/res/xml/rowkeys_khmer2.xml
new file mode 100644
index 000000000..cba2d3b90
--- /dev/null
+++ b/java/res/xml/rowkeys_khmer2.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+1788: "ឈ" KHMER LETTER CHO
+ U+17DC: "ៜ" KHMER SIGN AVAKRAHASANYA -->
+ <Key
+ latin:keyLabel="&#x1788;"
+ latin:keyHintLabel="&#x17DC;"
+ latin:moreKeys="&#x17DC;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17BA: "ឺ" KHMER VOWEL SIGN YY
+ U+17DD: "៝" KHMER SIGN ATTHACAN -->
+ <Key
+ latin:keyLabel="&#x17BA;"
+ latin:keyHintLabel="&#x17DD;"
+ latin:moreKeys="&#x17DD;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C2: "ែ" KHMER VOWEL SIGN AE -->
+ <Key
+ latin:keyLabel="&#x17C2;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17AC: "ឬ" KHMER INDEPENDENT VOWEL RYY
+ U+17AB: "ឫ" KHMER INDEPENDENT VOWEL RY -->
+ <Key
+ latin:keyLabel="&#x17AC;"
+ latin:keyHintLabel="&#x17AB;"
+ latin:moreKeys="&#x17AB;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1791: "ទ" KHMER LETTER TO -->
+ <Key
+ latin:keyLabel="&#x1791;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17BD: "ួ" KHMER VOWEL SIGN UA -->
+ <Key
+ latin:keyLabel="&#x17BD;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17BC: "ូ" KHMER VOWEL SIGN UU -->
+ <Key
+ latin:keyLabel="&#x17BC;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17B8: "ី" KHMER VOWEL SIGN II -->
+ <Key
+ latin:keyLabel="&#x17B8;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C5: "ៅ" KHMER VOWEL SIGN AU -->
+ <Key
+ latin:keyLabel="&#x17C5;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1797: "ភ" KHMER LETTER PHO -->
+ <Key
+ latin:keyLabel="&#x1797;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17BF: "ឿ" KHMER VOWEL SIGN YA -->
+ <Key
+ latin:keyLabel="&#x17BF;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17B0: "ឰ" KHMER INDEPENDENT VOWEL QAI -->
+ <Key
+ latin:keyLabel="&#x17B0;"
+ latin:keyLabelFlags="fontNormal" />
+ </case>
+ <default>
+ <!-- U+1786: "ឆ" KHMER LETTER CHA -->
+ <Key
+ latin:keyLabel="&#x1786;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17B9: "ឹ" KHMER VOWEL SIGN Y -->
+ <Key
+ latin:keyLabel="&#x17B9;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C1: "េ" KHMER VOWEL SIGN E -->
+ <Key
+ latin:keyLabel="&#x17C1;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+179A: "រ" KHMER LETTER RO -->
+ <Key
+ latin:keyLabel="&#x179A;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+178F: "ត" KHMER LETTER TA -->
+ <Key
+ latin:keyLabel="&#x178F;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1799: "យ" KHMER LETTER YO -->
+ <Key
+ latin:keyLabel="&#x1799;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17BB: "ុ" KHMER VOWEL SIGN U -->
+ <Key
+ latin:keyLabel="&#x17BB;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17B7: "ិ" KHMER VOWEL SIGN I -->
+ <Key
+ latin:keyLabel="&#x17B7;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C4: "ោ" KHMER VOWEL SIGN OO -->
+ <Key
+ latin:keyLabel="&#x17C4;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1795: "ផ" KHMER LETTER PHA -->
+ <Key
+ latin:keyLabel="&#x1795;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C0: "ៀ" KHMER VOWEL SIGN IE -->
+ <Key
+ latin:keyLabel="&#x17C0;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17AA: "ឪ" KHMER INDEPENDENT VOWEL QUUV
+ U+17A7: "ឧ" KHMER INDEPENDENT VOWEL QU
+ U+17B1: "ឱ" KHMER INDEPENDENT VOWEL QOO TYPE ONE
+ U+17B3: "ឳ" KHMER INDEPENDENT VOWEL QAU
+ U+17A9: "ឩ" KHMER INDEPENDENT VOWEL QUU
+ U+17A8: "ឨ" KHMER INDEPENDENT VOWEL QUK -->
+ <Key
+ latin:keyLabel="&#x17AA;"
+ latin:keyHintLabel="&#x17A7;"
+ latin:moreKeys="&#x17A7;,&#x17B1;,&#x17B3;,&#x17A9;,&#x17A8;"
+ latin:keyLabelFlags="fontNormal" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_khmer3.xml b/java/res/xml/rowkeys_khmer3.xml
new file mode 100644
index 000000000..ff6c9ca51
--- /dev/null
+++ b/java/res/xml/rowkeys_khmer3.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+17B6/U+17C6: "ាំ" KHMER VOWEL SIGN AA/KHMER SIGN NIKAHIT -->
+ <Key
+ latin:keyLabel="&#x17B6;&#x17C6;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+17C3: "ៃ" KHMER VOWEL SIGN AI -->
+ <Key
+ latin:keyLabel="&#x17C3;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+178C: "ឌ" KHMER LETTER DO -->
+ <Key
+ latin:keyLabel="&#x178C;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1792: "ធ" KHMER LETTER THO -->
+ <Key
+ latin:keyLabel="&#x1792;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17A2: "អ" KHMER LETTER QA -->
+ <Key
+ latin:keyLabel="&#x17A2;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C7: "ះ" KHMER SIGN REAHMUK
+ U+17C8: "ៈ" KHMER SIGN YUUKALEAPINTU;-->
+ <Key
+ latin:keyLabel="&#x17C7;"
+ latin:keyHintLabel="&#x17C8;"
+ latin:moreKeys="&#x17C8;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1789: "ញ" KHMER LETTER NYO -->
+ <Key
+ latin:keyLabel="&#x1789;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1782: "គ" KHMER LETTER KO
+ U+179D: "ឝ" KHMER LETTER SHA -->
+ <Key
+ latin:keyLabel="&#x1782;"
+ latin:keyHintLabel="&#x179D;"
+ latin:moreKeys="&#x179D;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17A1: "ឡ" KHMER LETTER LA -->
+ <Key
+ latin:keyLabel="&#x17A1;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C4/U+17C7: "ោះ" KHMER VOWEL SIGN OO/KHMER SIGN REAHMUK -->
+ <Key
+ latin:keyLabel="&#x17C4;&#x17C7;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C9: "៉" KHMER SIGN MUUSIKATOAN -->
+ <Key
+ latin:keyLabel="&#x17C9;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17AF: "ឯ" KHMER INDEPENDENT VOWEL QE -->
+ <Key
+ latin:keyLabel="&#x17AF;"
+ latin:keyLabelFlags="fontNormal" />
+ </case>
+ <default>
+ <!-- U+17B6: "ា" KHMER VOWEL SIGN AA -->
+ <Key
+ latin:keyLabel="&#x17B6;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+179F: "ស" KHMER LETTER SA -->
+ <Key
+ latin:keyLabel="&#x179F;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+178A: "ដ" KHMER LETTER DA -->
+ <Key
+ latin:keyLabel="&#x178A;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1790: "ថ" KHMER LETTER THA -->
+ <Key
+ latin:keyLabel="&#x1790;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1784: "ង" KHMER LETTER NGO -->
+ <Key
+ latin:keyLabel="&#x1784;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17A0: "ហ" KHMER LETTER HA -->
+ <Key
+ latin:keyLabel="&#x17A0;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17D2: "្" KHMER SIGN COENG -->
+ <Key
+ latin:keyLabel="&#x17D2;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1780: "ក" KHMER LETTER KA -->
+ <Key
+ latin:keyLabel="&#x1780;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+179B: "ល" KHMER LETTER LO -->
+ <Key
+ latin:keyLabel="&#x179B;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17BE: "ើ" KHMER VOWEL SIGN OE -->
+ <Key
+ latin:keyLabel="&#x17BE;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17CB: "់" KHMER SIGN BANTOC -->
+ <Key
+ latin:keyLabel="&#x17CB;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17AE: "ឮ" KHMER INDEPENDENT VOWEL LYY
+ U+17AD: "ឭ" KHMER INDEPENDENT VOWEL LY
+ U+17B0: "ឰ" KHMER INDEPENDENT VOWEL QAI -->
+ <Key
+ latin:keyLabel="&#x17AE;"
+ latin:keyHintLabel="&#x17AD;"
+ latin:moreKeys="&#x17AD;,&#x17B0;"
+ latin:keyLabelFlags="fontNormal" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rowkeys_khmer4.xml b/java/res/xml/rowkeys_khmer4.xml
new file mode 100644
index 000000000..fe6c59125
--- /dev/null
+++ b/java/res/xml/rowkeys_khmer4.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLocked|alphabetShiftLockShifted"
+ >
+ <!-- U+178D: "ឍ" KHMER LETTER TTHO -->
+ <Key
+ latin:keyLabel="&#x178D;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1783: "ឃ" KHMER LETTER KHO -->
+ <Key
+ latin:keyLabel="&#x1783;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1787: "ជ" KHMER LETTER CO -->
+ <Key
+ latin:keyLabel="&#x1787;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C1/U+17C7: "េះ" KHMER VOWEL SIGN E/KHMER SIGN REAHMUK -->
+ <Key
+ latin:keyLabel="&#x17C1;&#x17C7;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1796: "ព" KHMER LETTER PO
+ U+179E: "ឞ" KHMER LETTER SSO -->
+ <Key
+ latin:keyLabel="&#x1796;"
+ latin:keyHintLabel="&#x179E;"
+ latin:moreKeys="&#x179E;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+178E: "ណ" KHMER LETTER NNO -->
+ <Key
+ latin:keyLabel="&#x178E;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17C6: "ំ" KHMER SIGN NIKAHIT -->
+ <Key
+ latin:keyLabel="&#x17C6;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17BB/U+17C7: "ុះ" KHMER VOWEL SIGN U/KHMER SIGN REAHMUK -->
+ <Key
+ latin:keyLabel="&#x17BB;&#x17C7;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+17D5: "៕" KHMER SIGN BARIYOOSAN -->
+ <Key
+ latin:keyLabel="&#x17D5;"
+ latin:keyLabelFlags="fontNormal" />
+ <Key
+ latin:keyLabel="\?" />
+ </case>
+ <default>
+ <!-- U+178B: "ឋ" KHMER LETTER TTHA -->
+ <Key
+ latin:keyLabel="&#x178B;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1781: "ខ" KHMER LETTER KHA -->
+ <Key
+ latin:keyLabel="&#x1781;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1785: "ច" KHMER LETTER CA -->
+ <Key
+ latin:keyLabel="&#x1785;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+179C: "វ" KHMER LETTER VO -->
+ <Key
+ latin:keyLabel="&#x179C;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1794: "ប" KHMER LETTER BA -->
+ <Key
+ latin:keyLabel="&#x1794;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1793: "ន" KHMER LETTER NO -->
+ <Key
+ latin:keyLabel="&#x1793;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+1798: "ម" KHMER LETTER MO -->
+ <Key
+ latin:keyLabel="&#x1798;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17BB/U+17C6: "ុំ" KHMER VOWEL SIGN U/KHMER SIGN NIKAHIT -->
+ <Key
+ latin:keyLabel="&#x17BB;&#x17C6;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+ <!-- U+17D4: "។" KHMER SIGN KHAN -->
+ <Key
+ latin:keyLabel="&#x17D4;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+17CA: "៊" KHMER SIGN TRIISAP -->
+ <Key
+ latin:keyLabel="&#x17CA;"
+ latin:keyLabelFlags="fontNormal" />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml/rows_khmer.xml b/java/res/xml/rows_khmer.xml
new file mode 100644
index 000000000..e3993871b
--- /dev/null
+++ b/java/res/xml/rows_khmer.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <include
+ latin:keyboardLayout="@xml/key_styles_common" />
+ <Row
+ latin:keyWidth="8.3333%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_khmer1" />
+ </Row>
+ <Row
+ latin:keyWidth="8.3333%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_khmer2" />
+ </Row>
+ <Row
+ latin:keyWidth="8.3333%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_khmer3" />
+ </Row>
+ <Row
+ latin:keyWidth="8.3333%p"
+ >
+ <Key
+ latin:keyStyle="shiftKeyStyle" />
+ <include
+ latin:keyboardLayout="@xml/rowkeys_khmer4" />
+ <Key
+ latin:keyStyle="deleteKeyStyle" />
+ </Row>
+ <include
+ latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/src/com/android/inputmethod/compat/ActivityManagerCompatUtils.java b/java/src/com/android/inputmethod/compat/ActivityManagerCompatUtils.java
new file mode 100644
index 000000000..385e3e025
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/ActivityManagerCompatUtils.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.compat;
+
+import android.app.ActivityManager;
+import android.content.Context;
+
+import java.lang.reflect.Method;
+
+public class ActivityManagerCompatUtils {
+ private static final Object LOCK = new Object();
+ private static volatile Boolean sBoolean = null;
+ private static final Method METHOD_isLowRamDevice = CompatUtils.getMethod(
+ ActivityManager.class, "isLowRamDevice");
+
+ private ActivityManagerCompatUtils() {
+ // Do not instantiate this class.
+ }
+
+ public static boolean isLowRamDevice(Context context) {
+ if (sBoolean == null) {
+ synchronized(LOCK) {
+ if (sBoolean == null) {
+ final ActivityManager am =
+ (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ sBoolean = (Boolean)CompatUtils.invoke(am, false, METHOD_isLowRamDevice);
+ }
+ }
+ }
+ return sBoolean;
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/EmojiCategoryPageIndicatorView.java b/java/src/com/android/inputmethod/keyboard/EmojiCategoryPageIndicatorView.java
new file mode 100644
index 000000000..fed134eb9
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/EmojiCategoryPageIndicatorView.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.keyboard;
+
+import com.android.inputmethod.latin.R;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.widget.LinearLayout;
+
+public class EmojiCategoryPageIndicatorView extends LinearLayout {
+ private static final float BOTTOM_MARGIN_RATIO = 0.66f;
+ private final Paint mPaint = new Paint();
+ private int mCategoryPageSize = 0;
+ private int mCurrentCategoryPageId = 0;
+ private float mOffset = 0.0f;
+
+ public EmojiCategoryPageIndicatorView(Context context) {
+ this(context, null /* attrs */);
+ }
+
+ public EmojiCategoryPageIndicatorView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mPaint.setColor(context.getResources().getColor(
+ R.color.emoji_category_page_id_view_foreground));
+ }
+
+ public void setCategoryPageId(int size, int id, float offset) {
+ mCategoryPageSize = size;
+ mCurrentCategoryPageId = id;
+ mOffset = offset;
+ invalidate();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (mCategoryPageSize == 0) {
+ // If the category is not set yet, just clear and return.
+ canvas.drawColor(0);
+ return;
+ }
+ final float height = getHeight();
+ final float width = getWidth();
+ final float unitWidth = width / mCategoryPageSize;
+ final float left = unitWidth * mCurrentCategoryPageId + mOffset * unitWidth;
+ final float top = 0.0f;
+ final float right = left + unitWidth;
+ final float bottom = height * BOTTOM_MARGIN_RATIO;
+ canvas.drawRect(left, top, right, bottom, mPaint);
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java b/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java
index 702ed2075..4e61edac2 100644
--- a/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java
@@ -28,11 +28,13 @@ import android.os.Build;
import android.preference.PreferenceManager;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
+import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
import android.view.LayoutInflater;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
@@ -76,10 +78,12 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
private final int mEmojiFunctionalKeyBackgroundId;
private final KeyboardLayoutSet mLayoutSet;
private final ColorStateList mTabLabelColor;
+ private final DeleteKeyOnTouchListener mDeleteKeyOnTouchListener;
private EmojiKeyboardAdapter mEmojiKeyboardAdapter;
private TabHost mTabHost;
private ViewPager mEmojiPager;
+ private EmojiCategoryPageIndicatorView mEmojiCategoryPageIndicatorView;
private KeyboardActionListener mKeyboardActionListener = KeyboardActionListener.EMPTY_LISTENER;
@@ -197,6 +201,21 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
return mCurrentCategoryId;
}
+ public int getCurrentCategoryPageSize() {
+ return getCategoryPageSize(mCurrentCategoryId);
+ }
+
+ public int getCategoryPageSize(int categoryId) {
+ for (final CategoryProperties prop : mShownCategories) {
+ if (prop.mCategoryId == categoryId) {
+ return prop.mPageCount;
+ }
+ }
+ Log.w(TAG, "Invalid category id: " + categoryId);
+ // Should not reach here.
+ return 0;
+ }
+
public void setCurrentCategoryId(int categoryId) {
mCurrentCategoryId = categoryId;
}
@@ -205,6 +224,10 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
mCurrentCategoryPageId = id;
}
+ public int getCurrentCategoryPageId() {
+ return mCurrentCategoryPageId;
+ }
+
public void saveLastTypedCategoryPage() {
Settings.writeEmojiCategoryLastTypedId(
mPrefs, mCurrentCategoryId, mCurrentCategoryPageId);
@@ -382,6 +405,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
mLayoutSet = builder.build();
mEmojiCategory = new EmojiCategory(PreferenceManager.getDefaultSharedPreferences(context),
context.getResources(), builder.build());
+ mDeleteKeyOnTouchListener = new DeleteKeyOnTouchListener(context);
}
@Override
@@ -435,18 +459,20 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
mEmojiPager.setOffscreenPageLimit(0);
final Resources res = getResources();
final EmojiLayoutParams emojiLp = new EmojiLayoutParams(res);
- emojiLp.setPagerProps(mEmojiPager);
+ emojiLp.setPagerProperties(mEmojiPager);
+
+ mEmojiCategoryPageIndicatorView =
+ (EmojiCategoryPageIndicatorView)findViewById(R.id.emoji_category_page_id_view);
+ emojiLp.setCategoryPageIdViewProperties(mEmojiCategoryPageIndicatorView);
setCurrentCategoryId(mEmojiCategory.getCurrentCategoryId(), true /* force */);
final LinearLayout actionBar = (LinearLayout)findViewById(R.id.emoji_action_bar);
- emojiLp.setActionBarProps(actionBar);
+ emojiLp.setActionBarProperties(actionBar);
- // TODO: Implement auto repeat, using View.OnTouchListener?
final ImageView deleteKey = (ImageView)findViewById(R.id.emoji_keyboard_delete);
- deleteKey.setBackgroundResource(mEmojiFunctionalKeyBackgroundId);
deleteKey.setTag(Constants.CODE_DELETE);
- deleteKey.setOnClickListener(this);
+ deleteKey.setOnTouchListener(mDeleteKeyOnTouchListener);
final ImageView alphabetKey = (ImageView)findViewById(R.id.emoji_keyboard_alphabet);
alphabetKey.setBackgroundResource(mEmojiFunctionalKeyBackgroundId);
alphabetKey.setTag(Constants.CODE_SWITCH_ALPHA_SYMBOL);
@@ -455,7 +481,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
spaceKey.setBackgroundResource(mKeyBackgroundId);
spaceKey.setTag(Constants.CODE_SPACE);
spaceKey.setOnClickListener(this);
- emojiLp.setKeyProps(spaceKey);
+ emojiLp.setKeyProperties(spaceKey);
final ImageView sendKey = (ImageView)findViewById(R.id.emoji_keyboard_send);
sendKey.setBackgroundResource(mEmojiFunctionalKeyBackgroundId);
sendKey.setTag(Constants.CODE_ENTER);
@@ -466,6 +492,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
public void onTabChanged(final String tabId) {
final int categoryId = mEmojiCategory.getCategoryId(tabId);
setCurrentCategoryId(categoryId, false /* force */);
+ updateEmojiCategoryPageIdView();
}
@@ -475,6 +502,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(position);
setCurrentCategoryId(newPos.first /* categoryId */, false /* force */);
mEmojiCategory.setCurrentCategoryPageId(newPos.second /* categoryPageId */);
+ updateEmojiCategoryPageIdView();
}
@Override
@@ -485,7 +513,23 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
@Override
public void onPageScrolled(final int position, final float positionOffset,
final int positionOffsetPixels) {
- // Ignore this message. Only want the actual page selected.
+ final Pair<Integer, Integer> newPos =
+ mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(position);
+ final int newCategoryId = newPos.first;
+ final int newCategorySize = mEmojiCategory.getCategoryPageSize(newCategoryId);
+ final int currentCategoryId = mEmojiCategory.getCurrentCategoryId();
+ final int currentCategoryPageId = mEmojiCategory.getCurrentCategoryPageId();
+ final int currentCategorySize = mEmojiCategory.getCurrentCategoryPageSize();
+ if (newCategoryId == currentCategoryId) {
+ mEmojiCategoryPageIndicatorView.setCategoryPageId(
+ newCategorySize, newPos.second, positionOffset);
+ } else if (newCategoryId > currentCategoryId) {
+ mEmojiCategoryPageIndicatorView.setCategoryPageId(
+ currentCategorySize, currentCategoryPageId, positionOffset);
+ } else if (newCategoryId < currentCategoryId) {
+ mEmojiCategoryPageIndicatorView.setCategoryPageId(
+ currentCategorySize, currentCategoryPageId, positionOffset - 1);
+ }
}
@Override
@@ -505,10 +549,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
@Override
public void onKeyClick(final Key key) {
- // TODO: Save emoticons to recents
- if (mEmojiCategory.getCurrentCategoryId() != CATEGORY_ID_EMOTICONS) {
- mEmojiKeyboardAdapter.addRecentKey(key);
- }
+ mEmojiKeyboardAdapter.addRecentKey(key);
mEmojiCategory.saveLastTypedCategoryPage();
final int code = key.getCode();
if (code == Constants.CODE_OUTPUT_TEXT) {
@@ -524,6 +565,16 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
public void setKeyboardActionListener(final KeyboardActionListener listener) {
mKeyboardActionListener = listener;
+ mDeleteKeyOnTouchListener.setKeyboardActionListener(mKeyboardActionListener);
+ }
+
+ private void updateEmojiCategoryPageIdView() {
+ if (mEmojiCategoryPageIndicatorView == null) {
+ return;
+ }
+ mEmojiCategoryPageIndicatorView.setCategoryPageId(
+ mEmojiCategory.getCurrentCategoryPageSize(),
+ mEmojiCategory.getCurrentCategoryPageId(), 0.0f /* offset */);
}
private void setCurrentCategoryId(final int categoryId, final boolean force) {
@@ -624,4 +675,92 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
container.removeView(keyboardView);
}
}
+
+ // TODO: Do the same things done in PointerTracker
+ private static class DeleteKeyOnTouchListener implements OnTouchListener {
+ private static final long MAX_REPEAT_COUNT_TIME = 30 * DateUtils.SECOND_IN_MILLIS;
+ private final int mDeleteKeyPressedBackgroundColor;
+ private final long mKeyRepeatStartTimeout;
+ private final long mKeyRepeatInterval;
+
+ public DeleteKeyOnTouchListener(Context context) {
+ final Resources res = context.getResources();
+ mDeleteKeyPressedBackgroundColor =
+ res.getColor(R.color.emoji_key_pressed_background_color);
+ mKeyRepeatStartTimeout = res.getInteger(R.integer.config_key_repeat_start_timeout);
+ mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval);
+ }
+
+ private KeyboardActionListener mKeyboardActionListener =
+ KeyboardActionListener.EMPTY_LISTENER;
+ private DummyRepeatKeyRepeatTimer mTimer;
+
+ private synchronized void startRepeat() {
+ if (mTimer != null) {
+ abortRepeat();
+ }
+ mTimer = new DummyRepeatKeyRepeatTimer();
+ mTimer.start();
+ }
+
+ private synchronized void abortRepeat() {
+ mTimer.abort();
+ mTimer = null;
+ }
+
+ // TODO: Remove
+ // This function is mimicking the repeat code in PointerTracker.
+ // Specifically referring to PointerTracker#startRepeatKey and PointerTracker#onKeyRepeat.
+ private class DummyRepeatKeyRepeatTimer extends Thread {
+ public boolean mAborted = false;
+
+ @Override
+ public void run() {
+ int timeCount = 0;
+ while (timeCount < MAX_REPEAT_COUNT_TIME && !mAborted) {
+ if (timeCount > mKeyRepeatStartTimeout) {
+ pressDelete();
+ }
+ timeCount += mKeyRepeatInterval;
+ try {
+ Thread.sleep(mKeyRepeatInterval);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ public void abort() {
+ mAborted = true;
+ }
+ }
+
+ public void pressDelete() {
+ mKeyboardActionListener.onPressKey(
+ Constants.CODE_DELETE, 0 /* repeatCount */, true /* isSinglePointer */);
+ mKeyboardActionListener.onCodeInput(
+ Constants.CODE_DELETE, NOT_A_COORDINATE, NOT_A_COORDINATE);
+ mKeyboardActionListener.onReleaseKey(
+ Constants.CODE_DELETE, false /* withSliding */);
+ }
+
+ public void setKeyboardActionListener(KeyboardActionListener listener) {
+ mKeyboardActionListener = listener;
+ }
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ switch(event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ v.setBackgroundColor(mDeleteKeyPressedBackgroundColor);
+ pressDelete();
+ startRepeat();
+ return true;
+ case MotionEvent.ACTION_UP:
+ v.setBackgroundColor(0);
+ abortRepeat();
+ return true;
+ }
+ return false;
+ }
+ }
}
diff --git a/java/src/com/android/inputmethod/keyboard/EmojiLayoutParams.java b/java/src/com/android/inputmethod/keyboard/EmojiLayoutParams.java
index 5570d594d..267fad5cd 100644
--- a/java/src/com/android/inputmethod/keyboard/EmojiLayoutParams.java
+++ b/java/src/com/android/inputmethod/keyboard/EmojiLayoutParams.java
@@ -30,6 +30,7 @@ public class EmojiLayoutParams {
public final int mEmojiPagerHeight;
private final int mEmojiPagerBottomMargin;
public final int mEmojiKeyboardHeight;
+ private final int mEmojiCategoryPageIdViewHeight;
public final int mEmojiActionBarHeight;
public final int mKeyVerticalGap;
private final int mKeyHorizontalGap;
@@ -47,23 +48,32 @@ public class EmojiLayoutParams {
(int) defaultKeyboardHeight, (int) defaultKeyboardHeight);
mKeyHorizontalGap = (int) (res.getFraction(R.fraction.key_horizontal_gap_ics,
defaultKeyboardWidth, defaultKeyboardWidth));
+ mEmojiCategoryPageIdViewHeight =
+ (int) (res.getDimension(R.dimen.emoji_category_page_id_height));
final int baseheight = defaultKeyboardHeight - mBottomPadding - mTopPadding
+ mKeyVerticalGap;
mEmojiActionBarHeight = ((int) baseheight) / DEFAULT_KEYBOARD_ROWS
- (mKeyVerticalGap - mBottomPadding) / 2;
- mEmojiPagerHeight = defaultKeyboardHeight - mEmojiActionBarHeight;
+ mEmojiPagerHeight = defaultKeyboardHeight - mEmojiActionBarHeight
+ - mEmojiCategoryPageIdViewHeight;
mEmojiPagerBottomMargin = mKeyVerticalGap / 2;
mEmojiKeyboardHeight = mEmojiPagerHeight - mEmojiPagerBottomMargin - 1;
}
- public void setPagerProps(ViewPager vp) {
+ public void setPagerProperties(ViewPager vp) {
final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) vp.getLayoutParams();
- lp.height = mEmojiPagerHeight - mEmojiPagerBottomMargin;
+ lp.height = mEmojiKeyboardHeight;
lp.bottomMargin = mEmojiPagerBottomMargin;
vp.setLayoutParams(lp);
}
- public void setActionBarProps(LinearLayout ll) {
+ public void setCategoryPageIdViewProperties(LinearLayout ll) {
+ final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) ll.getLayoutParams();
+ lp.height = mEmojiCategoryPageIdViewHeight;
+ ll.setLayoutParams(lp);
+ }
+
+ public void setActionBarProperties(LinearLayout ll) {
final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) ll.getLayoutParams();
lp.height = mEmojiActionBarHeight;
lp.topMargin = 0;
@@ -71,7 +81,7 @@ public class EmojiLayoutParams {
ll.setLayoutParams(lp);
}
- public void setKeyProps(ImageView ib) {
+ public void setKeyProperties(ImageView ib) {
final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) ib.getLayoutParams();
lp.leftMargin = mKeyHorizontalGap / 2;
lp.rightMargin = mKeyHorizontalGap / 2;
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 23f037fbd..bc1383aff 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -155,6 +155,15 @@ public class Keyboard {
return mKeys;
}
+ public Key getKeyFromOutputText(final String outputText) {
+ for (final Key key : getKeys()) {
+ if (outputText.equals(key.getOutputText())) {
+ return key;
+ }
+ }
+ return null;
+ }
+
public Key getKey(final int code) {
if (code == Constants.CODE_UNSPECIFIED) {
return null;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 0ef6802ca..aeb9e67b2 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -26,6 +26,7 @@ import android.graphics.Paint.Align;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Region;
+import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
@@ -445,6 +446,8 @@ public class KeyboardView extends View {
if (hintLabel != null) {
paint.setTextSize(key.selectHintTextSize(params));
paint.setColor(key.selectHintTextColor(params));
+ // TODO: Should add a way to specify type face for hint letters
+ paint.setTypeface(Typeface.DEFAULT_BOLD);
blendAlpha(paint, params.mAnimAlpha);
final float hintX, hintY;
if (key.hasHintLabel()) {
@@ -465,9 +468,13 @@ public class KeyboardView extends View {
paint.setTextAlign(Align.CENTER);
} else { // key.hasHintLetter()
// The hint letter is placed at top-right corner of the key. Used mainly on phone.
+ final float keyNumericHintLabelReferenceCharWidth =
+ TypefaceUtils.getCharWidth(KEY_NUMERIC_HINT_LABEL_REFERENCE_CHAR, paint);
+ final float keyHintLabelStringWidth =
+ TypefaceUtils.getStringWidth(hintLabel, paint);
hintX = keyWidth - mKeyHintLetterPadding
- - TypefaceUtils.getCharWidth(KEY_NUMERIC_HINT_LABEL_REFERENCE_CHAR, paint)
- / 2.0f;
+ - Math.max(keyNumericHintLabelReferenceCharWidth, keyHintLabelStringWidth)
+ / 2.0f;
hintY = -paint.ascent();
paint.setTextAlign(Align.CENTER);
}
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index f8ad43e74..13db47004 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -155,7 +155,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
private final SlidingKeyInputPreview mSlidingKeyInputPreview;
// Key preview
- private static final int PREVIEW_ALPHA = 240;
private final int mKeyPreviewLayoutId;
private final int mKeyPreviewOffset;
private final int mKeyPreviewHeight;
@@ -816,7 +815,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
if (background != null) {
final int hasMoreKeys = (key.getMoreKeys() != null) ? STATE_HAS_MOREKEYS : STATE_NORMAL;
background.setState(KEY_PREVIEW_BACKGROUND_STATE_TABLE[statePosition][hasMoreKeys]);
- background.setAlpha(PREVIEW_ALPHA);
}
ViewLayoutUtils.placeViewAt(
previewText, previewX, previewY, previewWidth, previewHeight);
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index cd127c760..a0316696c 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -245,8 +245,8 @@ public class ProximityInfo {
final int threshold = (int) (defaultWidth * SEARCH_DISTANCE);
final int thresholdSquared = threshold * threshold;
// Round-up so we don't have any pixels outside the grid
- final int fullGridWidth = mGridWidth * mCellWidth;
- final int fullGridHeight = mGridHeight * mCellHeight;
+ final int lastPixelXCoordinate = mGridWidth * mCellWidth - 1;
+ final int lastPixelYCoordinate = mGridHeight * mCellHeight - 1;
// For large layouts, 'neighborsFlatBuffer' is about 80k of memory: gridSize is usually 512,
// keycount is about 40 and a pointer to a Key is 4 bytes. This contains, for each cell,
@@ -329,22 +329,20 @@ y |---+---+---+---+-v-+-|-+---+---+---+---+---| | thresholdBase and get
final int yMiddleOfTopCell = topPixelWithinThreshold - yDeltaToGrid + halfCellHeight;
final int yStart = Math.max(halfCellHeight,
yMiddleOfTopCell + (yDeltaToGrid <= halfCellHeight ? 0 : mCellHeight));
- final int yEnd = Math.min(fullGridHeight, keyY + key.getHeight() + threshold);
+ final int yEnd = Math.min(lastPixelYCoordinate, keyY + key.getHeight() + threshold);
final int leftPixelWithinThreshold = keyX - threshold;
final int xDeltaToGrid = leftPixelWithinThreshold % mCellWidth;
final int xMiddleOfLeftCell = leftPixelWithinThreshold - xDeltaToGrid + halfCellWidth;
final int xStart = Math.max(halfCellWidth,
xMiddleOfLeftCell + (xDeltaToGrid <= halfCellWidth ? 0 : mCellWidth));
- final int xEnd = Math.min(fullGridWidth, keyX + key.getWidth() + threshold);
+ final int xEnd = Math.min(lastPixelXCoordinate, keyX + key.getWidth() + threshold);
int baseIndexOfCurrentRow = (yStart / mCellHeight) * mGridWidth + (xStart / mCellWidth);
for (int centerY = yStart; centerY <= yEnd; centerY += mCellHeight) {
int index = baseIndexOfCurrentRow;
for (int centerX = xStart; centerX <= xEnd; centerX += mCellWidth) {
- // TODO: Remove "index < neighborCountPerCell.length" below.
- if (index < neighborCountPerCell.length
- && key.squaredDistanceToEdge(centerX, centerY) < thresholdSquared) {
+ if (key.squaredDistanceToEdge(centerX, centerY) < thresholdSquared) {
neighborsFlatBuffer[index * keyCount + neighborCountPerCell[index]] = key;
++neighborCountPerCell[index];
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java b/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java
index f203eb7d7..0dd71e2ec 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java
@@ -18,25 +18,27 @@ package com.android.inputmethod.keyboard.internal;
import android.content.SharedPreferences;
import android.text.TextUtils;
+import android.util.Log;
import com.android.inputmethod.keyboard.EmojiKeyboardView;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
import java.util.ArrayDeque;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
/**
* This is a Keyboard class where you can add keys dynamically shown in a grid layout
*/
public class DynamicGridKeyboard extends Keyboard {
+ private static final String TAG = DynamicGridKeyboard.class.getSimpleName();
private static final int TEMPLATE_KEY_CODE_0 = 0x30;
private static final int TEMPLATE_KEY_CODE_1 = 0x31;
- // Recent codes are saved as an integer array, so we use comma as a separater.
- private static final String RECENT_KEY_SEPARATOR = Constants.STRING_COMMA;
private final SharedPreferences mPrefs;
private final int mLeftPadding;
@@ -84,6 +86,9 @@ public class DynamicGridKeyboard extends Keyboard {
}
private void addKey(final Key usedKey, final boolean addFirst) {
+ if (usedKey == null) {
+ return;
+ }
synchronized (mGridKeys) {
mCachedGridKeys = null;
final GridKey key = new GridKey(usedKey);
@@ -109,28 +114,45 @@ public class DynamicGridKeyboard extends Keyboard {
}
private void saveRecentKeys() {
- final StringBuilder sb = new StringBuilder();
+ final ArrayList<Object> keys = CollectionUtils.newArrayList();
for (final Key key : mGridKeys) {
- sb.append(key.getCode()).append(RECENT_KEY_SEPARATOR);
+ if (key.getOutputText() != null) {
+ keys.add(key.getOutputText());
+ } else {
+ keys.add(key.getCode());
+ }
}
- Settings.writeEmojiRecentKeys(mPrefs, sb.toString());
+ final String jsonStr = StringUtils.listToJsonStr(keys);
+ Settings.writeEmojiRecentKeys(mPrefs, jsonStr);
}
- public void loadRecentKeys(Collection<DynamicGridKeyboard> keyboards) {
- final String str = Settings.readEmojiRecentKeys(mPrefs);
- for (String s : str.split(RECENT_KEY_SEPARATOR)) {
- if (TextUtils.isEmpty(s)) {
- continue;
- }
- final int code = Integer.valueOf(s);
- for (DynamicGridKeyboard kbd : keyboards) {
+ private static Key getKey(final Collection<DynamicGridKeyboard> keyboards, final Object o) {
+ for (final DynamicGridKeyboard kbd : keyboards) {
+ if (o instanceof Integer) {
+ final int code = (Integer) o;
final Key key = kbd.getKey(code);
if (key != null) {
- addKeyLast(key);
- break;
+ return key;
+ }
+ } else if (o instanceof String) {
+ final String outputText = (String) o;
+ final Key key = kbd.getKeyFromOutputText(outputText);
+ if (key != null) {
+ return key;
}
+ } else {
+ Log.w(TAG, "Invalid object: " + o);
}
}
+ return null;
+ }
+
+ public void loadRecentKeys(Collection<DynamicGridKeyboard> keyboards) {
+ final String str = Settings.readEmojiRecentKeys(mPrefs);
+ final List<Object> keys = StringUtils.jsonStrToList(str);
+ for (final Object o : keys) {
+ addKeyLast(getKey(keyboards, o));
+ }
}
private int getKeyX(final int index) {
@@ -171,7 +193,7 @@ public class DynamicGridKeyboard extends Keyboard {
public void updateCorrdinates(final int x, final int y) {
mCurrentX = x;
mCurrentY = y;
- getHitBox().offsetTo(x, y);
+ getHitBox().set(x, y, x + getWidth(), y + getHeight());
}
@Override
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
index a72595f7c..67553fb75 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
@@ -1769,15 +1769,27 @@ public final class KeyboardTextsSet {
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null,
/* ~52 */
+ // U+058A: "֊" ARMENIAN HYPHEN
+ // U+055C: "՜" ARMENIAN EXCLAMATION MARK
+ // U+055D: "՝" ARMENIAN COMMA
// U+055E: "՞" ARMENIAN QUESTION MARK
- /* 53 */ "!fixedColumnOrder!4,\u055E,!,\\,,?,:,;,@",
+ // U+0559: "ՙ" ARMENIAN MODIFIER LETTER LEFT HALF RING
+ // U+055A: "՚" ARMENIAN APOSTROPHE
+ // U+055B: "՛" ARMENIAN EMPHASIS MARK
+ // U+055F: "՟" ARMENIAN ABBREVIATION MARK
+ /* 53 */ "!fixedColumnOrder!8,!,?,\\,,.,\u058A,\u055C,\u055D,\u055E,:,;,@,\u0559,\u055A,\u055B,\u055F",
/* 54~ */
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- null, null, null, null, null, null, null, null, null,
- /* ~107 */
- /* 108 */ "\u055E,?",
+ null,
+ /* ~99 */
+ // U+055C: "՜" ARMENIAN EXCLAMATION MARK
+ // U+00A1: "¡" INVERTED EXCLAMATION MARK
+ /* 100 */ "\u055C,\u00A1",
+ // U+055E: "՞" ARMENIAN QUESTION MARK
+ // U+00BF: "¿" INVERTED QUESTION MARK
+ /* 101 */ "\u055E,\u00BF",
};
/* Language is: Icelandic */
@@ -2015,6 +2027,25 @@ public final class KeyboardTextsSet {
/* 45 */ "\u0410\u0411\u0412",
};
+ /* Language km: Khmer */
+ private static final String[] LANGUAGE_km = {
+ /* 0~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ /* ~44 */
+ // Label for "switch to alphabetic" key.
+ // U+1780: "ក" KHMER LETTER KA
+ // U+1781: "ខ" KHMER LETTER KHA
+ // U+1782: "គ" KHMER LETTER KO
+ /* 45 */ "\u1780\u1781\u1782",
+ /* 46~ */
+ null, null, null, null,
+ /* ~49 */
+ // U+17DB: "៛" KHMER CURRENCY SYMBOL RIEL
+ /* 50 */ "\u17DB,\u00A2,\u00A3,\u20AC,\u00A5,\u20B1",
+ };
+
/* Language ky: Kirghiz */
private static final String[] LANGUAGE_ky = {
/* 0~ */
@@ -3407,6 +3438,7 @@ public final class KeyboardTextsSet {
"iw", LANGUAGE_iw, /* Hebrew */
"ka", LANGUAGE_ka, /* Georgian */
"kk", LANGUAGE_kk, /* Kazakh */
+ "km", LANGUAGE_km, /* Khmer */
"ky", LANGUAGE_ky, /* Kirghiz */
"lo", LANGUAGE_lo, /* Lao */
"lt", LANGUAGE_lt, /* Lithuanian */
diff --git a/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java b/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java
index 55df263fe..845a9b987 100644
--- a/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java
+++ b/java/src/com/android/inputmethod/latin/AbstractDictionaryWriter.java
@@ -58,7 +58,7 @@ abstract public class AbstractDictionaryWriter extends Dictionary {
final File file = new File(mContext.getFilesDir(), fileName);
final File tempFile = new File(mContext.getFilesDir(), tempFileName);
try {
- final DictEncoder dictEncoder = new Ver3DictEncoder(file);
+ final DictEncoder dictEncoder = new Ver3DictEncoder(tempFile);
writeDictionary(dictEncoder);
tempFile.renameTo(file);
} catch (IOException e) {
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index b49cd80ab..61ccfcfad 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -27,6 +27,7 @@ import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.JniUtils;
import com.android.inputmethod.latin.utils.StringUtils;
+import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
@@ -109,7 +110,7 @@ public final class BinaryDictionary extends Dictionary {
private static native void flushWithGCNative(long dict, String filePath);
private static native void closeNative(long dict);
private static native int getProbabilityNative(long dict, int[] word);
- private static native boolean isValidBigramNative(long dict, int[] word0, int[] word1);
+ private static native int getBigramProbabilityNative(long dict, int[] word0, int[] word1);
private static native int getSuggestionsNative(long dict, long proximityInfo,
long traverseSession, int[] xCoordinates, int[] yCoordinates, int[] times,
int[] pointerIds, int[] inputCodePoints, int inputSize, int commitPoint,
@@ -122,6 +123,8 @@ public final class BinaryDictionary extends Dictionary {
private static native void addBigramWordsNative(long dict, int[] word0, int[] word1,
int probability);
private static native void removeBigramWordsNative(long dict, int[] word0, int[] word1);
+ private static native int calculateProbabilityNative(long dict, int unigramProbability,
+ int bigramProbability);
// TODO: Move native dict into session
private final void loadDictionary(final String path, final long startOffset,
@@ -219,12 +222,12 @@ public final class BinaryDictionary extends Dictionary {
@Override
public boolean isValidWord(final String word) {
- return getFrequency(word) >= 0;
+ return getFrequency(word) != NOT_A_PROBABILITY;
}
@Override
public int getFrequency(final String word) {
- if (word == null) return -1;
+ if (word == null) return NOT_A_PROBABILITY;
int[] codePoints = StringUtils.toCodePointArray(word);
return getProbabilityNative(mNativeDict, codePoints);
}
@@ -232,10 +235,20 @@ public final class BinaryDictionary extends Dictionary {
// TODO: Add a batch process version (isValidBigramMultiple?) to avoid excessive numbers of jni
// calls when checking for changes in an entire dictionary.
public boolean isValidBigram(final String word0, final String word1) {
- if (TextUtils.isEmpty(word0) || TextUtils.isEmpty(word1)) return false;
+ return getBigramProbability(word0, word1) != NOT_A_PROBABILITY;
+ }
+
+ public int getBigramProbability(final String word0, final String word1) {
+ if (TextUtils.isEmpty(word0) || TextUtils.isEmpty(word1)) return NOT_A_PROBABILITY;
final int[] codePoints0 = StringUtils.toCodePointArray(word0);
final int[] codePoints1 = StringUtils.toCodePointArray(word1);
- return isValidBigramNative(mNativeDict, codePoints0, codePoints1);
+ return getBigramProbabilityNative(mNativeDict, codePoints0, codePoints1);
+ }
+
+ private void runGCIfRequired() {
+ if (needsToRunGCNative(mNativeDict)) {
+ flushWithGC();
+ }
}
// Add a unigram entry to binary dictionary in native code.
@@ -243,6 +256,7 @@ public final class BinaryDictionary extends Dictionary {
if (TextUtils.isEmpty(word)) {
return;
}
+ runGCIfRequired();
final int[] codePoints = StringUtils.toCodePointArray(word);
addUnigramWordNative(mNativeDict, codePoints, probability);
}
@@ -252,6 +266,7 @@ public final class BinaryDictionary extends Dictionary {
if (TextUtils.isEmpty(word0) || TextUtils.isEmpty(word1)) {
return;
}
+ runGCIfRequired();
final int[] codePoints0 = StringUtils.toCodePointArray(word0);
final int[] codePoints1 = StringUtils.toCodePointArray(word1);
addBigramWordsNative(mNativeDict, codePoints0, codePoints1, probability);
@@ -262,29 +277,41 @@ public final class BinaryDictionary extends Dictionary {
if (TextUtils.isEmpty(word0) || TextUtils.isEmpty(word1)) {
return;
}
+ runGCIfRequired();
final int[] codePoints0 = StringUtils.toCodePointArray(word0);
final int[] codePoints1 = StringUtils.toCodePointArray(word1);
removeBigramWordsNative(mNativeDict, codePoints0, codePoints1);
}
- @UsedForTesting
public void flush() {
if (!isValidDictionary()) return;
flushNative(mNativeDict, mDictFilePath);
+ closeNative(mNativeDict);
+ final File dictFile = new File(mDictFilePath);
+ mNativeDict = openNative(dictFile.getAbsolutePath(), 0 /* startOffset */,
+ dictFile.length(), true /* isUpdatable */);
}
- @UsedForTesting
public void flushWithGC() {
if (!isValidDictionary()) return;
flushWithGCNative(mNativeDict, mDictFilePath);
+ closeNative(mNativeDict);
+ final File dictFile = new File(mDictFilePath);
+ mNativeDict = openNative(dictFile.getAbsolutePath(), 0 /* startOffset */,
+ dictFile.length(), true /* isUpdatable */);
}
- @UsedForTesting
public boolean needsToRunGC() {
if (!isValidDictionary()) return false;
return needsToRunGCNative(mNativeDict);
}
+ @UsedForTesting
+ public int calculateProbability(final int unigramProbability, final int bigramProbability) {
+ if (!isValidDictionary()) return NOT_A_PROBABILITY;
+ return calculateProbabilityNative(mNativeDict, unigramProbability, bigramProbability);
+ }
+
@Override
public boolean shouldAutoCommit(final SuggestedWordInfo candidate) {
// TODO: actually use the confidence rather than use this completely broken heuristic
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index 566184244..181ad17ea 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -286,7 +286,8 @@ final public class BinaryDictionaryGetter {
}
if (!dictPackSettings.isWordListActive(wordListId)) continue;
if (canUse) {
- fileList.add(AssetFileAddress.makeFromFileName(f.getPath()));
+ final AssetFileAddress afa = AssetFileAddress.makeFromFileName(f.getPath());
+ if (null != afa) fileList.add(afa);
} else {
Log.e(TAG, "Found a cached dictionary file but cannot read or use it");
}
diff --git a/java/src/com/android/inputmethod/latin/Constants.java b/java/src/com/android/inputmethod/latin/Constants.java
index 029ba02ed..c4f96016c 100644
--- a/java/src/com/android/inputmethod/latin/Constants.java
+++ b/java/src/com/android/inputmethod/latin/Constants.java
@@ -76,6 +76,11 @@ public final class Constants {
public static final String ASCII_CAPABLE = "AsciiCapable";
/**
+ * The subtype extra value used to indicate that the subtype keyboard layout is capable
+ * for typing EMOJI characters.
+ */
+ public static final String EMOJI_CAPABLE = "EmojiCapable";
+ /**
* The subtype extra value used to indicate that the subtype require network connection
* to work.
*/
@@ -133,6 +138,9 @@ public final class Constants {
public static final int SPELL_CHECKER_COORDINATE = -3;
public static final int EXTERNAL_KEYBOARD_COORDINATE = -4;
+ // A hint on how many characters to cache from the TextView. A good value of this is given by
+ // how many characters we need to be able to almost always find the caps mode.
+ public static final int EDITOR_CONTENTS_CACHE_SIZE = 1024;
// Must be equal to MAX_WORD_LENGTH in native/jni/src/defines.h
public static final int DICTIONARY_MAX_WORD_LENGTH = 48;
@@ -157,6 +165,7 @@ public final class Constants {
public static final int CODE_TAB = '\t';
public static final int CODE_SPACE = ' ';
public static final int CODE_PERIOD = '.';
+ public static final int CODE_ARMENIAN_PERIOD = 0x0589;
public static final int CODE_DASH = '-';
public static final int CODE_SINGLE_QUOTE = '\'';
public static final int CODE_DOUBLE_QUOTE = '"';
@@ -164,9 +173,7 @@ public final class Constants {
public static final int CODE_EXCLAMATION_MARK = '!';
public static final int CODE_SLASH = '/';
public static final int CODE_COMMERCIAL_AT = '@';
- // TODO: Check how this should work for right-to-left languages. It seems to stand
- // that for rtl languages, a closing parenthesis is a left parenthesis. Is this
- // managed by the font? Or is it a different char?
+ public static final int CODE_PLUS = '+';
public static final int CODE_CLOSING_PARENTHESIS = ')';
public static final int CODE_CLOSING_SQUARE_BRACKET = ']';
public static final int CODE_CLOSING_CURLY_BRACKET = '}';
@@ -221,7 +228,6 @@ public final class Constants {
}
public static final int MAX_INT_BIT_COUNT = 32;
- public static final String STRING_COMMA = ",";
private Constants() {
// This utility class is not publicly instantiable.
diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
index 67eb7f3dd..ffeb92784 100644
--- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
@@ -22,6 +22,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
+import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.SystemClock;
import android.provider.BaseColumns;
@@ -145,8 +146,10 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
cursor.close();
}
}
- } catch (IllegalStateException e) {
- Log.e(TAG, "Contacts DB is having problems");
+ } catch (final SQLiteException e) {
+ Log.e(TAG, "SQLiteException in the remote Contacts process.", e);
+ } catch (final IllegalStateException e) {
+ Log.e(TAG, "Contacts DB is having problems", e);
}
}
@@ -173,14 +176,18 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
private int getContactCount() {
// TODO: consider switching to a rawQuery("select count(*)...") on the database if
// performance is a bottleneck.
- final Cursor cursor = mContext.getContentResolver().query(
- Contacts.CONTENT_URI, PROJECTION_ID_ONLY, null, null, null);
- if (cursor != null) {
- try {
- return cursor.getCount();
- } finally {
- cursor.close();
+ try {
+ final Cursor cursor = mContext.getContentResolver().query(
+ Contacts.CONTENT_URI, PROJECTION_ID_ONLY, null, null, null);
+ if (cursor != null) {
+ try {
+ return cursor.getCount();
+ } finally {
+ cursor.close();
+ }
}
+ } catch (final SQLiteException e) {
+ Log.e(TAG, "SQLiteException in the remote Contacts process.", e);
}
return 0;
}
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 2a9076436..0774ce203 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -22,14 +22,22 @@ import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo;
-import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.makedict.DictEncoder;
+import com.android.inputmethod.latin.makedict.FormatSpec;
+import com.android.inputmethod.latin.makedict.FusionDictionary;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
+import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
+import com.android.inputmethod.latin.makedict.Ver3DictEncoder;
import com.android.inputmethod.latin.personalization.DynamicPersonalizationDictionaryWriter;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.utils.AsyncResultHolder;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.PrioritizedSerialExecutor;
import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
@@ -49,9 +57,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
/** Whether to print debug output to log */
private static boolean DEBUG = false;
- // TODO: Remove and enable dynamic update in native code.
+ // TODO: Remove.
/** Whether to call binary dictionary dynamically updating methods. */
- private static boolean ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE = false;
+ public static boolean ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE = true;
private static final int TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS = 100;
@@ -60,6 +68,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
*/
protected static final int MAX_WORD_LENGTH = Constants.DICTIONARY_MAX_WORD_LENGTH;
+ private static final FormatSpec.FormatOptions FORMAT_OPTIONS =
+ new FormatSpec.FormatOptions(3 /* version */, true /* supportsDynamicUpdate */);
+
/**
* A static map of time recorders, each of which records the time of accesses to a single binary
* dictionary file. The key for this map is the filename and the value is the shared dictionary
@@ -154,7 +165,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
private static AbstractDictionaryWriter getDictionaryWriter(final Context context,
final String dictType, final boolean isDynamicPersonalizationDictionary) {
if (isDynamicPersonalizationDictionary) {
- return new DynamicPersonalizationDictionaryWriter(context, dictType);
+ if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
+ return null;
+ } else {
+ return new DynamicPersonalizationDictionaryWriter(context, dictType);
+ }
} else {
return new DictionaryWriter(context, dictType);
}
@@ -198,7 +213,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
mBinaryDictionary.close();
mBinaryDictionary = null;
}
- mDictionaryWriter.close();
+ if (mDictionaryWriter != null) {
+ mDictionaryWriter.close();
+ }
}
});
}
@@ -220,7 +237,23 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
getExecutor(mFilename).execute(new Runnable() {
@Override
public void run() {
- mDictionaryWriter.clear();
+ if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE && mDictionaryWriter == null) {
+ mBinaryDictionary.close();
+ final File file = new File(mContext.getFilesDir(), mFilename);
+ final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
+ new FusionDictionary.DictionaryOptions(new HashMap<String,String>(),
+ false, false));
+ final DictEncoder dictEncoder = new Ver3DictEncoder(file);
+ try {
+ dictEncoder.writeDictionary(dict, FORMAT_OPTIONS);
+ } catch (IOException e) {
+ Log.e(TAG, "Exception in creating new dictionary file.", e);
+ } catch (UnsupportedFormatException e) {
+ Log.e(TAG, "Exception in creating new dictionary file.", e);
+ }
+ } else {
+ mDictionaryWriter.clear();
+ }
}
});
}
@@ -257,9 +290,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
public void run() {
if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
mBinaryDictionary.addUnigramWord(word, frequency);
+ } else {
+ // TODO: Remove.
+ mDictionaryWriter.addUnigramWord(word, shortcutTarget, frequency, isNotAWord);
}
- // TODO: Remove.
- mDictionaryWriter.addUnigramWord(word, shortcutTarget, frequency, isNotAWord);
}
});
}
@@ -280,10 +314,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
public void run() {
if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
mBinaryDictionary.addBigramWords(word0, word1, frequency);
+ } else {
+ // TODO: Remove.
+ mDictionaryWriter.addBigramWords(word0, word1, frequency, isValid,
+ 0 /* lastTouchedTime */);
}
- // TODO: Remove.
- mDictionaryWriter.addBigramWords(word0, word1, frequency, isValid,
- 0 /* lastTouchedTime */);
}
});
}
@@ -303,17 +338,19 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
public void run() {
if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
mBinaryDictionary.removeBigramWords(word0, word1);
+ } else {
+ // TODO: Remove.
+ mDictionaryWriter.removeBigramWords(word0, word1);
}
- // TODO: Remove.
- mDictionaryWriter.removeBigramWords(word0, word1);
}
});
}
@Override
- public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
+ public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
+ final int sessionId) {
reloadDictionaryIfRequired();
final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
final AsyncResultHolder<ArrayList<SuggestedWordInfo>> holder =
@@ -321,32 +358,54 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
getExecutor(mFilename).executePrioritized(new Runnable() {
@Override
public void run() {
- final ArrayList<SuggestedWordInfo> inMemDictSuggestion =
- mDictionaryWriter.getSuggestions(composer, prevWord, proximityInfo,
- blockOffensiveWords, additionalFeaturesOptions);
- // TODO: Remove checking mIsUpdatable and use native suggestion.
- if (mBinaryDictionary != null && !mIsUpdatable) {
+ if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
+ if (mBinaryDictionary == null) {
+ holder.set(null);
+ return;
+ }
final ArrayList<SuggestedWordInfo> binarySuggestion =
- mBinaryDictionary.getSuggestions(composer, prevWord, proximityInfo,
- blockOffensiveWords, additionalFeaturesOptions);
- if (inMemDictSuggestion == null) {
- holder.set(binarySuggestion);
- } else if (binarySuggestion == null) {
- holder.set(inMemDictSuggestion);
+ mBinaryDictionary.getSuggestionsWithSessionId(composer, prevWord,
+ proximityInfo, blockOffensiveWords, additionalFeaturesOptions,
+ sessionId);
+ holder.set(binarySuggestion);
+ } else {
+ final ArrayList<SuggestedWordInfo> inMemDictSuggestion =
+ composer.isBatchMode() ? null :
+ mDictionaryWriter.getSuggestionsWithSessionId(composer,
+ prevWord, proximityInfo, blockOffensiveWords,
+ additionalFeaturesOptions, sessionId);
+ // TODO: Remove checking mIsUpdatable and use native suggestion.
+ if (mBinaryDictionary != null && !mIsUpdatable) {
+ final ArrayList<SuggestedWordInfo> binarySuggestion =
+ mBinaryDictionary.getSuggestionsWithSessionId(composer, prevWord,
+ proximityInfo, blockOffensiveWords,
+ additionalFeaturesOptions, sessionId);
+ if (inMemDictSuggestion == null) {
+ holder.set(binarySuggestion);
+ } else if (binarySuggestion == null) {
+ holder.set(inMemDictSuggestion);
+ } else {
+ binarySuggestion.addAll(inMemDictSuggestion);
+ holder.set(binarySuggestion);
+ }
} else {
- binarySuggestion.addAll(inMemDictSuggestion);
- holder.set(binarySuggestion);
+ holder.set(inMemDictSuggestion);
}
- } else {
- holder.set(inMemDictSuggestion);
}
}
});
-
return holder.get(null, TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS);
}
@Override
+ public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
+ final String prevWord, final ProximityInfo proximityInfo,
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
+ return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords,
+ additionalFeaturesOptions, 0 /* sessionId */);
+ }
+
+ @Override
public boolean isValidWord(final String word) {
reloadDictionaryIfRequired();
return isValidWordInner(word);
@@ -401,8 +460,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
final BinaryDictionary newBinaryDictionary = new BinaryDictionary(filename, 0, length,
true /* useFullEditDistance */, null, mDictType, mIsUpdatable);
- // Ensure all threads accessing the current dictionary have finished before swapping in
- // the new one.
+ // Ensure all threads accessing the current dictionary have finished before
+ // swapping in the new one.
+ // TODO: Ensure multi-thread assignment of mBinaryDictionary.
final BinaryDictionary oldBinaryDictionary = mBinaryDictionary;
getExecutor(mFilename).executePrioritized(new Runnable() {
@Override
@@ -433,8 +493,33 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
if (needsToReloadBeforeWriting()) {
mDictionaryWriter.clear();
loadDictionaryAsync();
+ mDictionaryWriter.write(mFilename);
+ } else {
+ if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
+ if (mBinaryDictionary == null || !mBinaryDictionary.isValidDictionary()) {
+ final File file = new File(mContext.getFilesDir(), mFilename);
+ final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
+ new FusionDictionary.DictionaryOptions(new HashMap<String,String>(),
+ false, false));
+ final DictEncoder dictEncoder = new Ver3DictEncoder(file);
+ try {
+ dictEncoder.writeDictionary(dict, FORMAT_OPTIONS);
+ } catch (IOException e) {
+ Log.e(TAG, "Exception in creating new dictionary file.", e);
+ } catch (UnsupportedFormatException e) {
+ Log.e(TAG, "Exception in creating new dictionary file.", e);
+ }
+ } else {
+ if (mBinaryDictionary.needsToRunGC()) {
+ mBinaryDictionary.flushWithGC();
+ } else {
+ mBinaryDictionary.flush();
+ }
+ }
+ } else {
+ mDictionaryWriter.write(mFilename);
+ }
}
- mDictionaryWriter.write(mFilename);
}
/**
@@ -529,7 +614,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
getExecutor(mFilename).executePrioritized(new Runnable() {
@Override
public void run() {
- loadDictionaryAsync();
+ if (!ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
+ loadDictionaryAsync();
+ }
}
});
}
@@ -537,7 +624,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
/**
* Generate binary dictionary using DictionaryWriter.
*/
- protected void asyncWriteBinaryDictionary() {
+ protected void asyncFlashAllBinaryDictionary() {
final Runnable newTask = new Runnable() {
@Override
public void run() {
@@ -610,8 +697,12 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@Override
public void run() {
if (mDictType == Dictionary.TYPE_USER_HISTORY) {
- holder.set(((DynamicPersonalizationDictionaryWriter) mDictionaryWriter)
- .isInDictionaryForTests(word));
+ if (ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
+ holder.set(mBinaryDictionary.isValidWord(word));
+ } else {
+ holder.set(((DynamicPersonalizationDictionaryWriter) mDictionaryWriter)
+ .isInDictionaryForTests(word));
+ }
}
}
});
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index d3a18d410..270dc4c06 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -46,6 +46,7 @@ import android.text.InputType;
import android.text.TextUtils;
import android.text.style.SuggestionSpan;
import android.util.Log;
+import android.util.Pair;
import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.view.KeyCharacterMap;
@@ -232,10 +233,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private static final int MSG_RESUME_SUGGESTIONS = 4;
private static final int MSG_REOPEN_DICTIONARIES = 5;
private static final int MSG_ON_END_BATCH_INPUT = 6;
+ private static final int MSG_RESET_CACHES = 7;
private static final int ARG1_NOT_GESTURE_INPUT = 0;
private static final int ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1;
private static final int ARG1_SHOW_GESTURE_FLOATING_PREVIEW_TEXT = 2;
+ private static final int ARG2_WITHOUT_TYPED_WORD = 0;
+ private static final int ARG2_WITH_TYPED_WORD = 1;
private int mDelayUpdateSuggestions;
private int mDelayUpdateShiftState;
@@ -269,7 +273,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
break;
case MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP:
if (msg.arg1 == ARG1_NOT_GESTURE_INPUT) {
- latinIme.showSuggestionStrip((SuggestedWords) msg.obj);
+ if (msg.arg2 == ARG2_WITH_TYPED_WORD) {
+ final Pair<SuggestedWords, String> p =
+ (Pair<SuggestedWords, String>) msg.obj;
+ latinIme.showSuggestionStripWithTypedWord(p.first, p.second);
+ } else {
+ latinIme.showSuggestionStrip((SuggestedWords) msg.obj);
+ }
} else {
latinIme.showGesturePreviewAndSuggestionStrip((SuggestedWords) msg.obj,
msg.arg1 == ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT);
@@ -288,6 +298,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
case MSG_ON_END_BATCH_INPUT:
latinIme.onEndBatchInputAsyncInternal((SuggestedWords) msg.obj);
break;
+ case MSG_RESET_CACHES:
+ latinIme.retryResetCaches(msg.arg1 == 1 /* tryResumeSuggestions */,
+ msg.arg2 /* remainingTries */);
+ break;
}
}
@@ -304,6 +318,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
sendMessageDelayed(obtainMessage(MSG_RESUME_SUGGESTIONS), mDelayUpdateSuggestions);
}
+ public void postResetCaches(final boolean tryResumeSuggestions, final int remainingTries) {
+ removeMessages(MSG_RESET_CACHES);
+ sendMessage(obtainMessage(MSG_RESET_CACHES, tryResumeSuggestions ? 1 : 0,
+ remainingTries, null));
+ }
+
public void cancelUpdateSuggestionStrip() {
removeMessages(MSG_UPDATE_SUGGESTION_STRIP);
}
@@ -331,14 +351,23 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final int arg1 = dismissGestureFloatingPreviewText
? ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT
: ARG1_SHOW_GESTURE_FLOATING_PREVIEW_TEXT;
- obtainMessage(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP, arg1, 0, suggestedWords)
- .sendToTarget();
+ obtainMessage(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP, arg1,
+ ARG2_WITHOUT_TYPED_WORD, suggestedWords).sendToTarget();
}
public void showSuggestionStrip(final SuggestedWords suggestedWords) {
removeMessages(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP);
obtainMessage(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP,
- ARG1_NOT_GESTURE_INPUT, 0, suggestedWords).sendToTarget();
+ ARG1_NOT_GESTURE_INPUT, ARG2_WITHOUT_TYPED_WORD, suggestedWords).sendToTarget();
+ }
+
+ // TODO: Remove this method.
+ public void showSuggestionStripWithTypedWord(final SuggestedWords suggestedWords,
+ final String typedWord) {
+ removeMessages(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP);
+ obtainMessage(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP, ARG1_NOT_GESTURE_INPUT,
+ ARG2_WITH_TYPED_WORD,
+ new Pair<SuggestedWords, String>(suggestedWords, typedWord)).sendToTarget();
}
public void onEndBatchInput(final SuggestedWords suggestedWords) {
@@ -834,7 +863,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// span, so we should reset our state unconditionally, even if restarting is true.
mEnteredText = null;
resetComposingState(true /* alsoResetLastComposedWord */);
- if (isDifferentTextField) mHandler.postResumeSuggestions();
mDeleteCount = 0;
mSpaceState = SPACE_STATE_NONE;
mRecapitalizeStatus.deactivate();
@@ -853,8 +881,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
mSuggestedWords = SuggestedWords.EMPTY;
- mConnection.resetCachesUponCursorMove(editorInfo.initialSelStart,
- false /* shouldFinishComposition */);
+ // Sometimes, while rotating, for some reason the framework tells the app we are not
+ // connected to it and that means we can't refresh the cache. In this case, schedule a
+ // refresh later.
+ if (!mConnection.resetCachesUponCursorMoveAndReturnSuccess(editorInfo.initialSelStart,
+ false /* shouldFinishComposition */)) {
+ // We try resetting the caches up to 5 times before giving up.
+ mHandler.postResetCaches(isDifferentTextField, 5 /* remainingTries */);
+ } else {
+ if (isDifferentTextField) mHandler.postResumeSuggestions();
+ }
if (isDifferentTextField) {
mainKeyboardView.closing();
@@ -881,6 +917,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mLastSelectionStart = editorInfo.initialSelStart;
mLastSelectionEnd = editorInfo.initialSelEnd;
+ // In some cases (namely, after rotation of the device) editorInfo.initialSelStart is lying
+ // so we try using some heuristics to find out about these and fix them.
+ tryFixLyingCursorPosition();
mHandler.cancelUpdateSuggestionStrip();
mHandler.cancelDoubleSpacePeriodTimer();
@@ -900,6 +939,35 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
}
+ /**
+ * Try to get the text from the editor to expose lies the framework may have been
+ * telling us. Concretely, when the device rotates, the frameworks tells us about where the
+ * cursor used to be initially in the editor at the time it first received the focus; this
+ * may be completely different from the place it is upon rotation. Since we don't have any
+ * means to get the real value, try at least to ask the text view for some characters and
+ * detect the most damaging cases: when the cursor position is declared to be much smaller
+ * than it really is.
+ */
+ private void tryFixLyingCursorPosition() {
+ final CharSequence textBeforeCursor =
+ mConnection.getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE, 0);
+ if (null == textBeforeCursor) {
+ mLastSelectionStart = mLastSelectionEnd = NOT_A_CURSOR_POSITION;
+ } else {
+ final int textLength = textBeforeCursor.length();
+ if (textLength > mLastSelectionStart
+ || (textLength < Constants.EDITOR_CONTENTS_CACHE_SIZE
+ && mLastSelectionStart < Constants.EDITOR_CONTENTS_CACHE_SIZE)) {
+ mLastSelectionStart = textLength;
+ // We can't figure out the value of mLastSelectionEnd :(
+ // But at least if it's smaller than mLastSelectionStart something is wrong
+ if (mLastSelectionStart > mLastSelectionEnd) {
+ mLastSelectionEnd = mLastSelectionStart;
+ }
+ }
+ }
+ }
+
// Initialization of personalization debug settings. This must be called inside
// onStartInputView.
private void initPersonalizationDebugSettings(SettingsValues currentSettingsValues) {
@@ -1054,7 +1122,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// argument as true. But in all cases where we don't reset the entire input state,
// we still want to tell the rich input connection about the new cursor position so
// that it can update its caches.
- mConnection.resetCachesUponCursorMove(newSelStart,
+ mConnection.resetCachesUponCursorMoveAndReturnSuccess(newSelStart,
false /* shouldFinishComposition */);
}
@@ -1290,7 +1358,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} else {
setSuggestedWords(settingsValues.mSuggestPuncList, false);
}
- mConnection.resetCachesUponCursorMove(newCursorPosition, shouldFinishComposition);
+ mConnection.resetCachesUponCursorMoveAndReturnSuccess(newCursorPosition,
+ shouldFinishComposition);
}
private void resetComposingState(final boolean alsoResetLastComposedWord) {
@@ -1394,7 +1463,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|| codePoint == Constants.CODE_CLOSING_PARENTHESIS
|| codePoint == Constants.CODE_CLOSING_SQUARE_BRACKET
|| codePoint == Constants.CODE_CLOSING_CURLY_BRACKET
- || codePoint == Constants.CODE_CLOSING_ANGLE_BRACKET;
+ || codePoint == Constants.CODE_CLOSING_ANGLE_BRACKET
+ || codePoint == Constants.CODE_PLUS;
}
// Callback for the {@link SuggestionStripView}, to call when the "add to dictionary" hint is
@@ -2467,27 +2537,39 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
false /* isPrediction */);
}
- private void setAutoCorrection(final SuggestedWords suggestedWords) {
+ private void setAutoCorrection(final SuggestedWords suggestedWords, final String typedWord) {
if (suggestedWords.isEmpty()) return;
final String autoCorrection;
if (suggestedWords.mWillAutoCorrect) {
autoCorrection = suggestedWords.getWord(SuggestedWords.INDEX_OF_AUTO_CORRECTION);
} else {
- autoCorrection = suggestedWords.getWord(SuggestedWords.INDEX_OF_TYPED_WORD);
+ // We can't use suggestedWords.getWord(SuggestedWords.INDEX_OF_TYPED_WORD)
+ // because it may differ from mWordComposer.mTypedWord.
+ autoCorrection = typedWord;
}
mWordComposer.setAutoCorrection(autoCorrection);
}
+ private void showSuggestionStripWithTypedWord(final SuggestedWords suggestedWords,
+ final String typedWord) {
+ if (suggestedWords.isEmpty()) {
+ clearSuggestionStrip();
+ return;
+ }
+ setAutoCorrection(suggestedWords, typedWord);
+ final boolean isAutoCorrection = suggestedWords.willAutoCorrect();
+ setSuggestedWords(suggestedWords, isAutoCorrection);
+ setAutoCorrectionIndicator(isAutoCorrection);
+ setSuggestionStripShown(isSuggestionsStripVisible());
+ }
+
private void showSuggestionStrip(final SuggestedWords suggestedWords) {
if (suggestedWords.isEmpty()) {
clearSuggestionStrip();
return;
}
- setAutoCorrection(suggestedWords);
- final boolean isAutoCorrection = suggestedWords.willAutoCorrect();
- setSuggestedWords(suggestedWords, isAutoCorrection);
- setAutoCorrectionIndicator(isAutoCorrection);
- setSuggestionStripShown(isSuggestionsStripVisible());
+ showSuggestionStripWithTypedWord(suggestedWords,
+ suggestedWords.getWord(SuggestedWords.INDEX_OF_TYPED_WORD));
}
private void commitCurrentAutoCorrection(final String separator) {
@@ -2685,6 +2767,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return prevWord;
}
+ private boolean isResumableWord(final String word, final SettingsValues settings) {
+ final int firstCodePoint = word.codePointAt(0);
+ return settings.isWordCodePoint(firstCodePoint)
+ && Constants.CODE_SINGLE_QUOTE != firstCodePoint
+ && Constants.CODE_DASH != firstCodePoint;
+ }
+
/**
* Check if the cursor is touching a word. If so, restart suggestions on this word, else
* do nothing.
@@ -2708,12 +2797,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final TextRange range = mConnection.getWordRangeAtCursor(currentSettings.mWordSeparators,
0 /* additionalPrecedingWordsCount */);
if (null == range) return; // Happens if we don't have an input connection at all
+ if (range.length() <= 0) return; // Race condition. No text to resume on, so bail out.
// If for some strange reason (editor bug or so) we measure the text before the cursor as
// longer than what the entire text is supposed to be, the safe thing to do is bail out.
final int numberOfCharsInWordBeforeCursor = range.getNumberOfCharsInWordBeforeCursor();
if (numberOfCharsInWordBeforeCursor > mLastSelectionStart) return;
final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
final String typedWord = range.mWord.toString();
+ if (!isResumableWord(typedWord, currentSettings)) return;
int i = 0;
for (final SuggestionSpan span : range.getSuggestionSpansAtWord()) {
for (final String s : span.getSuggestions()) {
@@ -2757,7 +2848,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Since there is only one word, willAutoCorrect is false.
suggestedWords = suggestedWordsIncludingTypedWord;
}
- unsetIsAutoCorrectionIndicatorOnAndCallShowSuggestionStrip(suggestedWords);
+ // We need to pass typedWord because mWordComposer.mTypedWord may differ from
+ // typedWord.
+ unsetIsAutoCorrectionIndicatorOnAndCallShowSuggestionStrip(suggestedWords,
+ typedWord);
}});
} else {
// We found suggestion spans in the word. We'll create the SuggestedWords out of
@@ -2766,12 +2860,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
true /* typedWordValid */, false /* willAutoCorrect */,
false /* isPunctuationSuggestions */, false /* isObsoleteSuggestions */,
false /* isPrediction */);
- unsetIsAutoCorrectionIndicatorOnAndCallShowSuggestionStrip(suggestedWords);
+ // We need to pass typedWord because mWordComposer.mTypedWord may differ from typedWord.
+ unsetIsAutoCorrectionIndicatorOnAndCallShowSuggestionStrip(suggestedWords, typedWord);
}
}
public void unsetIsAutoCorrectionIndicatorOnAndCallShowSuggestionStrip(
- final SuggestedWords suggestedWords) {
+ final SuggestedWords suggestedWords, final String typedWord) {
// Note that it's very important here that suggestedWords.mWillAutoCorrect is false.
// We never want to auto-correct on a resumed suggestion. Please refer to the three places
// above in restartSuggestionsOnWordTouchedByCursor() where suggestedWords is affected.
@@ -2779,7 +2874,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// the text to adapt it.
// TODO: remove mIsAutoCorrectionIndicatorOn (see comment on definition)
mIsAutoCorrectionIndicatorOn = false;
- mHandler.showSuggestionStrip(suggestedWords);
+ mHandler.showSuggestionStripWithTypedWord(suggestedWords, typedWord);
}
/**
@@ -2809,6 +2904,27 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mHandler.postUpdateSuggestionStrip();
}
+ /**
+ * Retry resetting caches in the rich input connection.
+ *
+ * When the editor can't be accessed we can't reset the caches, so we schedule a retry.
+ * This method handles the retry, and re-schedules a new retry if we still can't access.
+ * We only retry up to 5 times before giving up.
+ *
+ * @param tryResumeSuggestions Whether we should resume suggestions or not.
+ * @param remainingTries How many times we may try again before giving up.
+ */
+ private void retryResetCaches(final boolean tryResumeSuggestions, final int remainingTries) {
+ if (!mConnection.resetCachesUponCursorMoveAndReturnSuccess(mLastSelectionStart, false)) {
+ if (0 < remainingTries) {
+ mHandler.postResetCaches(tryResumeSuggestions, remainingTries - 1);
+ }
+ return;
+ }
+ tryFixLyingCursorPosition();
+ if (tryResumeSuggestions) mHandler.postResumeSuggestions();
+ }
+
private void revertCommit() {
final String previousWord = mLastComposedWord.mPrevWord;
final String originallyTypedWord = mLastComposedWord.mTypedWord;
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index a031bb3be..925381b50 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -73,9 +73,6 @@ public final class RichInputConnection {
* This contains the currently composing text, as LatinIME thinks the TextView is seeing it.
*/
private final StringBuilder mComposingText = new StringBuilder();
- // A hint on how many characters to cache from the TextView. A good value of this is given by
- // how many characters we need to be able to almost always find the caps mode.
- private static final int DEFAULT_TEXT_CACHE_SIZE = 100;
private final InputMethodService mParent;
InputConnection mIC;
@@ -93,7 +90,8 @@ public final class RichInputConnection {
r.token = 1;
r.flags = 0;
final ExtractedText et = mIC.getExtractedText(r, 0);
- final CharSequence beforeCursor = getTextBeforeCursor(DEFAULT_TEXT_CACHE_SIZE, 0);
+ final CharSequence beforeCursor = getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE,
+ 0);
final StringBuilder internal = new StringBuilder().append(mCommittedTextBeforeComposingText)
.append(mComposingText);
if (null == et || null == beforeCursor) return;
@@ -142,19 +140,56 @@ public final class RichInputConnection {
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
}
- public void resetCachesUponCursorMove(final int newCursorPosition,
+ /**
+ * Reset the cached text and retrieve it again from the editor.
+ *
+ * This should be called when the cursor moved. It's possible that we can't connect to
+ * the application when doing this; notably, this happens sometimes during rotation, probably
+ * because of a race condition in the framework. In this case, we just can't retrieve the
+ * data, so we empty the cache and note that we don't know the new cursor position, and we
+ * return false so that the caller knows about this and can retry later.
+ *
+ * @param newCursorPosition The new position of the cursor, as received from the system.
+ * @param shouldFinishComposition Whether we should finish the composition in progress.
+ * @return true if we were able to connect to the editor successfully, false otherwise. When
+ * this method returns false, the caches could not be correctly refreshed so they were only
+ * reset: the caller should try again later to return to normal operation.
+ */
+ public boolean resetCachesUponCursorMoveAndReturnSuccess(final int newCursorPosition,
final boolean shouldFinishComposition) {
mExpectedCursorPosition = newCursorPosition;
mComposingText.setLength(0);
mCommittedTextBeforeComposingText.setLength(0);
- final CharSequence textBeforeCursor = getTextBeforeCursor(DEFAULT_TEXT_CACHE_SIZE, 0);
- if (null != textBeforeCursor) mCommittedTextBeforeComposingText.append(textBeforeCursor);
+ mIC = mParent.getCurrentInputConnection();
+ // Call upon the inputconnection directly since our own method is using the cache, and
+ // we want to refresh it.
+ final CharSequence textBeforeCursor = null == mIC ? null :
+ mIC.getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE, 0);
+ if (null == textBeforeCursor) {
+ // For some reason the app thinks we are not connected to it. This looks like a
+ // framework bug... Fall back to ground state and return false.
+ mExpectedCursorPosition = INVALID_CURSOR_POSITION;
+ Log.e(TAG, "Unable to connect to the editor to retrieve text... will retry later");
+ return false;
+ }
+ mCommittedTextBeforeComposingText.append(textBeforeCursor);
+ final int lengthOfTextBeforeCursor = textBeforeCursor.length();
+ if (lengthOfTextBeforeCursor > newCursorPosition
+ || (lengthOfTextBeforeCursor < Constants.EDITOR_CONTENTS_CACHE_SIZE
+ && newCursorPosition < Constants.EDITOR_CONTENTS_CACHE_SIZE)) {
+ // newCursorPosition may be lying -- when rotating the device (probably a framework
+ // bug). If we have less chars than we asked for, then we know how many chars we have,
+ // and if we got more than newCursorPosition says, then we know it was lying. In both
+ // cases the length is more reliable
+ mExpectedCursorPosition = lengthOfTextBeforeCursor;
+ }
if (null != mIC && shouldFinishComposition) {
mIC.finishComposingText();
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.richInputConnection_finishComposingText();
}
}
+ return true;
}
private void checkBatchEdit() {
@@ -233,8 +268,11 @@ public final class RichInputConnection {
// getCapsMode should be updated to be able to return a "not enough info" result so that
// we can get more context only when needed.
if (TextUtils.isEmpty(mCommittedTextBeforeComposingText) && 0 != mExpectedCursorPosition) {
- mCommittedTextBeforeComposingText.append(
- getTextBeforeCursor(DEFAULT_TEXT_CACHE_SIZE, 0));
+ final CharSequence textBeforeCursor = getTextBeforeCursor(
+ Constants.EDITOR_CONTENTS_CACHE_SIZE, 0);
+ if (!TextUtils.isEmpty(textBeforeCursor)) {
+ mCommittedTextBeforeComposingText.append(textBeforeCursor);
+ }
}
// This never calls InputConnection#getCapsMode - in fact, it's a static method that
// never blocks or initiates IPC.
@@ -362,7 +400,7 @@ public final class RichInputConnection {
if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
final CharSequence textBeforeCursor =
- getTextBeforeCursor(DEFAULT_TEXT_CACHE_SIZE + (end - start), 0);
+ getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE + (end - start), 0);
mCommittedTextBeforeComposingText.setLength(0);
if (!TextUtils.isEmpty(textBeforeCursor)) {
final int indexOfStartOfComposingText =
@@ -404,7 +442,8 @@ public final class RichInputConnection {
}
mExpectedCursorPosition = start;
mCommittedTextBeforeComposingText.setLength(0);
- mCommittedTextBeforeComposingText.append(getTextBeforeCursor(DEFAULT_TEXT_CACHE_SIZE, 0));
+ mCommittedTextBeforeComposingText.append(
+ getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE, 0));
}
public void commitCorrection(final CorrectionInfo correctionInfo) {
@@ -523,9 +562,9 @@ public final class RichInputConnection {
if (mIC == null || sep == null) {
return null;
}
- final CharSequence before = mIC.getTextBeforeCursor(1000,
+ final CharSequence before = mIC.getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE,
InputConnection.GET_TEXT_WITH_STYLES);
- final CharSequence after = mIC.getTextAfterCursor(1000,
+ final CharSequence after = mIC.getTextAfterCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE,
InputConnection.GET_TEXT_WITH_STYLES);
if (before == null || after == null) {
return null;
@@ -568,8 +607,11 @@ public final class RichInputConnection {
}
}
- return new TextRange(TextUtils.concat(before, after), startIndexInBefore,
- before.length() + endIndexInAfter, before.length());
+ // We don't use TextUtils#concat because it copies all spans without respect to their
+ // nature. If the text includes a PARAGRAPH span and it has been split, then
+ // TextUtils#concat will crash when it tries to concat both sides of it.
+ return new TextRange(StringUtils.concatWithNonParagraphSuggestionSpansOnly(before, after),
+ startIndexInBefore, before.length() + endIndexInAfter, before.length());
}
public boolean isCursorTouchingWord(final SettingsValues settingsValues) {
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index 0889f22ca..cd9c89f04 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -58,17 +58,20 @@ public final class SubtypeSwitcher {
// Dummy no language QWERTY subtype. See {@link R.xml.method}.
private static final InputMethodSubtype DUMMY_NO_LANGUAGE_SUBTYPE = new InputMethodSubtype(
- R.string.subtype_no_language_qwerty, R.drawable.ic_subtype_keyboard,
- SubtypeLocaleUtils.NO_LANGUAGE, "keyboard",
- "KeyboardLayoutSet=" + SubtypeLocaleUtils.QWERTY
- + ",AsciiCapable,EnabledWhenDefaultIsNotAsciiCapable",
+ R.string.subtype_no_language_qwerty, R.drawable.ic_ime_switcher_dark,
+ SubtypeLocaleUtils.NO_LANGUAGE, "keyboard", "KeyboardLayoutSet="
+ + SubtypeLocaleUtils.QWERTY
+ + "," + Constants.Subtype.ExtraValue.ASCII_CAPABLE
+ + ",EnabledWhenDefaultIsNotAsciiCapable,"
+ + Constants.Subtype.ExtraValue.EMOJI_CAPABLE,
false /* isAuxiliary */, false /* overridesImplicitlyEnabledSubtype */);
// Caveat: We probably should remove this when we add an Emoji subtype in {@link R.xml.method}.
// Dummy Emoji subtype. See {@link R.xml.method}.
private static final InputMethodSubtype DUMMY_EMOJI_SUBTYPE = new InputMethodSubtype(
- R.string.subtype_emoji, R.drawable.ic_subtype_keyboard,
- SubtypeLocaleUtils.NO_LANGUAGE, "keyboard",
- "KeyboardLayoutSet=" + SubtypeLocaleUtils.EMOJI,
+ R.string.subtype_emoji, R.drawable.ic_ime_switcher_dark,
+ SubtypeLocaleUtils.NO_LANGUAGE, "keyboard", "KeyboardLayoutSet="
+ + SubtypeLocaleUtils.EMOJI + ","
+ + Constants.Subtype.ExtraValue.EMOJI_CAPABLE,
false /* isAuxiliary */, false /* overridesImplicitlyEnabledSubtype */);
static final class NeedsToDisplayLanguage {
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 7815f4d41..6c18c948f 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -361,12 +361,6 @@ public final class Suggest {
// At second character typed, search the unigrams (scores being affected by bigrams)
for (final String key : mDictionaries.keySet()) {
- // Skip User history dictionary for lookup
- // TODO: The user history dictionary should just override getSuggestionsWithSessionId
- // to make sure it doesn't return anything and we should remove this test
- if (key.equals(Dictionary.TYPE_USER_HISTORY)) {
- continue;
- }
final Dictionary dictionary = mDictionaries.get(key);
suggestionsSet.addAll(dictionary.getSuggestionsWithSessionId(wordComposer,
prevWordForBigram, proximityInfo, blockOffensiveWords,
@@ -460,7 +454,7 @@ public final class Suggest {
private static final SuggestedWordInfoComparator sSuggestedWordInfoComparator =
new SuggestedWordInfoComparator();
- private static SuggestedWordInfo getTransformedSuggestedWordInfo(
+ /* package for test */ static SuggestedWordInfo getTransformedSuggestedWordInfo(
final SuggestedWordInfo wordInfo, final Locale locale, final boolean isAllUpperCase,
final boolean isFirstCharCapitalized, final int trailingSingleQuotesCount) {
final StringBuilder sb = new StringBuilder(wordInfo.mWord.length());
@@ -471,7 +465,12 @@ public final class Suggest {
} else {
sb.append(wordInfo.mWord);
}
- for (int i = trailingSingleQuotesCount - 1; i >= 0; --i) {
+ // Appending quotes is here to help people quote words. However, it's not helpful
+ // when they type words with quotes toward the end like "it's" or "didn't", where
+ // it's more likely the user missed the last character (or didn't type it yet).
+ final int quotesToAppend = trailingSingleQuotesCount
+ - (-1 == wordInfo.mWord.indexOf(Constants.CODE_SINGLE_QUOTE) ? 0 : 1);
+ for (int i = quotesToAppend - 1; i >= 0; --i) {
sb.appendCodePoint(Constants.CODE_SINGLE_QUOTE);
}
return new SuggestedWordInfo(sb.toString(), wordInfo.mScore, wordInfo.mKind,
diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
index a241b5505..864a17375 100644
--- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
@@ -22,10 +22,12 @@ import android.content.ContentUris;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
+import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.Build;
import android.provider.UserDictionary.Words;
import android.text.TextUtils;
+import android.util.Log;
import com.android.inputmethod.compat.UserDictionaryCompatUtils;
import com.android.inputmethod.latin.utils.LocaleUtils;
@@ -39,6 +41,7 @@ import java.util.Locale;
* dictionary file to use it from native code.
*/
public class UserBinaryDictionary extends ExpandableBinaryDictionary {
+ private static final String TAG = ExpandableBinaryDictionary.class.getSimpleName();
// The user dictionary provider uses an empty string to mean "all languages".
private static final String USER_DICTIONARY_ALL_LANGUAGES = "";
@@ -168,12 +171,19 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
} else {
requestArguments = localeElements;
}
- final Cursor cursor = mContext.getContentResolver().query(
- Words.CONTENT_URI, PROJECTION_QUERY, request.toString(), requestArguments, null);
+ Cursor cursor = null;
try {
+ cursor = mContext.getContentResolver().query(
+ Words.CONTENT_URI, PROJECTION_QUERY, request.toString(), requestArguments, null);
addWords(cursor);
+ } catch (final SQLiteException e) {
+ Log.e(TAG, "SQLiteException in the remote User dictionary process.", e);
} finally {
- if (null != cursor) cursor.close();
+ try {
+ if (null != cursor) cursor.close();
+ } catch (final SQLiteException e) {
+ Log.e(TAG, "SQLiteException in the remote User dictionary process.", e);
+ }
}
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
index 5b319ad90..665c7a27c 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
@@ -498,7 +498,7 @@ public final class BinaryDictDecoderUtils {
// reach the end of the array.
if (options.mSupportsDynamicUpdate) {
- final boolean hasValidForwardLink = dictDecoder.readForwardLinkAndAdvancePosition();
+ final boolean hasValidForwardLink = dictDecoder.readAndFollowForwardLink();
if (!hasValidForwardLink) break;
}
} while (options.mSupportsDynamicUpdate && dictDecoder.hasNextPtNodeArray());
@@ -550,7 +550,7 @@ public final class BinaryDictDecoderUtils {
* @return the created (or merged) dictionary.
*/
@UsedForTesting
- /* package */ static FusionDictionary readDictionaryBinary(final Ver3DictDecoder dictDecoder,
+ /* package */ static FusionDictionary readDictionaryBinary(final DictDecoder dictDecoder,
final FusionDictionary dict) throws IOException, UnsupportedFormatException {
// Read header
final FileHeader fileHeader = dictDecoder.readHeader();
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
index f333b0d86..4dba8e5cf 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
@@ -368,9 +368,9 @@ public class BinaryDictEncoderUtils {
if (null != ptNode.mBigrams) {
for (WeightedString bigram : ptNode.mBigrams) {
final int offset = getOffsetToTargetPtNodeDuringUpdate(ptNodeArray,
- nodeSize + size + FormatSpec.PTNODE_FLAGS_SIZE,
+ nodeSize + size + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE,
FusionDictionary.findWordInTree(dict.mRootNodeArray, bigram.mWord));
- nodeSize += getByteSize(offset) + FormatSpec.PTNODE_FLAGS_SIZE;
+ nodeSize += getByteSize(offset) + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE;
}
}
ptNode.mCachedSize = nodeSize;
@@ -758,8 +758,15 @@ public class BinaryDictEncoderUtils {
final FormatOptions formatOptions) {
int positionOfChildrenPosField = ptNode.mCachedAddressAfterUpdate
+ getNodeHeaderSize(ptNode, formatOptions);
- if (ptNode.mFrequency >= 0) {
- positionOfChildrenPosField += FormatSpec.PTNODE_FREQUENCY_SIZE;
+ if (ptNode.isTerminal()) {
+ // A terminal node has either the terminal id or the frequency.
+ // If positionOfChildrenPosField is incorrect, we may crash when jumping to the children
+ // position.
+ if (formatOptions.mHasTerminalId) {
+ positionOfChildrenPosField += FormatSpec.PTNODE_TERMINAL_ID_SIZE;
+ } else {
+ positionOfChildrenPosField += FormatSpec.PTNODE_FREQUENCY_SIZE;
+ }
}
return null == ptNode.mChildren ? FormatSpec.NO_CHILDREN_ADDRESS
: ptNode.mChildren.mCachedAddressAfterUpdate - positionOfChildrenPosField;
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 2c5e93e5c..a282f595c 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -114,7 +114,7 @@ public final class BinaryDictIOUtils {
if (p.mPosition == p.mNumOfPtNode) {
if (formatOptions.mSupportsDynamicUpdate) {
final boolean hasValidForwardLinkAddress =
- dictDecoder.readForwardLinkAndAdvancePosition();
+ dictDecoder.readAndFollowForwardLink();
if (hasValidForwardLinkAddress && dictDecoder.hasNextPtNodeArray()) {
// The node array has a forward link.
p.mNumOfPtNode = Position.NOT_READ_PTNODE_COUNT;
@@ -233,7 +233,7 @@ public final class BinaryDictIOUtils {
}
final boolean hasValidForwardLinkAddress =
- dictDecoder.readForwardLinkAndAdvancePosition();
+ dictDecoder.readAndFollowForwardLink();
if (!hasValidForwardLinkAddress || !dictDecoder.hasNextPtNodeArray()) {
return FormatSpec.NOT_VALID_WORD;
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java
index 40e852423..3796a466c 100644
--- a/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/DictDecoder.java
@@ -17,9 +17,11 @@
package com.android.inputmethod.latin.makedict;
import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding;
import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
+import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import com.android.inputmethod.latin.utils.ByteArrayDictBuffer;
import java.io.File;
@@ -30,13 +32,50 @@ import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.TreeMap;
/**
- * An interface of binary dictionary decoder.
+ * The base class of binary dictionary decoders.
*/
-public interface DictDecoder {
- public FileHeader readHeader() throws IOException, UnsupportedFormatException;
+public abstract class DictDecoder {
+
+ protected FileHeader readHeader(final DictBuffer dictBuffer)
+ throws IOException, UnsupportedFormatException {
+ if (dictBuffer == null) {
+ openDictBuffer();
+ }
+
+ final int version = HeaderReader.readVersion(dictBuffer);
+ if (version < FormatSpec.MINIMUM_SUPPORTED_VERSION
+ || version > FormatSpec.MAXIMUM_SUPPORTED_VERSION) {
+ throw new UnsupportedFormatException("Unsupported version : " + version);
+ }
+ // TODO: Remove this field.
+ final int optionsFlags = HeaderReader.readOptionFlags(dictBuffer);
+
+ final int headerSize = HeaderReader.readHeaderSize(dictBuffer);
+
+ if (headerSize < 0) {
+ throw new UnsupportedFormatException("header size can't be negative.");
+ }
+
+ final HashMap<String, String> attributes = HeaderReader.readAttributes(dictBuffer,
+ headerSize);
+
+ final FileHeader header = new FileHeader(headerSize,
+ new FusionDictionary.DictionaryOptions(attributes,
+ 0 != (optionsFlags & FormatSpec.GERMAN_UMLAUT_PROCESSING_FLAG),
+ 0 != (optionsFlags & FormatSpec.FRENCH_LIGATURE_PROCESSING_FLAG)),
+ new FormatOptions(version,
+ 0 != (optionsFlags & FormatSpec.SUPPORTS_DYNAMIC_UPDATE)));
+ return header;
+ }
+
+ /**
+ * Reads and returns the file header.
+ */
+ public abstract FileHeader readHeader() throws IOException, UnsupportedFormatException;
/**
* Reads PtNode from nodeAddress.
@@ -44,7 +83,7 @@ public interface DictDecoder {
* @param formatOptions the format options.
* @return PtNodeInfo.
*/
- public PtNodeInfo readPtNode(final int ptNodePos, final FormatOptions formatOptions);
+ public abstract PtNodeInfo readPtNode(final int ptNodePos, final FormatOptions formatOptions);
/**
* Reads a buffer and returns the memory representation of the dictionary.
@@ -59,9 +98,9 @@ public interface DictDecoder {
* @return the created (or merged) dictionary.
*/
@UsedForTesting
- public FusionDictionary readDictionaryBinary(final FusionDictionary dict,
+ public abstract FusionDictionary readDictionaryBinary(final FusionDictionary dict,
final boolean deleteDictIfBroken)
- throws FileNotFoundException, IOException, UnsupportedFormatException;
+ throws FileNotFoundException, IOException, UnsupportedFormatException;
/**
* Gets the address of the last PtNode of the exact matching word in the dictionary.
@@ -74,7 +113,12 @@ public interface DictDecoder {
*/
@UsedForTesting
public int getTerminalPosition(final String word)
- throws IOException, UnsupportedFormatException;
+ throws IOException, UnsupportedFormatException {
+ if (!isDictBufferOpen()) {
+ openDictBuffer();
+ }
+ return BinaryDictIOUtils.getTerminalPosition(this, word);
+ }
/**
* Reads unigrams and bigrams from the binary file.
@@ -86,50 +130,56 @@ public interface DictDecoder {
* @throws IOException if the file can't be read.
* @throws UnsupportedFormatException if the format of the file is not recognized.
*/
+ @UsedForTesting
public void readUnigramsAndBigramsBinary(final TreeMap<Integer, String> words,
final TreeMap<Integer, Integer> frequencies,
final TreeMap<Integer, ArrayList<PendingAttribute>> bigrams)
- throws IOException, UnsupportedFormatException;
+ throws IOException, UnsupportedFormatException {
+ if (!isDictBufferOpen()) {
+ openDictBuffer();
+ }
+ BinaryDictIOUtils.readUnigramsAndBigramsBinary(this, words, frequencies, bigrams);
+ }
/**
* Sets the position of the buffer to the given value.
*
* @param newPos the new position
*/
- public void setPosition(final int newPos);
+ public abstract void setPosition(final int newPos);
/**
* Gets the position of the buffer.
*
* @return the position
*/
- public int getPosition();
+ public abstract int getPosition();
/**
* Reads and returns the PtNode count out of a buffer and forwards the pointer.
*/
- public int readPtNodeCount();
+ public abstract int readPtNodeCount();
/**
* Reads the forward link and advances the position.
*
- * @return if this method advances the position then true else false.
+ * @return true if this method moves the file pointer, false otherwise.
*/
- public boolean readForwardLinkAndAdvancePosition();
- public boolean hasNextPtNodeArray();
+ public abstract boolean readAndFollowForwardLink();
+ public abstract boolean hasNextPtNodeArray();
/**
* Opens the dictionary file and makes DictBuffer.
*/
@UsedForTesting
- public void openDictBuffer() throws FileNotFoundException, IOException;
+ public abstract void openDictBuffer() throws FileNotFoundException, IOException;
@UsedForTesting
- public boolean isOpenedDictBuffer();
+ public abstract boolean isDictBufferOpen();
- // Flags for DictionaryBufferFactory.
+ // Constants for DictionaryBufferFactory.
public static final int USE_READONLY_BYTEBUFFER = 0x01000000;
public static final int USE_BYTEARRAY = 0x02000000;
- public static final int USE_WRITABLE_BYTEBUFFER = 0x04000000;
+ public static final int USE_WRITABLE_BYTEBUFFER = 0x03000000;
public static final int MASK_DICTBUFFER = 0x0F000000;
public interface DictionaryBufferFactory {
@@ -221,4 +271,124 @@ public interface DictDecoder {
return null;
}
}
+
+ /**
+ * A utility class for reading a file header.
+ */
+ protected static class HeaderReader {
+ protected static int readVersion(final DictBuffer dictBuffer)
+ throws IOException, UnsupportedFormatException {
+ return BinaryDictDecoderUtils.checkFormatVersion(dictBuffer);
+ }
+
+ protected static int readOptionFlags(final DictBuffer dictBuffer) {
+ return dictBuffer.readUnsignedShort();
+ }
+
+ protected static int readHeaderSize(final DictBuffer dictBuffer) {
+ return dictBuffer.readInt();
+ }
+
+ protected static HashMap<String, String> readAttributes(final DictBuffer dictBuffer,
+ final int headerSize) {
+ final HashMap<String, String> attributes = new HashMap<String, String>();
+ while (dictBuffer.position() < headerSize) {
+ // We can avoid an infinite loop here since dictBuffer.position() is always
+ // increased by calling CharEncoding.readString.
+ final String key = CharEncoding.readString(dictBuffer);
+ final String value = CharEncoding.readString(dictBuffer);
+ attributes.put(key, value);
+ }
+ dictBuffer.position(headerSize);
+ return attributes;
+ }
+ }
+
+ /**
+ * A utility class for reading a PtNode.
+ */
+ protected static class PtNodeReader {
+ protected static int readPtNodeOptionFlags(final DictBuffer dictBuffer) {
+ return dictBuffer.readUnsignedByte();
+ }
+
+ protected static int readParentAddress(final DictBuffer dictBuffer,
+ final FormatOptions formatOptions) {
+ if (BinaryDictIOUtils.supportsDynamicUpdate(formatOptions)) {
+ return BinaryDictDecoderUtils.readSInt24(dictBuffer);
+ } else {
+ return FormatSpec.NO_PARENT_ADDRESS;
+ }
+ }
+
+ protected static int readChildrenAddress(final DictBuffer dictBuffer, final int optionFlags,
+ final FormatOptions formatOptions) {
+ if (BinaryDictIOUtils.supportsDynamicUpdate(formatOptions)) {
+ final int address = BinaryDictDecoderUtils.readSInt24(dictBuffer);
+ if (address == 0) return FormatSpec.NO_CHILDREN_ADDRESS;
+ return address;
+ } else {
+ switch (optionFlags & FormatSpec.MASK_CHILDREN_ADDRESS_TYPE) {
+ case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE:
+ return dictBuffer.readUnsignedByte();
+ case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_TWOBYTES:
+ return dictBuffer.readUnsignedShort();
+ case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_THREEBYTES:
+ return dictBuffer.readUnsignedInt24();
+ case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_NOADDRESS:
+ default:
+ return FormatSpec.NO_CHILDREN_ADDRESS;
+ }
+ }
+ }
+
+ // Reads shortcuts and returns the read length.
+ protected static int readShortcut(final DictBuffer dictBuffer,
+ final ArrayList<WeightedString> shortcutTargets) {
+ final int pointerBefore = dictBuffer.position();
+ dictBuffer.readUnsignedShort(); // skip the size
+ while (true) {
+ final int targetFlags = dictBuffer.readUnsignedByte();
+ final String word = CharEncoding.readString(dictBuffer);
+ shortcutTargets.add(new WeightedString(word,
+ targetFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY));
+ if (0 == (targetFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT)) break;
+ }
+ return dictBuffer.position() - pointerBefore;
+ }
+
+ protected static int readBigramAddresses(final DictBuffer dictBuffer,
+ final ArrayList<PendingAttribute> bigrams, final int baseAddress) {
+ int readLength = 0;
+ int bigramCount = 0;
+ while (bigramCount++ < FormatSpec.MAX_BIGRAMS_IN_A_PTNODE) {
+ final int bigramFlags = dictBuffer.readUnsignedByte();
+ ++readLength;
+ final int sign = 0 == (bigramFlags & FormatSpec.FLAG_BIGRAM_ATTR_OFFSET_NEGATIVE)
+ ? 1 : -1;
+ int bigramAddress = baseAddress + readLength;
+ switch (bigramFlags & FormatSpec.MASK_BIGRAM_ATTR_ADDRESS_TYPE) {
+ case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_ONEBYTE:
+ bigramAddress += sign * dictBuffer.readUnsignedByte();
+ readLength += 1;
+ break;
+ case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_TWOBYTES:
+ bigramAddress += sign * dictBuffer.readUnsignedShort();
+ readLength += 2;
+ break;
+ case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_THREEBYTES:
+ bigramAddress += sign * dictBuffer.readUnsignedInt24();
+ readLength += 3;
+ break;
+ default:
+ throw new RuntimeException("Has bigrams with no address");
+ }
+ bigrams.add(new PendingAttribute(
+ bigramFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY,
+ bigramAddress));
+ if (0 == (bigramFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT)) break;
+ }
+ return readLength;
+ }
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index 96ccd8e49..51b89a02a 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -360,18 +360,26 @@ public final class FormatSpec {
* Returns new dictionary decoder.
*
* @param dictFile the dictionary file.
- * @param bufferType the flag indicating buffer type which is used by the dictionary decoder.
+ * @param bufferType The type of buffer, as one of USE_* in DictDecoder.
* @return new dictionary decoder if the dictionary file exists, otherwise null.
*/
public static DictDecoder getDictDecoder(final File dictFile, final int bufferType) {
- if (!dictFile.isFile()) return null;
- return new Ver3DictDecoder(dictFile, bufferType);
+ if (dictFile.isDirectory()) {
+ return new Ver4DictDecoder(dictFile, bufferType);
+ } else if (dictFile.isFile()) {
+ return new Ver3DictDecoder(dictFile, bufferType);
+ }
+ return null;
}
public static DictDecoder getDictDecoder(final File dictFile,
final DictionaryBufferFactory factory) {
- if (!dictFile.isFile()) return null;
- return new Ver3DictDecoder(dictFile, factory);
+ if (dictFile.isDirectory()) {
+ return new Ver4DictDecoder(dictFile, factory);
+ } else if (dictFile.isFile()) {
+ return new Ver3DictDecoder(dictFile, factory);
+ }
+ return null;
}
public static DictDecoder getDictDecoder(final File dictFile) {
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java
index 1a90a4b98..848277cd4 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver3DictDecoder.java
@@ -32,14 +32,12 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashMap;
-import java.util.TreeMap;
/**
* An implementation of DictDecoder for version 3 binary dictionary.
*/
@UsedForTesting
-public class Ver3DictDecoder implements DictDecoder {
+public class Ver3DictDecoder extends DictDecoder {
private static final String TAG = Ver3DictDecoder.class.getSimpleName();
static {
@@ -49,124 +47,10 @@ public class Ver3DictDecoder implements DictDecoder {
// TODO: implement something sensical instead of just a phony method
private static native int doNothing();
- private final static class HeaderReader {
- protected static int readVersion(final DictBuffer dictBuffer)
- throws IOException, UnsupportedFormatException {
- return BinaryDictDecoderUtils.checkFormatVersion(dictBuffer);
- }
-
- protected static int readOptionFlags(final DictBuffer dictBuffer) {
- return dictBuffer.readUnsignedShort();
- }
-
- protected static int readHeaderSize(final DictBuffer dictBuffer) {
- return dictBuffer.readInt();
- }
-
- protected static HashMap<String, String> readAttributes(final DictBuffer dictBuffer,
- final int headerSize) {
- final HashMap<String, String> attributes = new HashMap<String, String>();
- while (dictBuffer.position() < headerSize) {
- // We can avoid an infinite loop here since dictBuffer.position() is always
- // increased by calling CharEncoding.readString.
- final String key = CharEncoding.readString(dictBuffer);
- final String value = CharEncoding.readString(dictBuffer);
- attributes.put(key, value);
- }
- dictBuffer.position(headerSize);
- return attributes;
- }
- }
-
- private final static class PtNodeReader {
- protected static int readPtNodeOptionFlags(final DictBuffer dictBuffer) {
+ protected static class PtNodeReader extends DictDecoder.PtNodeReader {
+ private static int readFrequency(final DictBuffer dictBuffer) {
return dictBuffer.readUnsignedByte();
}
-
- protected static int readParentAddress(final DictBuffer dictBuffer,
- final FormatOptions formatOptions) {
- if (BinaryDictIOUtils.supportsDynamicUpdate(formatOptions)) {
- return BinaryDictDecoderUtils.readSInt24(dictBuffer);
- } else {
- return FormatSpec.NO_PARENT_ADDRESS;
- }
- }
-
- protected static int readFrequency(final DictBuffer dictBuffer) {
- return dictBuffer.readUnsignedByte();
- }
-
- protected static int readChildrenAddress(final DictBuffer dictBuffer, final int optionFlags,
- final FormatOptions formatOptions) {
- if (BinaryDictIOUtils.supportsDynamicUpdate(formatOptions)) {
- final int address = BinaryDictDecoderUtils.readSInt24(dictBuffer);
- if (address == 0) return FormatSpec.NO_CHILDREN_ADDRESS;
- return address;
- } else {
- switch (optionFlags & FormatSpec.MASK_CHILDREN_ADDRESS_TYPE) {
- case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE:
- return dictBuffer.readUnsignedByte();
- case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_TWOBYTES:
- return dictBuffer.readUnsignedShort();
- case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_THREEBYTES:
- return dictBuffer.readUnsignedInt24();
- case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_NOADDRESS:
- default:
- return FormatSpec.NO_CHILDREN_ADDRESS;
- }
- }
- }
-
- // Reads shortcuts and returns the read length.
- protected static int readShortcut(final DictBuffer dictBuffer,
- final ArrayList<WeightedString> shortcutTargets) {
- final int pointerBefore = dictBuffer.position();
- dictBuffer.readUnsignedShort(); // skip the size
- while (true) {
- final int targetFlags = dictBuffer.readUnsignedByte();
- final String word = CharEncoding.readString(dictBuffer);
- shortcutTargets.add(new WeightedString(word,
- targetFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY));
- if (0 == (targetFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT)) break;
- }
- return dictBuffer.position() - pointerBefore;
- }
-
- protected static int readBigrams(final DictBuffer dictBuffer,
- final ArrayList<PendingAttribute> bigrams, final int baseAddress) {
- int readLength = 0;
- int bigramCount = 0;
- while (bigramCount++ < FormatSpec.MAX_BIGRAMS_IN_A_PTNODE) {
- final int bigramFlags = dictBuffer.readUnsignedByte();
- ++readLength;
- final int sign = 0 == (bigramFlags & FormatSpec.FLAG_BIGRAM_ATTR_OFFSET_NEGATIVE)
- ? 1 : -1;
- int bigramAddress = baseAddress + readLength;
- switch (bigramFlags & FormatSpec.MASK_BIGRAM_ATTR_ADDRESS_TYPE) {
- case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_ONEBYTE:
- bigramAddress += sign * dictBuffer.readUnsignedByte();
- readLength += 1;
- break;
- case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_TWOBYTES:
- bigramAddress += sign * dictBuffer.readUnsignedShort();
- readLength += 2;
- break;
- case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_THREEBYTES:
- final int offset = (dictBuffer.readUnsignedByte() << 16)
- + dictBuffer.readUnsignedShort();
- bigramAddress += sign * offset;
- readLength += 3;
- break;
- default:
- throw new RuntimeException("Has bigrams with no address");
- }
- bigrams.add(new PendingAttribute(
- bigramFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY,
- bigramAddress));
- if (0 == (bigramFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT)) break;
- }
- return readLength;
- }
}
private final File mDictionaryBinaryFile;
@@ -199,7 +83,7 @@ public class Ver3DictDecoder implements DictDecoder {
}
@Override
- public boolean isOpenedDictBuffer() {
+ public boolean isDictBufferOpen() {
return mDictBuffer != null;
}
@@ -218,25 +102,11 @@ public class Ver3DictDecoder implements DictDecoder {
if (mDictBuffer == null) {
openDictBuffer();
}
-
- final int version = HeaderReader.readVersion(mDictBuffer);
- final int optionsFlags = HeaderReader.readOptionFlags(mDictBuffer);
-
- final int headerSize = HeaderReader.readHeaderSize(mDictBuffer);
-
- if (headerSize < 0) {
- throw new UnsupportedFormatException("header size can't be negative.");
+ final FileHeader header = super.readHeader(mDictBuffer);
+ final int version = header.mFormatOptions.mVersion;
+ if (!(version >= 2 && version <= 3)) {
+ throw new UnsupportedFormatException("File header has a wrong version : " + version);
}
-
- final HashMap<String, String> attributes = HeaderReader.readAttributes(mDictBuffer,
- headerSize);
-
- final FileHeader header = new FileHeader(headerSize,
- new FusionDictionary.DictionaryOptions(attributes,
- 0 != (optionsFlags & FormatSpec.GERMAN_UMLAUT_PROCESSING_FLAG),
- 0 != (optionsFlags & FormatSpec.FRENCH_LIGATURE_PROCESSING_FLAG)),
- new FormatOptions(version,
- 0 != (optionsFlags & FormatSpec.SUPPORTS_DYNAMIC_UPDATE)));
return header;
}
@@ -246,11 +116,11 @@ public class Ver3DictDecoder implements DictDecoder {
public PtNodeInfo readPtNode(final int ptNodePos, final FormatOptions options) {
int addressPointer = ptNodePos;
final int flags = PtNodeReader.readPtNodeOptionFlags(mDictBuffer);
- ++addressPointer;
+ addressPointer += FormatSpec.PTNODE_FLAGS_SIZE;
final int parentAddress = PtNodeReader.readParentAddress(mDictBuffer, options);
if (BinaryDictIOUtils.supportsDynamicUpdate(options)) {
- addressPointer += 3;
+ addressPointer += FormatSpec.PARENT_ADDRESS_SIZE;
}
final int characters[];
@@ -258,7 +128,7 @@ public class Ver3DictDecoder implements DictDecoder {
int index = 0;
int character = CharEncoding.readChar(mDictBuffer);
addressPointer += CharEncoding.getCharSize(character);
- while (-1 != character) {
+ while (FormatSpec.INVALID_CHARACTER != character) {
// FusionDictionary is making sure that the length of the word is smaller than
// MAX_WORD_LENGTH.
// So we'll never write past the end of mCharacterBuffer.
@@ -274,8 +144,8 @@ public class Ver3DictDecoder implements DictDecoder {
}
final int frequency;
if (0 != (FormatSpec.FLAG_IS_TERMINAL & flags)) {
- ++addressPointer;
frequency = PtNodeReader.readFrequency(mDictBuffer);
+ addressPointer += FormatSpec.PTNODE_FREQUENCY_SIZE;
} else {
frequency = PtNode.NOT_A_TERMINAL;
}
@@ -296,7 +166,8 @@ public class Ver3DictDecoder implements DictDecoder {
final ArrayList<PendingAttribute> bigrams;
if (0 != (flags & FormatSpec.FLAG_HAS_BIGRAMS)) {
bigrams = new ArrayList<PendingAttribute>();
- addressPointer += PtNodeReader.readBigrams(mDictBuffer, bigrams, addressPointer);
+ addressPointer += PtNodeReader.readBigramAddresses(mDictBuffer, bigrams,
+ addressPointer);
if (bigrams.size() >= FormatSpec.MAX_BIGRAMS_IN_A_PTNODE) {
MakedictLog.d("too many bigrams in a PtNode.");
}
@@ -332,25 +203,6 @@ public class Ver3DictDecoder implements DictDecoder {
}
@Override
- public int getTerminalPosition(String word) throws IOException, UnsupportedFormatException {
- if (mDictBuffer == null) {
- openDictBuffer();
- }
- return BinaryDictIOUtils.getTerminalPosition(this, word);
- }
-
- @Override
- public void readUnigramsAndBigramsBinary(final TreeMap<Integer, String> words,
- final TreeMap<Integer, Integer> frequencies,
- final TreeMap<Integer, ArrayList<PendingAttribute>> bigrams)
- throws IOException, UnsupportedFormatException {
- if (mDictBuffer == null) {
- openDictBuffer();
- }
- BinaryDictIOUtils.readUnigramsAndBigramsBinary(this, words, frequencies, bigrams);
- }
-
- @Override
public void setPosition(int newPos) {
mDictBuffer.position(newPos);
}
@@ -366,7 +218,7 @@ public class Ver3DictDecoder implements DictDecoder {
}
@Override
- public boolean readForwardLinkAndAdvancePosition() {
+ public boolean readAndFollowForwardLink() {
final int nextAddress = mDictBuffer.readUnsignedInt24();
if (nextAddress >= 0 && nextAddress < mDictBuffer.limit()) {
mDictBuffer.position(nextAddress);
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver3DictEncoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver3DictEncoder.java
index 222a0f474..76f0f4052 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver3DictEncoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver3DictEncoder.java
@@ -167,7 +167,7 @@ public class Ver3DictEncoder implements DictEncoder {
}
}
- public void writeChildrenPosition(final PtNode ptNode, final FormatOptions formatOptions) {
+ private void writeChildrenPosition(final PtNode ptNode, final FormatOptions formatOptions) {
final int childrenPos = BinaryDictEncoderUtils.getChildrenPosition(ptNode, formatOptions);
if (formatOptions.mSupportsDynamicUpdate) {
mPosition += BinaryDictEncoderUtils.writeSignedChildrenPosition(mBuffer, mPosition,
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
new file mode 100644
index 000000000..36c5a2720
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.makedict;
+
+import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding;
+import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
+import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
+import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
+import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
+import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * An implementation of binary dictionary decoder for version 4 binary dictionary.
+ */
+@UsedForTesting
+public class Ver4DictDecoder extends DictDecoder {
+ private static final String TAG = Ver4DictDecoder.class.getSimpleName();
+
+ private static final int FILETYPE_TRIE = 1;
+ private static final int FILETYPE_FREQUENCY = 2;
+
+ private final File mDictDirectory;
+ private final DictionaryBufferFactory mBufferFactory;
+ private DictBuffer mDictBuffer;
+ private DictBuffer mFrequencyBuffer;
+
+ @UsedForTesting
+ /* package */ Ver4DictDecoder(final File dictDirectory, final int factoryFlag) {
+ mDictDirectory = dictDirectory;
+ mDictBuffer = mFrequencyBuffer = null;
+
+ if ((factoryFlag & MASK_DICTBUFFER) == USE_READONLY_BYTEBUFFER) {
+ mBufferFactory = new DictionaryBufferFromReadOnlyByteBufferFactory();
+ } else if ((factoryFlag & MASK_DICTBUFFER) == USE_BYTEARRAY) {
+ mBufferFactory = new DictionaryBufferFromByteArrayFactory();
+ } else if ((factoryFlag & MASK_DICTBUFFER) == USE_WRITABLE_BYTEBUFFER) {
+ mBufferFactory = new DictionaryBufferFromWritableByteBufferFactory();
+ } else {
+ mBufferFactory = new DictionaryBufferFromReadOnlyByteBufferFactory();
+ }
+ }
+
+ @UsedForTesting
+ /* package */ Ver4DictDecoder(final File dictDirectory, final DictionaryBufferFactory factory) {
+ mDictDirectory = dictDirectory;
+ mBufferFactory = factory;
+ mDictBuffer = mFrequencyBuffer = null;
+ }
+
+ private File getFile(final int fileType) {
+ if (fileType == FILETYPE_TRIE) {
+ return new File(mDictDirectory,
+ mDictDirectory.getName() + FormatSpec.TRIE_FILE_EXTENSION);
+ } else if (fileType == FILETYPE_FREQUENCY) {
+ return new File(mDictDirectory,
+ mDictDirectory.getName() + FormatSpec.FREQ_FILE_EXTENSION);
+ } else {
+ throw new RuntimeException("Unsupported kind of file : " + fileType);
+ }
+ }
+
+ @Override
+ public void openDictBuffer() throws FileNotFoundException, IOException {
+ final String filename = mDictDirectory.getName();
+ mDictBuffer = mBufferFactory.getDictionaryBuffer(getFile(FILETYPE_TRIE));
+ mFrequencyBuffer = mBufferFactory.getDictionaryBuffer(getFile(FILETYPE_FREQUENCY));
+ }
+
+ @Override
+ public boolean isDictBufferOpen() {
+ return mDictBuffer != null;
+ }
+
+ /* package */ DictBuffer getDictBuffer() {
+ return mDictBuffer;
+ }
+
+ @Override
+ public FileHeader readHeader() throws IOException, UnsupportedFormatException {
+ if (mDictBuffer == null) {
+ openDictBuffer();
+ }
+ final FileHeader header = super.readHeader(mDictBuffer);
+ final int version = header.mFormatOptions.mVersion;
+ if (version != 4) {
+ throw new UnsupportedFormatException("File header has a wrong version : " + version);
+ }
+ return header;
+ }
+
+ protected static class PtNodeReader extends DictDecoder.PtNodeReader {
+ protected static int readFrequency(final DictBuffer frequencyBuffer, final int terminalId) {
+ frequencyBuffer.position(terminalId * FormatSpec.FREQUENCY_AND_FLAGS_SIZE + 1);
+ return frequencyBuffer.readUnsignedByte();
+ }
+
+ protected static int readTerminalId(final DictBuffer dictBuffer) {
+ return dictBuffer.readInt();
+ }
+ }
+
+ // TODO: Make this buffer thread safe.
+ // TODO: Support words longer than FormatSpec.MAX_WORD_LENGTH.
+ private final int[] mCharacterBuffer = new int[FormatSpec.MAX_WORD_LENGTH];
+ @Override
+ public PtNodeInfo readPtNode(int ptNodePos, FormatOptions options) {
+ int addressPointer = ptNodePos;
+ final int flags = PtNodeReader.readPtNodeOptionFlags(mDictBuffer);
+ addressPointer += FormatSpec.PTNODE_FLAGS_SIZE;
+
+ final int parentAddress = PtNodeReader.readParentAddress(mDictBuffer, options);
+ if (BinaryDictIOUtils.supportsDynamicUpdate(options)) {
+ addressPointer += FormatSpec.PARENT_ADDRESS_SIZE;
+ }
+
+ final int characters[];
+ if (0 != (flags & FormatSpec.FLAG_HAS_MULTIPLE_CHARS)) {
+ int index = 0;
+ int character = CharEncoding.readChar(mDictBuffer);
+ addressPointer += CharEncoding.getCharSize(character);
+ while (FormatSpec.INVALID_CHARACTER != character
+ && index < FormatSpec.MAX_WORD_LENGTH) {
+ mCharacterBuffer[index++] = character;
+ character = CharEncoding.readChar(mDictBuffer);
+ addressPointer += CharEncoding.getCharSize(character);
+ }
+ characters = Arrays.copyOfRange(mCharacterBuffer, 0, index);
+ } else {
+ final int character = CharEncoding.readChar(mDictBuffer);
+ addressPointer += CharEncoding.getCharSize(character);
+ characters = new int[] { character };
+ }
+ final int terminalId;
+ if (0 != (FormatSpec.FLAG_IS_TERMINAL & flags)) {
+ terminalId = PtNodeReader.readTerminalId(mDictBuffer);
+ addressPointer += FormatSpec.PTNODE_TERMINAL_ID_SIZE;
+ } else {
+ terminalId = PtNode.NOT_A_TERMINAL;
+ }
+
+ final int frequency;
+ if (0 != (FormatSpec.FLAG_IS_TERMINAL & flags)) {
+ frequency = PtNodeReader.readFrequency(mFrequencyBuffer, terminalId);
+ } else {
+ frequency = PtNode.NOT_A_TERMINAL;
+ }
+ int childrenAddress = PtNodeReader.readChildrenAddress(mDictBuffer, flags, options);
+ if (childrenAddress != FormatSpec.NO_CHILDREN_ADDRESS) {
+ childrenAddress += addressPointer;
+ }
+ addressPointer += BinaryDictIOUtils.getChildrenAddressSize(flags, options);
+ final ArrayList<WeightedString> shortcutTargets;
+ if (0 != (flags & FormatSpec.FLAG_HAS_SHORTCUT_TARGETS)) {
+ // readShortcut will add shortcuts to shortcutTargets.
+ shortcutTargets = new ArrayList<WeightedString>();
+ addressPointer += PtNodeReader.readShortcut(mDictBuffer, shortcutTargets);
+ } else {
+ shortcutTargets = null;
+ }
+
+ final ArrayList<PendingAttribute> bigrams;
+ if (0 != (flags & FormatSpec.FLAG_HAS_BIGRAMS)) {
+ bigrams = new ArrayList<PendingAttribute>();
+ addressPointer += PtNodeReader.readBigramAddresses(mDictBuffer, bigrams,
+ addressPointer);
+ if (bigrams.size() >= FormatSpec.MAX_BIGRAMS_IN_A_PTNODE) {
+ MakedictLog.d("too many bigrams in a node.");
+ }
+ } else {
+ bigrams = null;
+ }
+ return new PtNodeInfo(ptNodePos, addressPointer, flags, characters, frequency,
+ parentAddress, childrenAddress, shortcutTargets, bigrams);
+ }
+
+ private void deleteDictFiles() {
+ final File[] files = mDictDirectory.listFiles();
+ for (int i = 0; i < files.length; ++i) {
+ files[i].delete();
+ }
+ }
+
+ @Override
+ public FusionDictionary readDictionaryBinary(final FusionDictionary dict,
+ final boolean deleteDictIfBroken)
+ throws FileNotFoundException, IOException, UnsupportedFormatException {
+ if (mDictBuffer == null) {
+ openDictBuffer();
+ }
+ try {
+ return BinaryDictDecoderUtils.readDictionaryBinary(this, dict);
+ } catch (IOException e) {
+ Log.e(TAG, "The dictionary " + mDictDirectory.getName() + " is broken.", e);
+ if (deleteDictIfBroken) {
+ deleteDictFiles();
+ }
+ throw e;
+ } catch (UnsupportedFormatException e) {
+ Log.e(TAG, "The dictionary " + mDictDirectory.getName() + " is broken.", e);
+ if (deleteDictIfBroken) {
+ deleteDictFiles();
+ }
+ throw e;
+ }
+ }
+
+ @Override
+ public void setPosition(int newPos) {
+ mDictBuffer.position(newPos);
+ }
+
+ @Override
+ public int getPosition() {
+ return mDictBuffer.position();
+ }
+
+ @Override
+ public int readPtNodeCount() {
+ return BinaryDictDecoderUtils.readPtNodeCount(mDictBuffer);
+ }
+
+ @Override
+ public boolean readAndFollowForwardLink() {
+ final int nextAddress = mDictBuffer.readUnsignedInt24();
+ if (nextAddress >= 0 && nextAddress < mDictBuffer.limit()) {
+ mDictBuffer.position(nextAddress);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean hasNextPtNodeArray() {
+ return mDictBuffer.position() != FormatSpec.NO_FORWARD_LINK_ADDRESS;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java b/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java
index e43e74d87..0af028a9e 100644
--- a/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java
+++ b/java/src/com/android/inputmethod/latin/personalization/DynamicPersonalizationDictionaryWriter.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.latin.personalization;
import android.content.Context;
import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.compat.ActivityManagerCompatUtils;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.AbstractDictionaryWriter;
import com.android.inputmethod.latin.ExpandableDictionary;
@@ -41,7 +42,8 @@ import java.util.ArrayList;
public class DynamicPersonalizationDictionaryWriter extends AbstractDictionaryWriter {
private static final String TAG = DynamicPersonalizationDictionaryWriter.class.getSimpleName();
/** Maximum number of pairs. Pruning will start when databases goes above this number. */
- public static final int MAX_HISTORY_BIGRAMS = 10000;
+ public static final int DEFAULT_MAX_HISTORY_BIGRAMS = 10000;
+ public static final int LOW_MEMORY_MAX_HISTORY_BIGRAMS = 2000;
/** Any pair being typed or picked */
private static final int FREQUENCY_FOR_TYPED = 2;
@@ -53,10 +55,14 @@ public class DynamicPersonalizationDictionaryWriter extends AbstractDictionaryWr
private final UserHistoryDictionaryBigramList mBigramList =
new UserHistoryDictionaryBigramList();
private final ExpandableDictionary mExpandableDictionary;
+ private final int mMaxHistoryBigrams;
public DynamicPersonalizationDictionaryWriter(final Context context, final String dictType) {
super(context, dictType);
mExpandableDictionary = new ExpandableDictionary(dictType);
+ final boolean isLowRamDevice = ActivityManagerCompatUtils.isLowRamDevice(context);
+ mMaxHistoryBigrams = isLowRamDevice ?
+ LOW_MEMORY_MAX_HISTORY_BIGRAMS : DEFAULT_MAX_HISTORY_BIGRAMS;
}
@Override
@@ -72,6 +78,10 @@ public class DynamicPersonalizationDictionaryWriter extends AbstractDictionaryWr
@Override
public void addUnigramWord(final String word, final String shortcutTarget, final int frequency,
final boolean isNotAWord) {
+ if (mBigramList.size() > mMaxHistoryBigrams * 2) {
+ // Too many entries: just stop adding new vocabrary and wait next refresh.
+ return;
+ }
mExpandableDictionary.addWord(word, shortcutTarget, frequency);
mBigramList.addBigram(null, word, (byte)frequency);
}
@@ -79,6 +89,10 @@ public class DynamicPersonalizationDictionaryWriter extends AbstractDictionaryWr
@Override
public void addBigramWords(final String word0, final String word1, final int frequency,
final boolean isValid, final long lastModifiedTime) {
+ if (mBigramList.size() > mMaxHistoryBigrams * 2) {
+ // Too many entries: just stop adding new vocabrary and wait next refresh.
+ return;
+ }
if (lastModifiedTime > 0) {
mExpandableDictionary.setBigramAndGetFrequency(word0, word1,
new ForgettingCurveParams(frequency, System.currentTimeMillis(),
@@ -102,19 +116,22 @@ public class DynamicPersonalizationDictionaryWriter extends AbstractDictionaryWr
protected void writeDictionary(final DictEncoder dictEncoder)
throws IOException, UnsupportedFormatException {
UserHistoryDictIOUtils.writeDictionary(dictEncoder,
- new FrequencyProvider(mBigramList, mExpandableDictionary), mBigramList,
- FORMAT_OPTIONS);
+ new FrequencyProvider(mBigramList, mExpandableDictionary, mMaxHistoryBigrams),
+ mBigramList, FORMAT_OPTIONS);
}
private static class FrequencyProvider implements BigramDictionaryInterface {
- final private UserHistoryDictionaryBigramList mBigramList;
- final private ExpandableDictionary mExpandableDictionary;
+ private final UserHistoryDictionaryBigramList mBigramList;
+ private final ExpandableDictionary mExpandableDictionary;
+ private final int mMaxHistoryBigrams;
public FrequencyProvider(final UserHistoryDictionaryBigramList bigramList,
- final ExpandableDictionary expandableDictionary) {
+ final ExpandableDictionary expandableDictionary, final int maxHistoryBigrams) {
mBigramList = bigramList;
mExpandableDictionary = expandableDictionary;
+ mMaxHistoryBigrams = maxHistoryBigrams;
}
+
@Override
public int getFrequency(final String word0, final String word1) {
final int freq;
@@ -130,7 +147,7 @@ public class DynamicPersonalizationDictionaryWriter extends AbstractDictionaryWr
if (prevFc > 0 && prevFc == fc) {
freq = fc & 0xFF;
} else if (UserHistoryForgettingCurveUtils.
- needsToSave(fc, isValid, mBigramList.size() <= MAX_HISTORY_BIGRAMS)) {
+ needsToSave(fc, isValid, mBigramList.size() <= mMaxHistoryBigrams)) {
freq = fc & 0xFF;
} else {
// Delete this entry
diff --git a/java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java b/java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java
index 9364fb034..075d7e3c3 100644
--- a/java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java
+++ b/java/src/com/android/inputmethod/latin/personalization/DynamicPredictionDictionaryBase.java
@@ -74,12 +74,12 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableBinaryDi
@Override
public void close() {
- // Close only binary dictionary to reuse this dictionary.
- // super.close();
- closeBinaryDictionary();
+ if (!ExpandableBinaryDictionary.ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE) {
+ closeBinaryDictionary();
+ }
// Flush pending writes.
// TODO: Remove after this class become to use a dynamic binary dictionary.
- asyncWriteBinaryDictionary();
+ asyncFlashAllBinaryDictionary();
Settings.writeLastUserHistoryWriteTime(mPrefs, mLocale);
}
@@ -212,6 +212,6 @@ public abstract class DynamicPredictionDictionaryBase extends ExpandableBinaryDi
// Clear the node structure on memory
clear();
// Then flush the cleared state of the dictionary on disk.
- asyncWriteBinaryDictionary();
+ asyncFlashAllBinaryDictionary();
}
}
diff --git a/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java b/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
index 215faa0c7..44b201642 100644
--- a/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
@@ -25,6 +25,7 @@ import android.os.Build;
import android.text.TextUtils;
import android.view.inputmethod.InputMethodSubtype;
+import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.R;
import java.util.ArrayList;
@@ -60,9 +61,10 @@ public final class AdditionalSubtypeUtils {
StringUtils.appendToCommaSplittableTextIfNotExists(
IS_ADDITIONAL_SUBTYPE, layoutDisplayNameExtraValue);
final int nameId = SubtypeLocaleUtils.getSubtypeNameId(localeString, keyboardLayoutSetName);
- return new InputMethodSubtype(nameId, R.drawable.ic_subtype_keyboard,
- localeString, KEYBOARD_MODE,
- layoutExtraValue + "," + additionalSubtypeExtraValue, false, false);
+ return new InputMethodSubtype(nameId, R.drawable.ic_ime_switcher_dark,
+ localeString, KEYBOARD_MODE, layoutExtraValue + "," + additionalSubtypeExtraValue
+ + "," + Constants.Subtype.ExtraValue.ASCII_CAPABLE
+ + "," + Constants.Subtype.ExtraValue.EMOJI_CAPABLE, false, false);
}
public static String getPrefSubtype(final InputMethodSubtype subtype) {
diff --git a/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
index 2f91c5743..60b24d5d5 100644
--- a/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
@@ -60,6 +60,11 @@ public final class CapsModeUtils {
|| WordComposer.CAPS_MODE_AUTO_SHIFT_LOCKED == mode;
}
+ private static boolean isPeriod(final int codePoint) {
+ // TODO: make this a resource.
+ return codePoint == Constants.CODE_PERIOD || codePoint == Constants.CODE_ARMENIAN_PERIOD;
+ }
+
/**
* Determine what caps mode should be in effect at the current offset in
* the text. Only the mode bits set in <var>reqModes</var> will be
@@ -190,7 +195,7 @@ public final class CapsModeUtils {
if (c == Constants.CODE_QUESTION_MARK || c == Constants.CODE_EXCLAMATION_MARK) {
return (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_SENTENCES) & reqModes;
}
- if (c != Constants.CODE_PERIOD || j <= 0) {
+ if (!isPeriod(c) || j <= 0) {
return (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS) & reqModes;
}
@@ -240,7 +245,7 @@ public final class CapsModeUtils {
case WORD:
if (Character.isLetter(c)) {
state = WORD;
- } else if (c == Constants.CODE_PERIOD) {
+ } else if (isPeriod(c)) {
state = PERIOD;
} else {
return caps;
@@ -256,7 +261,7 @@ public final class CapsModeUtils {
case LETTER:
if (Character.isLetter(c)) {
state = LETTER;
- } else if (c == Constants.CODE_PERIOD) {
+ } else if (isPeriod(c)) {
state = PERIOD;
} else {
return noCaps;
diff --git a/java/src/com/android/inputmethod/latin/utils/StringUtils.java b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
index be4184093..327780ad0 100644
--- a/java/src/com/android/inputmethod/latin/utils/StringUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
@@ -16,16 +16,30 @@
package com.android.inputmethod.latin.utils;
-import android.text.TextUtils;
-
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.settings.SettingsValues;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.SpannedString;
+import android.text.TextUtils;
+import android.text.style.SuggestionSpan;
+import android.util.JsonReader;
+import android.util.JsonWriter;
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.Locale;
public final class StringUtils {
+ private static final String TAG = StringUtils.class.getSimpleName();
public static final int CAPITALIZE_NONE = 0; // No caps, or mixed case
public static final int CAPITALIZE_FIRST = 1; // First only
public static final int CAPITALIZE_ALL = 2; // All caps
@@ -390,4 +404,151 @@ public final class StringUtils {
}
return bytes;
}
+
+ public static List<Object> jsonStrToList(String s) {
+ final ArrayList<Object> retval = CollectionUtils.newArrayList();
+ final JsonReader reader = new JsonReader(new StringReader(s));
+ try {
+ reader.beginArray();
+ while(reader.hasNext()) {
+ reader.beginObject();
+ while (reader.hasNext()) {
+ final String name = reader.nextName();
+ if (name.equals(Integer.class.getSimpleName())) {
+ retval.add(reader.nextInt());
+ } else if (name.equals(String.class.getSimpleName())) {
+ retval.add(reader.nextString());
+ } else {
+ Log.w(TAG, "Invalid name: " + name);
+ reader.skipValue();
+ }
+ }
+ reader.endObject();
+ }
+ reader.endArray();
+ return retval;
+ } catch (IOException e) {
+ } finally {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ }
+ }
+ return Collections.<Object>emptyList();
+ }
+
+ public static String listToJsonStr(List<Object> list) {
+ if (list == null || list.isEmpty()) {
+ return "";
+ }
+ final StringWriter sw = new StringWriter();
+ final JsonWriter writer = new JsonWriter(sw);
+ try {
+ writer.beginArray();
+ for (final Object o : list) {
+ writer.beginObject();
+ if (o instanceof Integer) {
+ writer.name(Integer.class.getSimpleName()).value((Integer)o);
+ } else if (o instanceof String) {
+ writer.name(String.class.getSimpleName()).value((String)o);
+ }
+ writer.endObject();
+ }
+ writer.endArray();
+ return sw.toString();
+ } catch (IOException e) {
+ } finally {
+ try {
+ if (writer != null) {
+ writer.close();
+ }
+ } catch (IOException e) {
+ }
+ }
+ return "";
+ }
+
+ /**
+ * Copies the spans from the region <code>start...end</code> in
+ * <code>source</code> to the region
+ * <code>destoff...destoff+end-start</code> in <code>dest</code>.
+ * Spans in <code>source</code> that begin before <code>start</code>
+ * or end after <code>end</code> but overlap this range are trimmed
+ * as if they began at <code>start</code> or ended at <code>end</code>.
+ * Only SuggestionSpans that don't have the SPAN_PARAGRAPH span are copied.
+ *
+ * This code is almost entirely taken from {@link TextUtils#copySpansFrom}, except for the
+ * kind of span that is copied.
+ *
+ * @throws IndexOutOfBoundsException if any of the copied spans
+ * are out of range in <code>dest</code>.
+ */
+ public static void copyNonParagraphSuggestionSpansFrom(Spanned source, int start, int end,
+ Spannable dest, int destoff) {
+ Object[] spans = source.getSpans(start, end, SuggestionSpan.class);
+
+ for (int i = 0; i < spans.length; i++) {
+ int fl = source.getSpanFlags(spans[i]);
+ if (0 != (fl & Spannable.SPAN_PARAGRAPH)) continue;
+
+ int st = source.getSpanStart(spans[i]);
+ int en = source.getSpanEnd(spans[i]);
+
+ if (st < start)
+ st = start;
+ if (en > end)
+ en = end;
+
+ dest.setSpan(spans[i], st - start + destoff, en - start + destoff,
+ fl);
+ }
+ }
+
+ /**
+ * Returns a CharSequence concatenating the specified CharSequences, retaining their
+ * SuggestionSpans that don't have the PARAGRAPH flag, but not other spans.
+ *
+ * This code is almost entirely taken from {@link TextUtils#concat(CharSequence...)}, except
+ * it calls copyNonParagraphSuggestionSpansFrom instead of {@link TextUtils#copySpansFrom}.
+ */
+ public static CharSequence concatWithNonParagraphSuggestionSpansOnly(CharSequence... text) {
+ if (text.length == 0) {
+ return "";
+ }
+
+ if (text.length == 1) {
+ return text[0];
+ }
+
+ boolean spanned = false;
+ for (int i = 0; i < text.length; i++) {
+ if (text[i] instanceof Spanned) {
+ spanned = true;
+ break;
+ }
+ }
+
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < text.length; i++) {
+ sb.append(text[i]);
+ }
+
+ if (!spanned) {
+ return sb.toString();
+ }
+
+ SpannableString ss = new SpannableString(sb);
+ int off = 0;
+ for (int i = 0; i < text.length; i++) {
+ int len = text[i].length();
+
+ if (text[i] instanceof Spanned) {
+ copyNonParagraphSuggestionSpansFrom((Spanned) text[i], 0, len, ss, off);
+ }
+
+ off += len;
+ }
+
+ return new SpannedString(ss);
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/utils/TextRange.java b/java/src/com/android/inputmethod/latin/utils/TextRange.java
index 5793e4170..48b443ddd 100644
--- a/java/src/com/android/inputmethod/latin/utils/TextRange.java
+++ b/java/src/com/android/inputmethod/latin/utils/TextRange.java
@@ -40,6 +40,10 @@ public final class TextRange {
return mWordAtCursorEndIndex - mCursorIndex;
}
+ public int length() {
+ return mWord.length();
+ }
+
/**
* Gets the suggestion spans that are put squarely on the word, with the exact start
* and end of the span matching the boundaries of the word.
diff --git a/java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java b/java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java
index 544e4d201..47ea1ea75 100644
--- a/java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java
@@ -66,6 +66,11 @@ public final class TypefaceUtils {
}
}
+ public static float getStringWidth(final String string, final Paint paint) {
+ paint.getTextBounds(string, 0, string.length(), sTextWidthBounds);
+ return sTextWidthBounds.width();
+ }
+
private static int getCharGeometryCacheKey(final char referenceChar, final Paint paint) {
final int labelSize = (int)paint.getTextSize();
final Typeface face = paint.getTypeface();