diff options
Diffstat (limited to 'java')
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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 diff --git a/java/res/drawable-hdpi/ic_emoji_light.png b/java/res/drawable-hdpi/ic_emoji_light.png Binary files differdeleted file mode 100644 index 2e3638bf3..000000000 --- a/java/res/drawable-hdpi/ic_emoji_light.png +++ /dev/null diff --git a/java/res/drawable-hdpi/ic_ime_light.png b/java/res/drawable-hdpi/ic_ime_light.png Binary files differdeleted file mode 100644 index 4fd3ba126..000000000 --- a/java/res/drawable-hdpi/ic_ime_light.png +++ /dev/null diff --git a/java/res/drawable-hdpi/ic_ime_switcher_dark.png b/java/res/drawable-hdpi/ic_ime_switcher_dark.png Binary files differnew file mode 100644 index 000000000..7506af5a3 --- /dev/null +++ b/java/res/drawable-hdpi/ic_ime_switcher_dark.png diff --git a/java/res/drawable-hdpi/ic_subtype_keyboard.png b/java/res/drawable-hdpi/ic_subtype_keyboard.png Binary files differdeleted file mode 100644 index 484305655..000000000 --- a/java/res/drawable-hdpi/ic_subtype_keyboard.png +++ /dev/null diff --git a/java/res/drawable-hdpi/ic_subtype_mic_dark.png b/java/res/drawable-hdpi/ic_subtype_mic_dark.png Binary files differnew file mode 100644 index 000000000..eacbcd255 --- /dev/null +++ b/java/res/drawable-hdpi/ic_subtype_mic_dark.png diff --git a/java/res/drawable-hdpi/keyboard_background_ics.9.png b/java/res/drawable-hdpi/keyboard_background_holo.9.png Binary files differindex 73868751c..73868751c 100644 --- a/java/res/drawable-hdpi/keyboard_background_ics.9.png +++ b/java/res/drawable-hdpi/keyboard_background_holo.9.png 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 diff --git a/java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.png b/java/res/drawable-hdpi/keyboard_suggest_strip_holo.9.png Binary files differindex 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 diff --git a/java/res/drawable-hdpi/sym_keyboard_delete.png b/java/res/drawable-hdpi/sym_keyboard_delete.png Binary files differdeleted file mode 100644 index 0591b82cd..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_delete.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_delete_holo.png b/java/res/drawable-hdpi/sym_keyboard_delete_holo.png Binary files differdeleted file mode 100644 index d3e108846..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_delete_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_delete_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_delete_holo_dark.png Binary files differnew file mode 100644 index 000000000..d2d3560a3 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_delete_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_label_mic.png b/java/res/drawable-hdpi/sym_keyboard_label_mic.png Binary files differdeleted file mode 100644 index 4e0a8ed8e..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_label_mic.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-hdpi/sym_keyboard_label_mic_holo.png Binary files differdeleted file mode 100644 index f8df44741..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_label_mic_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_language_switch.png b/java/res/drawable-hdpi/sym_keyboard_language_switch.png Binary files differdeleted file mode 100644 index 7b980a0c8..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_language_switch.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_language_switch_dark.png b/java/res/drawable-hdpi/sym_keyboard_language_switch_dark.png Binary files differnew file mode 100644 index 000000000..78d3a1fc5 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_language_switch_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_mic.png b/java/res/drawable-hdpi/sym_keyboard_mic.png Binary files differdeleted file mode 100644 index 520a40f09..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_mic.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.png Binary files differnew file mode 100644 index 000000000..3c5469403 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_return.png b/java/res/drawable-hdpi/sym_keyboard_return.png Binary files differdeleted file mode 100644 index 9743c7f2f..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_return.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_return_holo.png b/java/res/drawable-hdpi/sym_keyboard_return_holo.png Binary files differdeleted file mode 100644 index 8978934b8..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_return_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_return_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_return_holo_dark.png Binary files differnew file mode 100644 index 000000000..60d893cf3 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_return_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_search.png b/java/res/drawable-hdpi/sym_keyboard_search.png Binary files differdeleted file mode 100644 index 8cd28c64a..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_search.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_search_holo.png b/java/res/drawable-hdpi/sym_keyboard_search_holo.png Binary files differdeleted file mode 100644 index b987a20f1..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_search_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_search_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_search_holo_dark.png Binary files differnew file mode 100644 index 000000000..fa0d1bde1 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_search_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_settings.png b/java/res/drawable-hdpi/sym_keyboard_settings.png Binary files differdeleted file mode 100644 index 1e5bf939e..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_settings.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_settings_holo.png b/java/res/drawable-hdpi/sym_keyboard_settings_holo.png Binary files differdeleted file mode 100644 index 5af09ad8c..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_settings_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_settings_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_settings_holo_dark.png Binary files differnew file mode 100644 index 000000000..c76008ab3 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_settings_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_shift.png b/java/res/drawable-hdpi/sym_keyboard_shift.png Binary files differdeleted file mode 100644 index 8e3d0320c..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_shift.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_holo.png b/java/res/drawable-hdpi/sym_keyboard_shift_holo.png Binary files differdeleted file mode 100644 index c58f9ab5c..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_shift_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_shift_holo_dark.png Binary files differnew file mode 100644 index 000000000..544b7e141 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_shift_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_locked.png b/java/res/drawable-hdpi/sym_keyboard_shift_locked.png Binary files differdeleted file mode 100644 index d345634a6..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_shift_locked.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.png Binary files differdeleted file mode 100644 index 7a5c03713..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..9b1d6a015 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_shift_locked_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_space_holo.png b/java/res/drawable-hdpi/sym_keyboard_space_holo.png Binary files differdeleted file mode 100644 index e8bc3902d..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_space_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_space_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_space_holo_dark.png Binary files differnew file mode 100644 index 000000000..12e27ade7 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_space_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_tab.png b/java/res/drawable-hdpi/sym_keyboard_tab.png Binary files differdeleted file mode 100644 index 3d1c5c0ea..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_tab.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_tab_holo.png b/java/res/drawable-hdpi/sym_keyboard_tab_holo.png Binary files differdeleted file mode 100644 index 8d10d057c..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_tab_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_tab_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_tab_holo_dark.png Binary files differnew file mode 100644 index 000000000..2e5f811f3 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_tab_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_holo.png b/java/res/drawable-hdpi/sym_keyboard_voice_holo.png Binary files differdeleted file mode 100644 index 8a6336a57..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_voice_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.png Binary files differnew file mode 100644 index 000000000..c1e16a651 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_voice_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-hdpi/sym_keyboard_voice_off_holo.png Binary files differdeleted file mode 100644 index edf1379ab..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_voice_off_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..26d068490 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_voice_off_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-hdpi/sym_keyboard_zwj_holo.png Binary files differdeleted file mode 100644 index 5fa30ceb8..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_zwj_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_zwj_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_zwj_holo_dark.png Binary files differnew file mode 100644 index 000000000..9f9bc173b --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_zwj_holo_dark.png diff --git a/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png Binary files differdeleted file mode 100644 index 91367f3d2..000000000 --- a/java/res/drawable-hdpi/sym_keyboard_zwnj_holo.png +++ /dev/null diff --git a/java/res/drawable-hdpi/sym_keyboard_zwnj_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_zwnj_holo_dark.png Binary files differnew file mode 100644 index 000000000..f0f832e13 --- /dev/null +++ b/java/res/drawable-hdpi/sym_keyboard_zwnj_holo_dark.png 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 diff --git a/java/res/drawable-mdpi/ic_emoji_light.png b/java/res/drawable-mdpi/ic_emoji_light.png Binary files differdeleted file mode 100644 index a3195041a..000000000 --- a/java/res/drawable-mdpi/ic_emoji_light.png +++ /dev/null diff --git a/java/res/drawable-mdpi/ic_ime_light.png b/java/res/drawable-mdpi/ic_ime_light.png Binary files differdeleted file mode 100644 index d94ad6f7e..000000000 --- a/java/res/drawable-mdpi/ic_ime_light.png +++ /dev/null diff --git a/java/res/drawable-mdpi/ic_ime_switcher_dark.png b/java/res/drawable-mdpi/ic_ime_switcher_dark.png Binary files differnew file mode 100644 index 000000000..152f65300 --- /dev/null +++ b/java/res/drawable-mdpi/ic_ime_switcher_dark.png diff --git a/java/res/drawable-mdpi/ic_subtype_keyboard.png b/java/res/drawable-mdpi/ic_subtype_keyboard.png Binary files differdeleted file mode 100644 index d28efc106..000000000 --- a/java/res/drawable-mdpi/ic_subtype_keyboard.png +++ /dev/null diff --git a/java/res/drawable-mdpi/keyboard_background_ics.9.png b/java/res/drawable-mdpi/keyboard_background_holo.9.png Binary files differindex fbe97f7a2..fbe97f7a2 100644 --- a/java/res/drawable-mdpi/keyboard_background_ics.9.png +++ b/java/res/drawable-mdpi/keyboard_background_holo.9.png 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 diff --git a/java/res/drawable-mdpi/suggestions_strip_divider.png b/java/res/drawable-mdpi/suggestions_strip_divider.png Binary files differindex 2dbe2f94b..21e904939 100644 --- a/java/res/drawable-mdpi/suggestions_strip_divider.png +++ b/java/res/drawable-mdpi/suggestions_strip_divider.png diff --git a/java/res/drawable-mdpi/sym_keyboard_delete.png b/java/res/drawable-mdpi/sym_keyboard_delete.png Binary files differdeleted file mode 100644 index 1b0f3f836..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_delete.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_delete_holo.png b/java/res/drawable-mdpi/sym_keyboard_delete_holo.png Binary files differdeleted file mode 100644 index 86be35185..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_delete_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_delete_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_delete_holo_dark.png Binary files differnew file mode 100644 index 000000000..edd9d164e --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_delete_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_label_mic.png b/java/res/drawable-mdpi/sym_keyboard_label_mic.png Binary files differdeleted file mode 100644 index a354d5321..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_label_mic.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-mdpi/sym_keyboard_label_mic_holo.png Binary files differdeleted file mode 100644 index 15606e95f..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_label_mic_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..537f39b02 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_label_mic_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_language_switch.png b/java/res/drawable-mdpi/sym_keyboard_language_switch.png Binary files differdeleted file mode 100644 index f840a631d..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_language_switch.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_language_switch_dark.png b/java/res/drawable-mdpi/sym_keyboard_language_switch_dark.png Binary files differnew file mode 100644 index 000000000..828929bc8 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_language_switch_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_mic.png b/java/res/drawable-mdpi/sym_keyboard_mic.png Binary files differdeleted file mode 100644 index e926b3fa6..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_mic.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.png Binary files differnew file mode 100644 index 000000000..5e58866a7 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_mic_holo_light.png b/java/res/drawable-mdpi/sym_keyboard_mic_holo_light.png Binary files differnew file mode 100644 index 000000000..84a63dc7f --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_mic_holo_light.png diff --git a/java/res/drawable-mdpi/sym_keyboard_return.png b/java/res/drawable-mdpi/sym_keyboard_return.png Binary files differdeleted file mode 100644 index 0c10f004a..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_return.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_return_holo.png b/java/res/drawable-mdpi/sym_keyboard_return_holo.png Binary files differdeleted file mode 100644 index bfcb91328..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_return_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_return_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_return_holo_dark.png Binary files differnew file mode 100644 index 000000000..e10103caf --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_return_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_search.png b/java/res/drawable-mdpi/sym_keyboard_search.png Binary files differdeleted file mode 100644 index 614f85f5e..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_search.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_search_holo.png b/java/res/drawable-mdpi/sym_keyboard_search_holo.png Binary files differdeleted file mode 100644 index dd3c83a84..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_search_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_search_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_search_holo_dark.png Binary files differnew file mode 100644 index 000000000..290cde41b --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_search_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_settings.png b/java/res/drawable-mdpi/sym_keyboard_settings.png Binary files differdeleted file mode 100644 index ad7618fa0..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_settings.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_settings_holo.png b/java/res/drawable-mdpi/sym_keyboard_settings_holo.png Binary files differdeleted file mode 100644 index 36c8c9623..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_settings_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_settings_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_settings_holo_dark.png Binary files differnew file mode 100644 index 000000000..a76a976c5 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_settings_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_shift.png b/java/res/drawable-mdpi/sym_keyboard_shift.png Binary files differdeleted file mode 100644 index 5109b0471..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_shift.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_holo.png b/java/res/drawable-mdpi/sym_keyboard_shift_holo.png Binary files differdeleted file mode 100644 index 621946455..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_shift_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_shift_holo_dark.png Binary files differnew file mode 100644 index 000000000..37375d935 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_shift_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_locked.png b/java/res/drawable-mdpi/sym_keyboard_shift_locked.png Binary files differdeleted file mode 100644 index 244179c2d..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_shift_locked.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.png Binary files differdeleted file mode 100644 index fb3a020d8..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..3654868dc --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_shift_locked_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_smiley_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_smiley_holo_dark.png Binary files differnew file mode 100644 index 000000000..71272bb88 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_smiley_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_space_holo.png b/java/res/drawable-mdpi/sym_keyboard_space_holo.png Binary files differdeleted file mode 100644 index 1f787d573..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_space_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_space_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_space_holo_dark.png Binary files differnew file mode 100644 index 000000000..a38f99496 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_space_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_tab.png b/java/res/drawable-mdpi/sym_keyboard_tab.png Binary files differdeleted file mode 100644 index eddb9a592..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_tab.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_tab_holo.png b/java/res/drawable-mdpi/sym_keyboard_tab_holo.png Binary files differdeleted file mode 100644 index 8d20153ee..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_tab_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_tab_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_tab_holo_dark.png Binary files differnew file mode 100644 index 000000000..f883807f2 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_tab_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_holo.png b/java/res/drawable-mdpi/sym_keyboard_voice_holo.png Binary files differdeleted file mode 100644 index 0795fcc9b..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_voice_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.png Binary files differnew file mode 100644 index 000000000..16be37d05 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_voice_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-mdpi/sym_keyboard_voice_off_holo.png Binary files differdeleted file mode 100644 index f76da5797..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_voice_off_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..95d718a46 --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_voice_off_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png Binary files differdeleted file mode 100644 index 70370d83d..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_zwj_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_zwj_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_zwj_holo_dark.png Binary files differnew file mode 100644 index 000000000..8957e282b --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_zwj_holo_dark.png diff --git a/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png Binary files differdeleted file mode 100644 index a69eade17..000000000 --- a/java/res/drawable-mdpi/sym_keyboard_zwnj_holo.png +++ /dev/null diff --git a/java/res/drawable-mdpi/sym_keyboard_zwnj_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_zwnj_holo_dark.png Binary files differnew file mode 100644 index 000000000..5f49e64aa --- /dev/null +++ b/java/res/drawable-mdpi/sym_keyboard_zwnj_holo_dark.png 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 diff --git a/java/res/drawable-xhdpi/ic_emoji_light.png b/java/res/drawable-xhdpi/ic_emoji_light.png Binary files differdeleted file mode 100644 index 21bc9090d..000000000 --- a/java/res/drawable-xhdpi/ic_emoji_light.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/ic_ime_light.png b/java/res/drawable-xhdpi/ic_ime_light.png Binary files differdeleted file mode 100644 index 9d2caeda6..000000000 --- a/java/res/drawable-xhdpi/ic_ime_light.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/ic_ime_switcher_dark.png b/java/res/drawable-xhdpi/ic_ime_switcher_dark.png Binary files differnew file mode 100644 index 000000000..c567077e5 --- /dev/null +++ b/java/res/drawable-xhdpi/ic_ime_switcher_dark.png diff --git a/java/res/drawable-xhdpi/ic_subtype_keyboard.png b/java/res/drawable-xhdpi/ic_subtype_keyboard.png Binary files differdeleted file mode 100644 index a79bb3458..000000000 --- a/java/res/drawable-xhdpi/ic_subtype_keyboard.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/ic_subtype_mic_dark.png b/java/res/drawable-xhdpi/ic_subtype_mic_dark.png Binary files differnew file mode 100644 index 000000000..17581ba89 --- /dev/null +++ b/java/res/drawable-xhdpi/ic_subtype_mic_dark.png diff --git a/java/res/drawable-xhdpi/keyboard_background_ics.9.png b/java/res/drawable-xhdpi/keyboard_background_holo.9.png Binary files differindex f5c9df3e5..f5c9df3e5 100644 --- a/java/res/drawable-xhdpi/keyboard_background_ics.9.png +++ b/java/res/drawable-xhdpi/keyboard_background_holo.9.png 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 diff --git a/java/res/drawable-xhdpi/suggestions_strip_divider.png b/java/res/drawable-xhdpi/suggestions_strip_divider.png Binary files differindex 0d8b98437..4101ebc59 100644 --- a/java/res/drawable-xhdpi/suggestions_strip_divider.png +++ b/java/res/drawable-xhdpi/suggestions_strip_divider.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_delete.png b/java/res/drawable-xhdpi/sym_keyboard_delete.png Binary files differdeleted file mode 100644 index 3c0b8b186..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_delete.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_delete_holo.png b/java/res/drawable-xhdpi/sym_keyboard_delete_holo.png Binary files differdeleted file mode 100644 index 354c09ee6..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_delete_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_delete_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_delete_holo_dark.png Binary files differnew file mode 100644 index 000000000..e3e37d5ff --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_delete_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_label_mic.png b/java/res/drawable-xhdpi/sym_keyboard_label_mic.png Binary files differdeleted file mode 100644 index 49810a02f..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_label_mic.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-xhdpi/sym_keyboard_label_mic_holo.png Binary files differdeleted file mode 100644 index 8eeb179f5..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_label_mic_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_language_switch.png b/java/res/drawable-xhdpi/sym_keyboard_language_switch.png Binary files differdeleted file mode 100644 index 6c2fb53ec..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_language_switch.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_language_switch_dark.png b/java/res/drawable-xhdpi/sym_keyboard_language_switch_dark.png Binary files differnew file mode 100644 index 000000000..b8687f550 --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_language_switch_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_mic.png b/java/res/drawable-xhdpi/sym_keyboard_mic.png Binary files differdeleted file mode 100644 index 1323b6d1e..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_mic.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.png Binary files differnew file mode 100644 index 000000000..566ba1fcd --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_return.png b/java/res/drawable-xhdpi/sym_keyboard_return.png Binary files differdeleted file mode 100644 index ad061227e..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_return.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_return_holo.png b/java/res/drawable-xhdpi/sym_keyboard_return_holo.png Binary files differdeleted file mode 100644 index ba424adfd..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_return_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_return_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_return_holo_dark.png Binary files differnew file mode 100644 index 000000000..7b7ad1747 --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_return_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_search.png b/java/res/drawable-xhdpi/sym_keyboard_search.png Binary files differdeleted file mode 100644 index aa785a221..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_search.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_search_holo.png b/java/res/drawable-xhdpi/sym_keyboard_search_holo.png Binary files differdeleted file mode 100644 index f2fb2a2b5..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_search_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_search_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_search_holo_dark.png Binary files differnew file mode 100644 index 000000000..36b1646bb --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_search_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_settings.png b/java/res/drawable-xhdpi/sym_keyboard_settings.png Binary files differdeleted file mode 100644 index 50704255d..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_settings.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_settings_holo.png b/java/res/drawable-xhdpi/sym_keyboard_settings_holo.png Binary files differdeleted file mode 100644 index 99ee97dbf..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_settings_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_settings_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_settings_holo_dark.png Binary files differnew file mode 100644 index 000000000..05eaffe2e --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_settings_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift.png b/java/res/drawable-xhdpi/sym_keyboard_shift.png Binary files differdeleted file mode 100644 index 290170619..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_shift.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_holo.png b/java/res/drawable-xhdpi/sym_keyboard_shift_holo.png Binary files differdeleted file mode 100644 index 1046b4545..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_shift_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_shift_holo_dark.png Binary files differnew file mode 100644 index 000000000..5ab549114 --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_shift_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_locked.png b/java/res/drawable-xhdpi/sym_keyboard_shift_locked.png Binary files differdeleted file mode 100644 index a5deb60e9..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_shift_locked.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.png Binary files differdeleted file mode 100644 index 6acb565d9..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..b820eaabb --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_shift_locked_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_smiley_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_smiley_holo_dark.png Binary files differnew file mode 100644 index 000000000..686831fd3 --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_smiley_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_space_holo.png b/java/res/drawable-xhdpi/sym_keyboard_space_holo.png Binary files differdeleted file mode 100644 index 504a3ed45..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_space_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_space_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_space_holo_dark.png Binary files differnew file mode 100644 index 000000000..7114b740f --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_space_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_tab.png b/java/res/drawable-xhdpi/sym_keyboard_tab.png Binary files differdeleted file mode 100644 index 0ef2ab5b9..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_tab.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_tab_holo.png b/java/res/drawable-xhdpi/sym_keyboard_tab_holo.png Binary files differdeleted file mode 100644 index ff380eeab..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_tab_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_tab_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_tab_holo_dark.png Binary files differnew file mode 100644 index 000000000..73ebfe525 --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_tab_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_holo.png b/java/res/drawable-xhdpi/sym_keyboard_voice_holo.png Binary files differdeleted file mode 100644 index b2bb9b803..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_voice_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.png Binary files differnew file mode 100644 index 000000000..944a8524d --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_voice_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.png Binary files differdeleted file mode 100644 index 23e75bfe7..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..2016caf40 --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_voice_off_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png Binary files differdeleted file mode 100644 index 26694274e..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_zwj_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwj_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_zwj_holo_dark.png Binary files differnew file mode 100644 index 000000000..2f9607add --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_zwj_holo_dark.png diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png Binary files differdeleted file mode 100644 index 75a22b65f..000000000 --- a/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo.png +++ /dev/null diff --git a/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo_dark.png Binary files differnew file mode 100644 index 000000000..ab07f7549 --- /dev/null +++ b/java/res/drawable-xhdpi/sym_keyboard_zwnj_holo_dark.png 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 diff --git a/java/res/drawable-xxhdpi/ic_emoji_light.png b/java/res/drawable-xxhdpi/ic_emoji_light.png Binary files differdeleted file mode 100644 index 7480e5294..000000000 --- a/java/res/drawable-xxhdpi/ic_emoji_light.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/ic_ime_light.png b/java/res/drawable-xxhdpi/ic_ime_light.png Binary files differdeleted file mode 100644 index 0309635d2..000000000 --- a/java/res/drawable-xxhdpi/ic_ime_light.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/ic_ime_switcher_dark.png b/java/res/drawable-xxhdpi/ic_ime_switcher_dark.png Binary files differnew file mode 100644 index 000000000..f99f7d0c7 --- /dev/null +++ b/java/res/drawable-xxhdpi/ic_ime_switcher_dark.png diff --git a/java/res/drawable-xxhdpi/ic_subtype_keyboard.png b/java/res/drawable-xxhdpi/ic_subtype_keyboard.png Binary files differdeleted file mode 100644 index 0bb4283b0..000000000 --- a/java/res/drawable-xxhdpi/ic_subtype_keyboard.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/ic_subtype_mic_dark.png b/java/res/drawable-xxhdpi/ic_subtype_mic_dark.png Binary files differnew file mode 100644 index 000000000..811103a56 --- /dev/null +++ b/java/res/drawable-xxhdpi/ic_subtype_mic_dark.png diff --git a/java/res/drawable-xxhdpi/keyboard_background_ics.9.png b/java/res/drawable-xxhdpi/keyboard_background_holo.9.png Binary files differindex bcef0f839..bcef0f839 100644 --- a/java/res/drawable-xxhdpi/keyboard_background_ics.9.png +++ b/java/res/drawable-xxhdpi/keyboard_background_holo.9.png 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 diff --git a/java/res/drawable-xxhdpi/sym_keyboard_delete_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_delete_holo.png Binary files differdeleted file mode 100644 index be3cb7ce7..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_delete_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_delete_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_delete_holo_dark.png Binary files differnew file mode 100644 index 000000000..92be79241 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_delete_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_label_mic_holo.png Binary files differdeleted file mode 100644 index b6d4477bd..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_label_mic_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_language_switch.png b/java/res/drawable-xxhdpi/sym_keyboard_language_switch.png Binary files differdeleted file mode 100644 index 7cd0684a0..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_language_switch.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_language_switch_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_language_switch_dark.png Binary files differnew file mode 100644 index 000000000..88b55bb37 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_language_switch_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.png Binary files differnew file mode 100644 index 000000000..f55af308c --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_return_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_return_holo.png Binary files differdeleted file mode 100644 index 7d9580796..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_return_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_return_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_return_holo_dark.png Binary files differnew file mode 100644 index 000000000..46ee50eba --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_return_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_search_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_search_holo.png Binary files differdeleted file mode 100644 index 6b09d8e57..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_search_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_search_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_search_holo_dark.png Binary files differnew file mode 100644 index 000000000..f518748ce --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_search_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_settings_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_settings_holo.png Binary files differdeleted file mode 100644 index 7041bb6ce..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_settings_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_settings_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_settings_holo_dark.png Binary files differnew file mode 100644 index 000000000..e4358463b --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_settings_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_shift_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_shift_holo.png Binary files differdeleted file mode 100644 index 2b4fbbba6..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_shift_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_shift_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_shift_holo_dark.png Binary files differnew file mode 100644 index 000000000..523286e6e --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_shift_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo.png Binary files differdeleted file mode 100644 index 91c8603fd..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..87926d9a6 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_smiley_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_smiley_holo_dark.png Binary files differnew file mode 100644 index 000000000..04b721617 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_smiley_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_space_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_space_holo.png Binary files differdeleted file mode 100644 index 65aa5ea9b..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_space_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_space_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_space_holo_dark.png Binary files differnew file mode 100644 index 000000000..1dab1f431 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_space_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_tab_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_tab_holo.png Binary files differdeleted file mode 100644 index 1f4ae3df7..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_tab_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_tab_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_tab_holo_dark.png Binary files differnew file mode 100644 index 000000000..6eb3eb0b3 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_tab_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_holo.png Binary files differdeleted file mode 100644 index f04cadf6f..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_voice_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.png Binary files differnew file mode 100644 index 000000000..6809f0711 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_voice_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo.png Binary files differdeleted file mode 100644 index e74d523bc..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo.png +++ /dev/null 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 Binary files differnew file mode 100644 index 000000000..6bd506a11 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_voice_off_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo.png Binary files differdeleted file mode 100644 index 85289b2a3..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo_dark.png Binary files differnew file mode 100644 index 000000000..5e225b837 --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_zwj_holo_dark.png diff --git a/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo.png b/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo.png Binary files differdeleted file mode 100644 index e610678b1..000000000 --- a/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo.png +++ /dev/null diff --git a/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo_dark.png Binary files differnew file mode 100644 index 000000000..cdfc0295b --- /dev/null +++ b/java/res/drawable-xxhdpi/sym_keyboard_zwnj_holo_dark.png 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">.,;:!?)]}&։՝</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">"	 \n"()[]{}*&<>+=|.,;:!?/_\"։՝</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="։" + latin:keyLabelFlags="hasPopupHint" + latin:backgroundType="functional" + latin:moreKeys="!text/more_keys_for_punctuation" /> + <!-- U+055D: "՝" ARMENIAN COMMA --> + <Key + latin:keyLabel="՝" + 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="։" + 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|‍" /> + <!-- U+17D7: "ៗ" KHMER SIGN LEK TOO + U+200C: ZERO WIDTH NON-JOINER --> + <Key + latin:keyLabel="ៗ" + latin:moreKeys="!icon/zwnj_key|‌" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17D1: "៑" KHMER SIGN VIRIAM --> + <Key + latin:keyLabel=""" + latin:keyHintLabel="៑" + latin:moreKeys="៑" /> + <!-- U+17DB: "៛" KHMER CURRENCY SYMBOL RIEL + U+20AC: "€" EURO SIGN --> + <Key + latin:keyLabel="៛" + latin:keyHintLabel="$" + latin:moreKeys="$,€" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17D6: "៖" KHMER SIGN CAMNUC PII KUUH --> + <Key + latin:keyLabel="%" + latin:keyHintLabel="៖" + latin:moreKeys="៖" /> + <!-- U+17CD: "៍" KHMER SIGN TOANDAKHIAT + U+17D9: "៙" KHMER SIGN PHNAEK MUAN --> + <Key + latin:keyLabel="៍" + latin:keyHintLabel="៙" + latin:moreKeys="៙" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17D0: "័" KHMER SIGN SAMYOK SANNYA + U+17DA: "៚" KHMER SIGN KOOMUUT --> + <Key + latin:keyLabel="័" + latin:keyHintLabel="៚" + latin:moreKeys="៚" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17CF: "៏" KHMER SIGN AHSDA --> + <Key + latin:keyLabel="៏" + latin:keyHintLabel="*" + latin:moreKeys="*" + latin:keyLabelFlags="fontNormal" /> + <!-- U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK --> + <Key + latin:keyLabel="(" + latin:keyHintLabel="{" + latin:moreKeys="{,«" /> + <!-- U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK --> + <Key + latin:keyLabel=")" + latin:keyHintLabel="}" + latin:moreKeys="},»" /> + <!-- U+17CC: "៌" KHMER SIGN ROBAT + U+00D7: "×" MULTIPLICATION SIGN --> + <Key + latin:keyLabel="៌" + latin:keyHintLabel="×" + latin:moreKeys="×" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17CE: "៎" KHMER SIGN KAKABAT --> + <Key + latin:keyLabel="៎" + latin:keyLabelFlags="fontNormal" /> + </case> + <default> + <!-- U+17E1: "១" KHMER DIGIT ONE + U+17F1: "៱" KHMER SYMBOL LEK ATTAK MUOY --> + <Key + latin:keyLabel="១" + latin:keyHintLabel="1" + latin:additionalMoreKeys="1" + latin:moreKeys="៱" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E2: "២" KHMER DIGIT TWO + U+17F2: "៲" KHMER SYMBOL LEK ATTAK PII --> + <Key + latin:keyLabel="២" + latin:keyHintLabel="2" + latin:additionalMoreKeys="2" + latin:moreKeys="៲" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E3: "៣" KHMER DIGIT THREE + U+17F3: "៳" KHMER SYMBOL LEK ATTAK BEI --> + <Key + latin:keyLabel="៣" + latin:keyHintLabel="3" + latin:additionalMoreKeys="3" + latin:moreKeys="៳" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E4: "៤" KHMER DIGIT FOUR + U+17F4: "៴" KHMER SYMBOL LEK ATTAK BUON --> + <Key + latin:keyLabel="៤" + latin:keyHintLabel="4" + latin:additionalMoreKeys="4" + latin:moreKeys="៴" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E5: "៥" KHMER DIGIT FIVE + U+17F5: "៵" KHMER SYMBOL LEK ATTAK PRAM --> + <Key + latin:keyLabel="៥" + latin:keyHintLabel="5" + latin:additionalMoreKeys="5" + latin:moreKeys="៵" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E6: "៦" KHMER DIGIT SIX + U+17F6: "៶" KHMER SYMBOL LEK ATTAK PRAM-MUOY --> + <Key + latin:keyLabel="៦" + latin:keyHintLabel="6" + latin:additionalMoreKeys="6" + latin:moreKeys="៶" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E7: "៧" KHMER DIGIT SEVEN + U+17F7: "៷" KHMER SYMBOL LEK ATTAK PRAM-PII --> + <Key + latin:keyLabel="៧" + latin:keyHintLabel="7" + latin:additionalMoreKeys="7" + latin:moreKeys="៷" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E8: "៨" KHMER DIGIT EIGHT + U+17F8: "៸" KHMER SYMBOL LEK ATTAK PRAM-BEI --> + <Key + latin:keyLabel="៨" + latin:keyHintLabel="8" + latin:additionalMoreKeys="8" + latin:moreKeys="៸" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E9: "៩" KHMER DIGIT NINE + U+17F9: "៹" KHMER SYMBOL LEK ATTAK PRAM-BUON --> + <Key + latin:keyLabel="៩" + latin:keyHintLabel="9" + latin:additionalMoreKeys="9" + latin:moreKeys="៹" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17E0: "០" KHMER DIGIT ZERO + U+17F0: "៰" KHMER SYMBOL LEK ATTAK SON --> + <Key + latin:keyLabel="០" + latin:keyHintLabel="0" + latin:additionalMoreKeys="0" + latin:moreKeys="៰" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17A5: "ឥ" KHMER INDEPENDENT VOWEL QI + U+17A6: "ឦ" KHMER INDEPENDENT VOWEL QII --> + <Key + latin:keyLabel="ឥ" + latin:keyHintLabel="ឦ" + latin:moreKeys=",ឦ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17B2: "ឲ" KHMER INDEPENDENT VOWEL QOO TYPE TWO + U+17B1: "ឱ" KHMER INDEPENDENT VOWEL QOO TYPE ONE --> + <Key + latin:keyLabel="ឲ" + latin:keyHintLabel="ឱ" + latin:moreKeys="ឱ" + 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="ឈ" + latin:keyHintLabel="ៜ" + latin:moreKeys="ៜ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17BA: "ឺ" KHMER VOWEL SIGN YY + U+17DD: "៝" KHMER SIGN ATTHACAN --> + <Key + latin:keyLabel="ឺ" + latin:keyHintLabel="៝" + latin:moreKeys="៝" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C2: "ែ" KHMER VOWEL SIGN AE --> + <Key + latin:keyLabel="ែ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17AC: "ឬ" KHMER INDEPENDENT VOWEL RYY + U+17AB: "ឫ" KHMER INDEPENDENT VOWEL RY --> + <Key + latin:keyLabel="ឬ" + latin:keyHintLabel="ឫ" + latin:moreKeys="ឫ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1791: "ទ" KHMER LETTER TO --> + <Key + latin:keyLabel="ទ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17BD: "ួ" KHMER VOWEL SIGN UA --> + <Key + latin:keyLabel="ួ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17BC: "ូ" KHMER VOWEL SIGN UU --> + <Key + latin:keyLabel="ូ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17B8: "ី" KHMER VOWEL SIGN II --> + <Key + latin:keyLabel="ី" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C5: "ៅ" KHMER VOWEL SIGN AU --> + <Key + latin:keyLabel="ៅ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1797: "ភ" KHMER LETTER PHO --> + <Key + latin:keyLabel="ភ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17BF: "ឿ" KHMER VOWEL SIGN YA --> + <Key + latin:keyLabel="ឿ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17B0: "ឰ" KHMER INDEPENDENT VOWEL QAI --> + <Key + latin:keyLabel="ឰ" + latin:keyLabelFlags="fontNormal" /> + </case> + <default> + <!-- U+1786: "ឆ" KHMER LETTER CHA --> + <Key + latin:keyLabel="ឆ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17B9: "ឹ" KHMER VOWEL SIGN Y --> + <Key + latin:keyLabel="ឹ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C1: "េ" KHMER VOWEL SIGN E --> + <Key + latin:keyLabel="េ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+179A: "រ" KHMER LETTER RO --> + <Key + latin:keyLabel="រ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+178F: "ត" KHMER LETTER TA --> + <Key + latin:keyLabel="ត" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1799: "យ" KHMER LETTER YO --> + <Key + latin:keyLabel="យ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17BB: "ុ" KHMER VOWEL SIGN U --> + <Key + latin:keyLabel="ុ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17B7: "ិ" KHMER VOWEL SIGN I --> + <Key + latin:keyLabel="ិ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C4: "ោ" KHMER VOWEL SIGN OO --> + <Key + latin:keyLabel="ោ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1795: "ផ" KHMER LETTER PHA --> + <Key + latin:keyLabel="ផ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C0: "ៀ" KHMER VOWEL SIGN IE --> + <Key + latin:keyLabel="ៀ" + 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="ឪ" + latin:keyHintLabel="ឧ" + latin:moreKeys="ឧ,ឱ,ឳ,ឩ,ឨ" + 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="ាំ" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+17C3: "ៃ" KHMER VOWEL SIGN AI --> + <Key + latin:keyLabel="ៃ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+178C: "ឌ" KHMER LETTER DO --> + <Key + latin:keyLabel="ឌ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1792: "ធ" KHMER LETTER THO --> + <Key + latin:keyLabel="ធ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17A2: "អ" KHMER LETTER QA --> + <Key + latin:keyLabel="អ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C7: "ះ" KHMER SIGN REAHMUK + U+17C8: "ៈ" KHMER SIGN YUUKALEAPINTU;--> + <Key + latin:keyLabel="ះ" + latin:keyHintLabel="ៈ" + latin:moreKeys="ៈ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1789: "ញ" KHMER LETTER NYO --> + <Key + latin:keyLabel="ញ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1782: "គ" KHMER LETTER KO + U+179D: "ឝ" KHMER LETTER SHA --> + <Key + latin:keyLabel="គ" + latin:keyHintLabel="ឝ" + latin:moreKeys="ឝ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17A1: "ឡ" KHMER LETTER LA --> + <Key + latin:keyLabel="ឡ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C4/U+17C7: "ោះ" KHMER VOWEL SIGN OO/KHMER SIGN REAHMUK --> + <Key + latin:keyLabel="ោះ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C9: "៉" KHMER SIGN MUUSIKATOAN --> + <Key + latin:keyLabel="៉" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17AF: "ឯ" KHMER INDEPENDENT VOWEL QE --> + <Key + latin:keyLabel="ឯ" + latin:keyLabelFlags="fontNormal" /> + </case> + <default> + <!-- U+17B6: "ា" KHMER VOWEL SIGN AA --> + <Key + latin:keyLabel="ា" + latin:keyLabelFlags="fontNormal" /> + <!-- U+179F: "ស" KHMER LETTER SA --> + <Key + latin:keyLabel="ស" + latin:keyLabelFlags="fontNormal" /> + <!-- U+178A: "ដ" KHMER LETTER DA --> + <Key + latin:keyLabel="ដ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1790: "ថ" KHMER LETTER THA --> + <Key + latin:keyLabel="ថ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1784: "ង" KHMER LETTER NGO --> + <Key + latin:keyLabel="ង" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17A0: "ហ" KHMER LETTER HA --> + <Key + latin:keyLabel="ហ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17D2: "្" KHMER SIGN COENG --> + <Key + latin:keyLabel="្" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1780: "ក" KHMER LETTER KA --> + <Key + latin:keyLabel="ក" + latin:keyLabelFlags="fontNormal" /> + <!-- U+179B: "ល" KHMER LETTER LO --> + <Key + latin:keyLabel="ល" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17BE: "ើ" KHMER VOWEL SIGN OE --> + <Key + latin:keyLabel="ើ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17CB: "់" KHMER SIGN BANTOC --> + <Key + latin:keyLabel="់" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17AE: "ឮ" KHMER INDEPENDENT VOWEL LYY + U+17AD: "ឭ" KHMER INDEPENDENT VOWEL LY + U+17B0: "ឰ" KHMER INDEPENDENT VOWEL QAI --> + <Key + latin:keyLabel="ឮ" + latin:keyHintLabel="ឭ" + latin:moreKeys="ឭ,ឰ" + 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="ឍ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1783: "ឃ" KHMER LETTER KHO --> + <Key + latin:keyLabel="ឃ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1787: "ជ" KHMER LETTER CO --> + <Key + latin:keyLabel="ជ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C1/U+17C7: "េះ" KHMER VOWEL SIGN E/KHMER SIGN REAHMUK --> + <Key + latin:keyLabel="េះ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1796: "ព" KHMER LETTER PO + U+179E: "ឞ" KHMER LETTER SSO --> + <Key + latin:keyLabel="ព" + latin:keyHintLabel="ឞ" + latin:moreKeys="ឞ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+178E: "ណ" KHMER LETTER NNO --> + <Key + latin:keyLabel="ណ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17C6: "ំ" KHMER SIGN NIKAHIT --> + <Key + latin:keyLabel="ំ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17BB/U+17C7: "ុះ" KHMER VOWEL SIGN U/KHMER SIGN REAHMUK --> + <Key + latin:keyLabel="ុះ" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+17D5: "៕" KHMER SIGN BARIYOOSAN --> + <Key + latin:keyLabel="៕" + latin:keyLabelFlags="fontNormal" /> + <Key + latin:keyLabel="\?" /> + </case> + <default> + <!-- U+178B: "ឋ" KHMER LETTER TTHA --> + <Key + latin:keyLabel="ឋ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1781: "ខ" KHMER LETTER KHA --> + <Key + latin:keyLabel="ខ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1785: "ច" KHMER LETTER CA --> + <Key + latin:keyLabel="ច" + latin:keyLabelFlags="fontNormal" /> + <!-- U+179C: "វ" KHMER LETTER VO --> + <Key + latin:keyLabel="វ" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1794: "ប" KHMER LETTER BA --> + <Key + latin:keyLabel="ប" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1793: "ន" KHMER LETTER NO --> + <Key + latin:keyLabel="ន" + latin:keyLabelFlags="fontNormal" /> + <!-- U+1798: "ម" KHMER LETTER MO --> + <Key + latin:keyLabel="ម" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17BB/U+17C6: "ុំ" KHMER VOWEL SIGN U/KHMER SIGN NIKAHIT --> + <Key + latin:keyLabel="ុំ" + latin:keyLabelFlags="fontNormal|followKeyLetterRatio" /> + <!-- U+17D4: "។" KHMER SIGN KHAN --> + <Key + latin:keyLabel="។" + latin:keyLabelFlags="fontNormal" /> + <!-- U+17CA: "៊" KHMER SIGN TRIISAP --> + <Key + latin:keyLabel="៊" + 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(); |