diff options
27 files changed, 525 insertions, 364 deletions
diff --git a/java/res/values-cs/bools.xml b/java/res/values-cs/bools.xml index 897f4b3db..dabfff8ba 100644 --- a/java/res/values-cs/bools.xml +++ b/java/res/values-cs/bools.xml @@ -1,22 +1,22 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -/* +/* ** ** Copyright 2008, 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 +** 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 +** 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 +** 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> - <bool name="im_is_default">true</bool> + <bool name="im_is_default">true</bool> </resources> diff --git a/java/res/values-de/bools.xml b/java/res/values-de/bools.xml index 897f4b3db..dabfff8ba 100644 --- a/java/res/values-de/bools.xml +++ b/java/res/values-de/bools.xml @@ -1,22 +1,22 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -/* +/* ** ** Copyright 2008, 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 +** 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 +** 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 +** 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> - <bool name="im_is_default">true</bool> + <bool name="im_is_default">true</bool> </resources> diff --git a/java/res/values-en/bools.xml b/java/res/values-en/bools.xml index 897f4b3db..dabfff8ba 100644 --- a/java/res/values-en/bools.xml +++ b/java/res/values-en/bools.xml @@ -1,22 +1,22 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -/* +/* ** ** Copyright 2008, 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 +** 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 +** 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 +** 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> - <bool name="im_is_default">true</bool> + <bool name="im_is_default">true</bool> </resources> diff --git a/java/res/values-es/bools.xml b/java/res/values-es/bools.xml index 897f4b3db..dabfff8ba 100644 --- a/java/res/values-es/bools.xml +++ b/java/res/values-es/bools.xml @@ -1,22 +1,22 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -/* +/* ** ** Copyright 2008, 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 +** 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 +** 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 +** 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> - <bool name="im_is_default">true</bool> + <bool name="im_is_default">true</bool> </resources> diff --git a/java/res/values-fr/bools.xml b/java/res/values-fr/bools.xml index 897f4b3db..dabfff8ba 100644 --- a/java/res/values-fr/bools.xml +++ b/java/res/values-fr/bools.xml @@ -1,22 +1,22 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -/* +/* ** ** Copyright 2008, 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 +** 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 +** 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 +** 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> - <bool name="im_is_default">true</bool> + <bool name="im_is_default">true</bool> </resources> diff --git a/java/res/values-land/dimens.xml b/java/res/values-land/dimens.xml index a1546f11d..fdd94347d 100644 --- a/java/res/values-land/dimens.xml +++ b/java/res/values-land/dimens.xml @@ -73,4 +73,10 @@ <dimen name="more_keys_keyboard_slide_allowance">53.76dp</dimen> <!-- popup_key_height x -1.0 --> <dimen name="more_keys_keyboard_vertical_correction">-44.8dp</dimen> + + <!-- Gesture floating preview text parameters --> + <dimen name="gesture_floating_preview_text_size">23dp</dimen> + <dimen name="gesture_floating_preview_text_offset">54dp</dimen> + <dimen name="gesture_floating_preview_horizontal_padding">23dp</dimen> + <dimen name="gesture_floating_preview_vertical_padding">15dp</dimen> </resources> diff --git a/java/res/values-nl/bools.xml b/java/res/values-nl/bools.xml index 897f4b3db..dabfff8ba 100644 --- a/java/res/values-nl/bools.xml +++ b/java/res/values-nl/bools.xml @@ -1,22 +1,22 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -/* +/* ** ** Copyright 2008, 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 +** 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 +** 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 +** 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> - <bool name="im_is_default">true</bool> + <bool name="im_is_default">true</bool> </resources> diff --git a/java/res/values-pl/bools.xml b/java/res/values-pl/bools.xml index 897f4b3db..dabfff8ba 100644 --- a/java/res/values-pl/bools.xml +++ b/java/res/values-pl/bools.xml @@ -1,22 +1,22 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -/* +/* ** ** Copyright 2008, 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 +** 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 +** 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 +** 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> - <bool name="im_is_default">true</bool> + <bool name="im_is_default">true</bool> </resources> diff --git a/java/res/values-sw600dp-land/dimens.xml b/java/res/values-sw600dp-land/dimens.xml index 9664bf9ed..51c710fa4 100644 --- a/java/res/values-sw600dp-land/dimens.xml +++ b/java/res/values-sw600dp-land/dimens.xml @@ -61,4 +61,10 @@ <dimen name="suggestions_strip_padding">252.0dp</dimen> <integer name="max_more_suggestions_row">5</integer> <fraction name="min_more_suggestions_width">50%</fraction> + + <!-- Gesture floating preview text parameters --> + <dimen name="gesture_floating_preview_text_size">26dp</dimen> + <dimen name="gesture_floating_preview_text_offset">76dp</dimen> + <dimen name="gesture_floating_preview_horizontal_padding">26dp</dimen> + <dimen name="gesture_floating_preview_vertical_padding">17dp</dimen> </resources> diff --git a/java/res/values-sw600dp/dimens.xml b/java/res/values-sw600dp/dimens.xml index e608f7d7b..586fbe6da 100644 --- a/java/res/values-sw600dp/dimens.xml +++ b/java/res/values-sw600dp/dimens.xml @@ -84,4 +84,13 @@ <dimen name="suggestion_padding">12dp</dimen> <dimen name="suggestion_text_size">22dp</dimen> <dimen name="more_suggestions_hint_text_size">33dp</dimen> + + <!-- Gesture preview trail parameters --> + <dimen name="gesture_preview_trail_width">2.5dp</dimen> + <!-- Gesture floating preview text parameters --> + <dimen name="gesture_floating_preview_text_size">28dp</dimen> + <dimen name="gesture_floating_preview_text_offset">87dp</dimen> + <dimen name="gesture_floating_preview_horizontal_padding">28dp</dimen> + <dimen name="gesture_floating_preview_vertical_padding">19dp</dimen> + <dimen name="gesture_floating_preview_round_radius">3dp</dimen> </resources> diff --git a/java/res/values-sw768dp-land/dimens.xml b/java/res/values-sw768dp-land/dimens.xml index 511217068..f4a57ffb0 100644 --- a/java/res/values-sw768dp-land/dimens.xml +++ b/java/res/values-sw768dp-land/dimens.xml @@ -64,4 +64,10 @@ <dimen name="suggestions_strip_padding">252.0dp</dimen> <fraction name="min_more_suggestions_width">50%</fraction> + + <!-- Gesture floating preview text parameters --> + <dimen name="gesture_floating_preview_text_size">32dp</dimen> + <dimen name="gesture_floating_preview_text_offset">100dp</dimen> + <dimen name="gesture_floating_preview_horizontal_padding">32dp</dimen> + <dimen name="gesture_floating_preview_vertical_padding">21dp</dimen> </resources> diff --git a/java/res/values-sw768dp/dimens.xml b/java/res/values-sw768dp/dimens.xml index ec9d75988..2fd732293 100644 --- a/java/res/values-sw768dp/dimens.xml +++ b/java/res/values-sw768dp/dimens.xml @@ -85,4 +85,13 @@ <dimen name="suggestion_padding">8dp</dimen> <dimen name="suggestion_text_size">22dp</dimen> <dimen name="more_suggestions_hint_text_size">33dp</dimen> + + <!-- Gesture preview trail parameters --> + <dimen name="gesture_preview_trail_width">2.5dp</dimen> + <!-- Gesture floating preview text parameters --> + <dimen name="gesture_floating_preview_text_size">26dp</dimen> + <dimen name="gesture_floating_preview_text_offset">86dp</dimen> + <dimen name="gesture_floating_preview_horizontal_padding">26dp</dimen> + <dimen name="gesture_floating_preview_vertical_padding">17dp</dimen> + <dimen name="gesture_floating_preview_round_radius">3dp</dimen> </resources> diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml index 05c53a40e..7e8c77e13 100644 --- a/java/res/values/attrs.xml +++ b/java/res/values/attrs.xml @@ -77,12 +77,10 @@ <attr name="gestureFloatingPreviewTextSize" format="dimension" /> <attr name="gestureFloatingPreviewTextColor" format="color" /> <attr name="gestureFloatingPreviewTextOffset" format="dimension" /> - <attr name="gestureFloatingPreviewTextShadingColor" format="color" /> - <attr name="gestureFloatingPreviewTextShadingBorder" format="dimension" /> - <attr name="gestureFloatingPreviewTextShadowColor" format="color" /> - <attr name="gestureFloatingPreviewTextShadowBorder" format="dimension" /> - <attr name="gestureFloatingPreviewTextConnectorColor" format="color" /> - <attr name="gestureFloatingPreviewTextConnectorWidth" format="dimension" /> + <attr name="gestureFloatingPreviewColor" format="color" /> + <attr name="gestureFloatingPreviewHorizontalPadding" format="dimension" /> + <attr name="gestureFloatingPreviewVerticalPadding" format="dimension" /> + <attr name="gestureFloatingPreviewRoundRadius" format="dimension" /> <!-- Delay after gesture input and gesture floating preview text dismissing in millisecond --> <attr name="gestureFloatingPreviewTextLingerTimeout" format="integer" /> <!-- Delay after gesture trail starts fading out in millisecond. --> @@ -92,7 +90,8 @@ <!-- Interval of updating gesture preview trail in millisecond. --> <attr name="gesturePreviewTrailUpdateInterval" format="integer" /> <attr name="gesturePreviewTrailColor" format="color" /> - <attr name="gesturePreviewTrailWidth" format="dimension" /> + <attr name="gesturePreviewTrailStartWidth" format="dimension" /> + <attr name="gesturePreviewTrailEndWidth" format="dimension" /> </declare-styleable> <declare-styleable name="MainKeyboardView"> diff --git a/java/res/values/bools.xml b/java/res/values/bools.xml index 889d8f784..006959600 100644 --- a/java/res/values/bools.xml +++ b/java/res/values/bools.xml @@ -1,19 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -/* +/* ** ** Copyright 2008, 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 +** 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 +** 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 +** 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. */ --> diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml index aa16c7770..d92a71560 100644 --- a/java/res/values/dimens.xml +++ b/java/res/values/dimens.xml @@ -99,13 +99,15 @@ <integer name="suggestions_count_in_strip">3</integer> <fraction name="center_suggestion_percentile">36%</fraction> - <!-- Gesture preview parameters --> - <dimen name="gesture_preview_trail_width">2.5dp</dimen> - <dimen name="gesture_floating_preview_text_size">35dp</dimen> - <dimen name="gesture_floating_preview_text_offset">75dp</dimen> - <dimen name="gesture_floating_preview_text_shadow_border">17.5dp</dimen> - <dimen name="gesture_floating_preview_text_shading_border">7.5dp</dimen> - <dimen name="gesture_floating_preview_text_connector_width">1.0dp</dimen> + <!-- Gesture preview trail parameters --> + <dimen name="gesture_preview_trail_start_width">18.0dp</dimen> + <dimen name="gesture_preview_trail_end_width">2.5dp</dimen> + <!-- Gesture floating preview text parameters --> + <dimen name="gesture_floating_preview_text_size">24dp</dimen> + <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> <!-- 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/styles.xml b/java/res/values/styles.xml index 40f1ff3f4..ed92440ef 100644 --- a/java/res/values/styles.xml +++ b/java/res/values/styles.xml @@ -66,20 +66,19 @@ <item name="backgroundDimAlpha">128</item> <!-- android:color/holo_blue_light=#FF33B5E5 --> <item name="gestureFloatingPreviewTextSize">@dimen/gesture_floating_preview_text_size</item> - <item name="gestureFloatingPreviewTextColor">@android:color/white</item> + <item name="gestureFloatingPreviewTextColor">@android:color/holo_blue_light</item> <item name="gestureFloatingPreviewTextOffset">@dimen/gesture_floating_preview_text_offset</item> - <item name="gestureFloatingPreviewTextShadingColor">@android:color/holo_blue_light</item> - <item name="gestureFloatingPreviewTextShadingBorder">@dimen/gesture_floating_preview_text_shading_border</item> - <item name="gestureFloatingPreviewTextShadowColor">#FF252525</item> - <item name="gestureFloatingPreviewTextShadowBorder">@dimen/gesture_floating_preview_text_shadow_border</item> - <item name="gestureFloatingPreviewTextConnectorColor">@android:color/white</item> - <item name="gestureFloatingPreviewTextConnectorWidth">@dimen/gesture_floating_preview_text_connector_width</item> + <item name="gestureFloatingPreviewColor">#C0000000</item> + <item name="gestureFloatingPreviewHorizontalPadding">@dimen/gesture_floating_preview_horizontal_padding</item> + <item name="gestureFloatingPreviewVerticalPadding">@dimen/gesture_floating_preview_vertical_padding</item> + <item name="gestureFloatingPreviewRoundRadius">@dimen/gesture_floating_preview_round_radius</item> <item name="gestureFloatingPreviewTextLingerTimeout">@integer/config_gesture_floating_preview_text_linger_timeout</item> <item name="gesturePreviewTrailFadeoutStartDelay">@integer/config_gesture_preview_trail_fadeout_start_delay</item> <item name="gesturePreviewTrailFadeoutDuration">@integer/config_gesture_preview_trail_fadeout_duration</item> <item name="gesturePreviewTrailUpdateInterval">@integer/config_gesture_preview_trail_update_interval</item> <item name="gesturePreviewTrailColor">@android:color/holo_blue_light</item> - <item name="gesturePreviewTrailWidth">@dimen/gesture_preview_trail_width</item> + <item name="gesturePreviewTrailStartWidth">@dimen/gesture_preview_trail_start_width</item> + <item name="gesturePreviewTrailEndWidth">@dimen/gesture_preview_trail_end_width</item> <!-- Common attributes of MainKeyboardView --> <item name="keyHysteresisDistance">@dimen/config_key_hysteresis_distance</item> <item name="touchNoiseThresholdTime">@integer/config_touch_noise_threshold_time</item> diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index ce7d79778..db3a7b1e9 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -71,12 +71,10 @@ import java.util.HashSet; * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextSize * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextColor * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextOffset - * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextShadingColor - * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextShadingBorder - * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextShadowColor - * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextShadowBorder - * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextConnectorColor - * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextConnectorWidth + * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewColor + * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewHorizontalPadding + * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewVerticalPadding + * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewRoundRadius * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextLingerTimeout * @attr ref R.styleable#KeyboardView_gesturePreviewTrailFadeoutStartDelay * @attr ref R.styleable#KeyboardView_gesturePreviewTrailFadeoutDuration diff --git a/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java index e814d8009..7442b7fad 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java +++ b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java @@ -17,16 +17,18 @@ package com.android.inputmethod.keyboard.internal; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.Xfermode; import android.os.SystemClock; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.ResizableIntArray; -class GesturePreviewTrail { +final class GesturePreviewTrail { private static final int DEFAULT_CAPACITY = GestureStrokeWithPreviewTrail.PREVIEW_CAPACITY; - private final GesturePreviewTrailParams mPreviewParams; private final ResizableIntArray mXCoordinates = new ResizableIntArray(DEFAULT_CAPACITY); private final ResizableIntArray mYCoordinates = new ResizableIntArray(DEFAULT_CAPACITY); private final ResizableIntArray mEventTimes = new ResizableIntArray(DEFAULT_CAPACITY); @@ -34,28 +36,39 @@ class GesturePreviewTrail { private long mCurrentDownTime; private int mTrailStartIndex; + private final static Xfermode PORTER_DUFF_MODE_SRC = + new PorterDuffXfermode(PorterDuff.Mode.SRC); + // Use this value as imaginary zero because x-coordinates may be zero. private static final int DOWN_EVENT_MARKER = -128; - static class GesturePreviewTrailParams { + static final class Params { + public final int mTrailColor; + public final float mTrailStartWidth; + public final float mTrailEndWidth; public final int mFadeoutStartDelay; public final int mFadeoutDuration; public final int mUpdateInterval; - public GesturePreviewTrailParams(final TypedArray keyboardViewAttr) { + public final int mTrailLingerDuration; + + public Params(final TypedArray keyboardViewAttr) { + mTrailColor = keyboardViewAttr.getColor( + R.styleable.KeyboardView_gesturePreviewTrailColor, 0); + mTrailStartWidth = keyboardViewAttr.getDimension( + R.styleable.KeyboardView_gesturePreviewTrailStartWidth, 0.0f); + mTrailEndWidth = keyboardViewAttr.getDimension( + R.styleable.KeyboardView_gesturePreviewTrailEndWidth, 0.0f); mFadeoutStartDelay = keyboardViewAttr.getInt( R.styleable.KeyboardView_gesturePreviewTrailFadeoutStartDelay, 0); mFadeoutDuration = keyboardViewAttr.getInt( R.styleable.KeyboardView_gesturePreviewTrailFadeoutDuration, 0); + mTrailLingerDuration = mFadeoutStartDelay + mFadeoutDuration; mUpdateInterval = keyboardViewAttr.getInt( R.styleable.KeyboardView_gesturePreviewTrailUpdateInterval, 0); } } - public GesturePreviewTrail(final GesturePreviewTrailParams params) { - mPreviewParams = params; - } - private static int markAsDownEvent(final int xCoord) { return DOWN_EVENT_MARKER - xCoord; } @@ -94,23 +107,30 @@ class GesturePreviewTrail { } } - private int getAlpha(final int elapsedTime) { - if (elapsedTime < mPreviewParams.mFadeoutStartDelay) { + private static int getAlpha(final int elapsedTime, final Params params) { + if (elapsedTime < params.mFadeoutStartDelay) { return Constants.Color.ALPHA_OPAQUE; } final int decreasingAlpha = Constants.Color.ALPHA_OPAQUE - * (elapsedTime - mPreviewParams.mFadeoutStartDelay) - / mPreviewParams.mFadeoutDuration; + * (elapsedTime - params.mFadeoutStartDelay) + / params.mFadeoutDuration; return Constants.Color.ALPHA_OPAQUE - decreasingAlpha; } + private static float getWidth(final int elapsedTime, final Params params) { + return Math.max((params.mTrailLingerDuration - elapsedTime) + * (params.mTrailStartWidth - params.mTrailEndWidth) + / params.mTrailLingerDuration, 0.0f); + } + /** * Draw gesture preview trail * @param canvas The canvas to draw the gesture preview trail * @param paint The paint object to be used to draw the gesture preview trail + * @param params The drawing parameters of gesture preview trail * @return true if some gesture preview trails remain to be drawn */ - public boolean drawGestureTrail(final Canvas canvas, final Paint paint) { + public boolean drawGestureTrail(final Canvas canvas, final Paint paint, final Params params) { final int trailSize = mEventTimes.getLength(); if (trailSize == 0) { return false; @@ -120,13 +140,11 @@ class GesturePreviewTrail { final int[] xCoords = mXCoordinates.getPrimitiveArray(); final int[] yCoords = mYCoordinates.getPrimitiveArray(); final int sinceDown = (int)(SystemClock.uptimeMillis() - mCurrentDownTime); - final int lingeringDuration = mPreviewParams.mFadeoutStartDelay - + mPreviewParams.mFadeoutDuration; int startIndex; for (startIndex = mTrailStartIndex; startIndex < trailSize; startIndex++) { final int elapsedTime = sinceDown - eventTimes[startIndex]; // Skip too old trail points. - if (elapsedTime < lingeringDuration) { + if (elapsedTime < params.mTrailLingerDuration) { break; } } @@ -135,13 +153,20 @@ class GesturePreviewTrail { if (startIndex < trailSize) { int lastX = getXCoordValue(xCoords[startIndex]); int lastY = yCoords[startIndex]; + paint.setColor(params.mTrailColor); + paint.setStyle(Paint.Style.STROKE); + paint.setStrokeCap(Paint.Cap.ROUND); + paint.setXfermode(PORTER_DUFF_MODE_SRC); for (int i = startIndex + 1; i < trailSize - 1; i++) { final int x = xCoords[i]; final int y = yCoords[i]; final int elapsedTime = sinceDown - eventTimes[i]; // Draw trail line only when the current point isn't a down point. if (!isDownEventXCoord(x)) { - paint.setAlpha(getAlpha(elapsedTime)); + final int alpha = getAlpha(elapsedTime, params); + paint.setAlpha(alpha); + final float width = getWidth(elapsedTime, params); + paint.setStrokeWidth(width); canvas.drawLine(lastX, lastY, x, y, paint); } lastX = getXCoordValue(x); diff --git a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java index 269b202b5..8dde4d671 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java +++ b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java @@ -21,6 +21,10 @@ import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Paint.Align; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.Rect; +import android.graphics.RectF; import android.os.Message; import android.text.TextUtils; import android.util.AttributeSet; @@ -28,22 +32,18 @@ import android.util.SparseArray; import android.widget.RelativeLayout; import com.android.inputmethod.keyboard.PointerTracker; -import com.android.inputmethod.keyboard.internal.GesturePreviewTrail.GesturePreviewTrailParams; +import com.android.inputmethod.keyboard.internal.GesturePreviewTrail.Params; import com.android.inputmethod.latin.CollectionUtils; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.StaticInnerHandlerWrapper; public class PreviewPlacerView extends RelativeLayout { - private final Paint mGesturePaint; - private final Paint mTextPaint; private final int mGestureFloatingPreviewTextColor; private final int mGestureFloatingPreviewTextOffset; - private final int mGestureFloatingPreviewTextShadowColor; - private final int mGestureFloatingPreviewTextShadowBorder; - private final int mGestureFloatingPreviewTextShadingColor; - private final int mGestureFloatingPreviewTextShadingBorder; - private final int mGestureFloatingPreviewTextConnectorColor; - private final int mGestureFloatingPreviewTextConnectorWidth; + private final int mGestureFloatingPreviewColor; + private final float mGestureFloatingPreviewHorizontalPadding; + private final float mGestureFloatingPreviewVerticalPadding; + private final float mGestureFloatingPreviewRoundRadius; /* package */ final int mGestureFloatingPreviewTextLingerTimeout; private int mXOrigin; @@ -51,13 +51,18 @@ public class PreviewPlacerView extends RelativeLayout { private final SparseArray<GesturePreviewTrail> mGesturePreviewTrails = CollectionUtils.newSparseArray(); - private final GesturePreviewTrailParams mGesturePreviewTrailParams; + private final Params mGesturePreviewTrailParams; + private final Paint mGesturePaint; + private boolean mDrawsGesturePreviewTrail; + private final Paint mTextPaint; private String mGestureFloatingPreviewText; + private final int mGestureFloatingPreviewTextHeight; + // {@link RectF} is needed for {@link Canvas#drawRoundRect(RectF, float, float, Paint)}. + private final RectF mGestureFloatingPreviewRectangle = new RectF(); private int mLastPointerX; private int mLastPointerY; - - private boolean mDrawsGesturePreviewTrail; + private static final char[] TEXT_HEIGHT_REFERENCE_CHAR = { 'M' }; private boolean mDrawsGestureFloatingPreviewText; private final DrawingHandler mDrawingHandler; @@ -66,10 +71,10 @@ public class PreviewPlacerView extends RelativeLayout { private static final int MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 0; private static final int MSG_UPDATE_GESTURE_PREVIEW_TRAIL = 1; - private final GesturePreviewTrailParams mGesturePreviewTrailParams; + private final Params mGesturePreviewTrailParams; public DrawingHandler(final PreviewPlacerView outerInstance, - final GesturePreviewTrailParams gesturePreviewTrailParams) { + final Params gesturePreviewTrailParams) { super(outerInstance); mGesturePreviewTrailParams = gesturePreviewTrailParams; } @@ -132,41 +137,38 @@ public class PreviewPlacerView extends RelativeLayout { R.styleable.KeyboardView_gestureFloatingPreviewTextColor, 0); mGestureFloatingPreviewTextOffset = keyboardViewAttr.getDimensionPixelOffset( R.styleable.KeyboardView_gestureFloatingPreviewTextOffset, 0); - mGestureFloatingPreviewTextShadowColor = keyboardViewAttr.getColor( - R.styleable.KeyboardView_gestureFloatingPreviewTextShadowColor, 0); - mGestureFloatingPreviewTextShadowBorder = keyboardViewAttr.getDimensionPixelSize( - R.styleable.KeyboardView_gestureFloatingPreviewTextShadowBorder, 0); - mGestureFloatingPreviewTextShadingColor = keyboardViewAttr.getColor( - R.styleable.KeyboardView_gestureFloatingPreviewTextShadingColor, 0); - mGestureFloatingPreviewTextShadingBorder = keyboardViewAttr.getDimensionPixelSize( - R.styleable.KeyboardView_gestureFloatingPreviewTextShadingBorder, 0); - mGestureFloatingPreviewTextConnectorColor = keyboardViewAttr.getColor( - R.styleable.KeyboardView_gestureFloatingPreviewTextConnectorColor, 0); - mGestureFloatingPreviewTextConnectorWidth = keyboardViewAttr.getDimensionPixelSize( - R.styleable.KeyboardView_gestureFloatingPreviewTextConnectorWidth, 0); + mGestureFloatingPreviewColor = keyboardViewAttr.getColor( + R.styleable.KeyboardView_gestureFloatingPreviewColor, 0); + mGestureFloatingPreviewHorizontalPadding = keyboardViewAttr.getDimension( + R.styleable.KeyboardView_gestureFloatingPreviewHorizontalPadding, 0.0f); + mGestureFloatingPreviewVerticalPadding = keyboardViewAttr.getDimension( + R.styleable.KeyboardView_gestureFloatingPreviewVerticalPadding, 0.0f); + mGestureFloatingPreviewRoundRadius = keyboardViewAttr.getDimension( + R.styleable.KeyboardView_gestureFloatingPreviewRoundRadius, 0.0f); mGestureFloatingPreviewTextLingerTimeout = keyboardViewAttr.getInt( R.styleable.KeyboardView_gestureFloatingPreviewTextLingerTimeout, 0); - final int gesturePreviewTrailColor = keyboardViewAttr.getColor( - R.styleable.KeyboardView_gesturePreviewTrailColor, 0); - final int gesturePreviewTrailWidth = keyboardViewAttr.getDimensionPixelSize( - R.styleable.KeyboardView_gesturePreviewTrailWidth, 0); - mGesturePreviewTrailParams = new GesturePreviewTrailParams(keyboardViewAttr); + mGesturePreviewTrailParams = new Params(keyboardViewAttr); keyboardViewAttr.recycle(); mDrawingHandler = new DrawingHandler(this, mGesturePreviewTrailParams); - mGesturePaint = new Paint(); - mGesturePaint.setAntiAlias(true); - mGesturePaint.setStyle(Paint.Style.STROKE); - mGesturePaint.setStrokeJoin(Paint.Join.ROUND); - mGesturePaint.setColor(gesturePreviewTrailColor); - mGesturePaint.setStrokeWidth(gesturePreviewTrailWidth); - - mTextPaint = new Paint(); - mTextPaint.setAntiAlias(true); - mTextPaint.setStrokeJoin(Paint.Join.ROUND); - mTextPaint.setTextAlign(Align.CENTER); - mTextPaint.setTextSize(gestureFloatingPreviewTextSize); + final Paint gesturePaint = new Paint(); + gesturePaint.setAntiAlias(true); + mGesturePaint = gesturePaint; + + final Paint textPaint = new Paint(); + textPaint.setAntiAlias(true); + textPaint.setStyle(Paint.Style.FILL); + textPaint.setTextAlign(Align.CENTER); + textPaint.setTextSize(gestureFloatingPreviewTextSize); + mTextPaint = textPaint; + final Rect textRect = new Rect(); + textPaint.getTextBounds(TEXT_HEIGHT_REFERENCE_CHAR, 0, 1, textRect); + mGestureFloatingPreviewTextHeight = textRect.height(); + + final Paint layerPaint = new Paint(); + layerPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); + setLayerType(LAYER_TYPE_HARDWARE, layerPaint); } public void setOrigin(final int x, final int y) { @@ -185,7 +187,7 @@ public class PreviewPlacerView extends RelativeLayout { synchronized (mGesturePreviewTrails) { trail = mGesturePreviewTrails.get(tracker.mPointerId); if (trail == null) { - trail = new GesturePreviewTrail(mGesturePreviewTrailParams); + trail = new GesturePreviewTrail(); mGesturePreviewTrails.put(tracker.mPointerId, trail); } } @@ -209,7 +211,8 @@ public class PreviewPlacerView extends RelativeLayout { for (int index = 0; index < trailsCount; index++) { final GesturePreviewTrail trail = mGesturePreviewTrails.valueAt(index); needsUpdatingGesturePreviewTrail |= - trail.drawGestureTrail(canvas, mGesturePaint); + trail.drawGestureTrail(canvas, mGesturePaint, + mGesturePreviewTrailParams); } } if (needsUpdatingGesturePreviewTrail) { @@ -242,45 +245,30 @@ public class PreviewPlacerView extends RelativeLayout { } final Paint paint = mTextPaint; + final RectF rectangle = mGestureFloatingPreviewRectangle; // TODO: Figure out how we should deal with the floating preview text with multiple moving // fingers. - final int lastX = mLastPointerX; - final int lastY = mLastPointerY; - final int textSize = (int)paint.getTextSize(); - final int canvasWidth = canvas.getWidth(); - final int halfTextWidth = (int)paint.measureText(gestureFloatingPreviewText) / 2 + textSize; - final int textX = Math.min(Math.max(lastX, halfTextWidth), canvasWidth - halfTextWidth); - - int textY = Math.max(-textSize, lastY - mGestureFloatingPreviewTextOffset); - if (textY < 0) { - // Paint black text shadow if preview extends above keyboard region. - paint.setStyle(Paint.Style.FILL_AND_STROKE); - paint.setColor(mGestureFloatingPreviewTextShadowColor); - paint.setStrokeWidth(mGestureFloatingPreviewTextShadowBorder); - canvas.drawText(gestureFloatingPreviewText, textX, textY, paint); - } - - // Paint the vertical line connecting the touch point to the preview text. - paint.setStyle(Paint.Style.STROKE); - paint.setColor(mGestureFloatingPreviewTextConnectorColor); - paint.setStrokeWidth(mGestureFloatingPreviewTextConnectorWidth); - final int lineTopY = textY - textSize / 4; - canvas.drawLine(lastX, lastY, lastX, lineTopY, paint); - if (lastX != textX) { - // Paint the horizontal line connection the touch point to the preview text. - canvas.drawLine(lastX, lineTopY, textX, lineTopY, paint); - } - - // Paint the shading for the text preview - paint.setStyle(Paint.Style.FILL_AND_STROKE); - paint.setColor(mGestureFloatingPreviewTextShadingColor); - paint.setStrokeWidth(mGestureFloatingPreviewTextShadingBorder); - canvas.drawText(gestureFloatingPreviewText, textX, textY, paint); + // Paint the round rectangle background. + final int textHeight = mGestureFloatingPreviewTextHeight; + final float textWidth = paint.measureText(gestureFloatingPreviewText); + final float hPad = mGestureFloatingPreviewHorizontalPadding; + final float vPad = mGestureFloatingPreviewVerticalPadding; + final float rectWidth = textWidth + hPad * 2.0f; + final float rectHeight = textHeight + vPad * 2.0f; + final int canvasWidth = canvas.getWidth(); + final float rectX = Math.min(Math.max(mLastPointerX - rectWidth / 2.0f, 0.0f), + canvasWidth - rectWidth); + final float rectY = mLastPointerY - mGestureFloatingPreviewTextOffset - rectHeight; + rectangle.set(rectX, rectY, rectX + rectWidth, rectY + rectHeight); + final float round = mGestureFloatingPreviewRoundRadius; + paint.setColor(mGestureFloatingPreviewColor); + canvas.drawRoundRect(rectangle, round, round, paint); // Paint the text preview paint.setColor(mGestureFloatingPreviewTextColor); - paint.setStyle(Paint.Style.FILL); + final float textX = rectX + hPad + textWidth / 2.0f; + final float textY = rectY + vPad + textHeight; canvas.drawText(gestureFloatingPreviewText, textX, textY, paint); } } diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java b/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java index 81d61e957..d6fa66131 100644 --- a/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java +++ b/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java @@ -54,7 +54,7 @@ public class UserHistoryDictIOUtils { private byte[] mBuffer; private int mPosition; - ByteArrayWrapper(final byte[] buffer) { + public ByteArrayWrapper(final byte[] buffer) { mBuffer = buffer; mPosition = 0; } diff --git a/java/src/com/android/inputmethod/research/ResearchLog.java b/java/src/com/android/inputmethod/research/ResearchLog.java index cd9ff85f8..70c38e909 100644 --- a/java/src/com/android/inputmethod/research/ResearchLog.java +++ b/java/src/com/android/inputmethod/research/ResearchLog.java @@ -93,7 +93,7 @@ public class ResearchLog { mFile = outputFile; } - public synchronized void close() { + public synchronized void close(final Runnable onClosed) { mExecutor.submit(new Callable<Object>() { @Override public Object call() throws Exception { @@ -102,7 +102,14 @@ public class ResearchLog { mJsonWriter.endArray(); mJsonWriter.flush(); mJsonWriter.close(); + if (DEBUG) { + Log.d(TAG, "wrote log to " + mFile); + } mHasWrittenData = false; + } else { + if (DEBUG) { + Log.d(TAG, "close() called, but no data, not outputting"); + } } } catch (Exception e) { Log.d(TAG, "error when closing ResearchLog:"); @@ -111,6 +118,9 @@ public class ResearchLog { if (mFile.exists()) { mFile.setWritable(false, false); } + if (onClosed != null) { + onClosed.run(); + } } return null; } diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java index 5c2487195..763fd6e00 100644 --- a/java/src/com/android/inputmethod/research/ResearchLogger.java +++ b/java/src/com/android/inputmethod/research/ResearchLogger.java @@ -84,6 +84,7 @@ import java.util.UUID; */ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = ResearchLogger.class.getSimpleName(); + private static final boolean DEBUG = false; private static final boolean OUTPUT_ENTIRE_BUFFER = false; // true may disclose private info public static final boolean DEFAULT_USABILITY_STUDY_MODE = false; /* package */ static boolean sIsLogging = false; @@ -344,6 +345,9 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang } private void start() { + if (DEBUG) { + Log.d(TAG, "start called"); + } maybeShowSplashScreen(); updateSuspendedState(); requestIndicatorRedraw(); @@ -371,21 +375,27 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang } /* package */ void stop() { + if (DEBUG) { + Log.d(TAG, "stop called"); + } logStatistics(); commitCurrentLogUnit(); if (mMainLogBuffer != null) { publishLogBuffer(mMainLogBuffer, mMainResearchLog, false /* isIncludingPrivateData */); - mMainResearchLog.close(); + mMainResearchLog.close(null /* callback */); mMainLogBuffer = null; } if (mFeedbackLogBuffer != null) { - mFeedbackLog.close(); + mFeedbackLog.close(null /* callback */); mFeedbackLogBuffer = null; } } public boolean abort() { + if (DEBUG) { + Log.d(TAG, "abort called"); + } boolean didAbortMainLog = false; if (mMainLogBuffer != null) { mMainLogBuffer.clear(); @@ -549,12 +559,19 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang false /* isPotentiallyPrivate */); mFeedbackLogBuffer.shiftIn(feedbackLogUnit); publishLogBuffer(mFeedbackLogBuffer, mFeedbackLog, true /* isIncludingPrivateData */); - mFeedbackLog.close(); - uploadNow(); + mFeedbackLog.close(new Runnable() { + @Override + public void run() { + uploadNow(); + } + }); mFeedbackLog = new ResearchLog(createLogFile(mFilesDir)); } public void uploadNow() { + if (DEBUG) { + Log.d(TAG, "calling uploadNow()"); + } mInputMethodService.startService(mUploadIntent); } @@ -574,6 +591,13 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang } private boolean isAllowedToLog() { + if (DEBUG) { + Log.d(TAG, "iatl: " + + "mipw=" + mIsPasswordView + + ", mils=" + mIsLoggingSuspended + + ", sil=" + sIsLogging + + ", mInFeedbackDialog=" + mInFeedbackDialog); + } return !mIsPasswordView && !mIsLoggingSuspended && sIsLogging && !mInFeedbackDialog; } @@ -662,6 +686,9 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang } /* package for test */ void commitCurrentLogUnit() { + if (DEBUG) { + Log.d(TAG, "commitCurrentLogUnit"); + } if (!mCurrentLogUnit.isEmpty()) { if (mMainLogBuffer != null) { mMainLogBuffer.shiftIn(mCurrentLogUnit); @@ -1014,26 +1041,26 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang final boolean isPasswordView = kid.passwordInput(); getInstance().setIsPasswordView(isPasswordView); final Object[] values = { - KeyboardId.elementIdToName(kid.mElementId), - kid.mLocale + ":" + kid.mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET), - kid.mOrientation, - kid.mWidth, - KeyboardId.modeName(kid.mMode), - kid.imeAction(), - kid.navigateNext(), - kid.navigatePrevious(), - kid.mClobberSettingsKey, - isPasswordView, - kid.mShortcutKeyEnabled, - kid.mHasShortcutKey, - kid.mLanguageSwitchKeyEnabled, - kid.isMultiLine(), - keyboard.mOccupiedWidth, - keyboard.mOccupiedHeight, - keyboard.mKeys - }; - getInstance().enqueueEvent(EVENTKEYS_MAINKEYBOARDVIEW_SETKEYBOARD, values); + KeyboardId.elementIdToName(kid.mElementId), + kid.mLocale + ":" + kid.mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET), + kid.mOrientation, + kid.mWidth, + KeyboardId.modeName(kid.mMode), + kid.imeAction(), + kid.navigateNext(), + kid.navigatePrevious(), + kid.mClobberSettingsKey, + isPasswordView, + kid.mShortcutKeyEnabled, + kid.mHasShortcutKey, + kid.mLanguageSwitchKeyEnabled, + kid.isMultiLine(), + keyboard.mOccupiedWidth, + keyboard.mOccupiedHeight, + keyboard.mKeys + }; getInstance().setIsPasswordView(isPasswordView); + getInstance().enqueueEvent(EVENTKEYS_MAINKEYBOARDVIEW_SETKEYBOARD, values); } } diff --git a/native/jni/src/binary_format.h b/native/jni/src/binary_format.h index 5d8b2a0f2..eec52e323 100644 --- a/native/jni/src/binary_format.h +++ b/native/jni/src/binary_format.h @@ -360,7 +360,7 @@ inline int BinaryFormat::getTerminalPosition(const uint8_t *const root, while (true) { // If we already traversed the tree further than the word is long, there means // there was no match (or we would have found it). - if (wordPos > length) return NOT_VALID_WORD; + if (wordPos >= length) return NOT_VALID_WORD; int charGroupCount = BinaryFormat::getGroupCountAndForwardPointer(root, &pos); const int32_t wChar = forceLowerCaseSearch ? toLowerCase(inWord[wordPos]) : inWord[wordPos]; while (true) { @@ -383,7 +383,7 @@ inline int BinaryFormat::getTerminalPosition(const uint8_t *const root, // character that does not match, as explained above, it means the word is // not in the dictionary (by virtue of this chargroup being the only one to // match the word on the first character, but not matching the whole word). - if (wordPos > length) return NOT_VALID_WORD; + if (wordPos >= length) return NOT_VALID_WORD; if (inWord[wordPos] != character) return NOT_VALID_WORD; character = BinaryFormat::getCodePointAndForwardPointer(root, &pos); } diff --git a/native/jni/src/proximity_info_state.cpp b/native/jni/src/proximity_info_state.cpp index b363dcc36..c62b9b35d 100644 --- a/native/jni/src/proximity_info_state.cpp +++ b/native/jni/src/proximity_info_state.cpp @@ -224,7 +224,7 @@ float ProximityInfoState::updateNearKeysDistances(const int x, const int y, bool ProximityInfoState::isPrevLocalMin(const NearKeysDistanceMap *const currentNearKeysDistances, const NearKeysDistanceMap *const prevNearKeysDistances, const NearKeysDistanceMap *const prevPrevNearKeysDistances) const { - static const float MARGIN = 0.5f; + static const float MARGIN = 0.05f; for (NearKeysDistanceMap::const_iterator it = prevNearKeysDistances->begin(); it != prevNearKeysDistances->end(); ++it) { @@ -245,14 +245,14 @@ float ProximityInfoState::getPointScore( const NearKeysDistanceMap *const prevNearKeysDistances, const NearKeysDistanceMap *const prevPrevNearKeysDistances) const { static const float BASE_SAMPLE_RATE_SCALE = 0.1f; - static const float SAVE_DISTANCE_SCALE = 12.0f; + static const float SAVE_DISTANCE_SCALE = 14.0f; static const float SAVE_DISTANCE_SCORE = 2.0f; static const float SKIP_DISTANCE_SCALE = 1.5f; static const float SKIP_DISTANCE_SCORE = -1.0f; - static const float CHECK_LOCALMIN_DISTANCE_THRESHOLD_SCALE = 2.5f; + static const float CHECK_LOCALMIN_DISTANCE_THRESHOLD_SCALE = 3.5f; static const float CHECK_LOCALMIN_DISTANCE_SCORE = -1.0f; static const float STRAIGHT_ANGLE_THRESHOLD = M_PI_F / 32.0f; - static const float STRAIGHT_SKIP_DISTANCE_THRESHOLD_SCALE = 4.0f; + static const float STRAIGHT_SKIP_DISTANCE_THRESHOLD_SCALE = 5.0f; static const float STRAIGHT_SKIP_NEAREST_DISTANCE_THRESHOLD = 0.5f; static const float STRAIGHT_SKIP_SCORE = -1.0f; @@ -275,19 +275,19 @@ float ProximityInfoState::getPointScore( score += SKIP_DISTANCE_SCORE; } // Location - if (!isPrevLocalMin(currentNearKeysDistances, currentNearKeysDistances, + if (distPrev < baseSampleRate * CHECK_LOCALMIN_DISTANCE_THRESHOLD_SCALE) { + if (!isPrevLocalMin(currentNearKeysDistances, currentNearKeysDistances, prevPrevNearKeysDistances)) { - if (distPrev < baseSampleRate * CHECK_LOCALMIN_DISTANCE_THRESHOLD_SCALE) { score += CHECK_LOCALMIN_DISTANCE_SCORE; } } // Angle - const float angle1 = getAngle(x, y, mInputXs.back(), mInputYs.back()); - const float angle2 = getAngle(mInputXs.back(), mInputYs.back(), - mInputXs[size - 2], mInputYs[size - 2]); - if (getAngleDiff(angle1, angle2) < STRAIGHT_ANGLE_THRESHOLD) { - if (nearest > STRAIGHT_SKIP_NEAREST_DISTANCE_THRESHOLD - && distPrev < baseSampleRate * STRAIGHT_SKIP_DISTANCE_THRESHOLD_SCALE) { + if (nearest > STRAIGHT_SKIP_NEAREST_DISTANCE_THRESHOLD + && distPrev < baseSampleRate * STRAIGHT_SKIP_DISTANCE_THRESHOLD_SCALE) { + const float angle1 = getAngle(x, y, mInputXs.back(), mInputYs.back()); + const float angle2 = getAngle(mInputXs.back(), mInputYs.back(), + mInputXs[size - 2], mInputYs[size - 2]); + if (getAngleDiff(angle1, angle2) < STRAIGHT_ANGLE_THRESHOLD) { score += STRAIGHT_SKIP_SCORE; } } @@ -383,13 +383,14 @@ float ProximityInfoState::calculateNormalizedSquaredDistance( } int ProximityInfoState::getDuration(const int index) const { - if (mInputSize > 0 && index > 0 && index < static_cast<int>(mInputSize) - 1) { + if (mInputSize > 0 && index > 0 && index < mInputSize - 1) { return mTimes[index + 1] - mTimes[index - 1]; } return 0; } -float ProximityInfoState::getPointToKeyLength(int inputIndex, int codePoint, float scale) { +float ProximityInfoState::getPointToKeyLength(const int inputIndex, const int codePoint, + const float scale) const { const int keyId = mProximityInfo->getKeyIndexOf(codePoint); if (keyId != NOT_AN_INDEX) { const int index = inputIndex * mProximityInfo->getKeyCount() + keyId; @@ -404,11 +405,7 @@ float ProximityInfoState::getPointToKeyLength(int inputIndex, int codePoint, flo return MAX_POINT_TO_KEY_LENGTH; } -int ProximityInfoState::getKeyKeyDistance(int key0, int key1) { - return mProximityInfo->getKeyKeyDistanceG(key0, key1); -} - -int ProximityInfoState::getSpaceY() { +int ProximityInfoState::getSpaceY() const { const int keyId = mProximityInfo->getKeyIndexOf(' '); return mProximityInfo->getKeyCenterYOfKeyIdG(keyId); } @@ -447,4 +444,12 @@ int32_t ProximityInfoState::getAllPossibleChars( } return i; } + +float ProximityInfoState::getAveragePointDuration() const { + if (mInputSize == 0) { + return 0; + } + return (mTimes[mInputSize - 1] - mTimes[0]) / static_cast<float>(mInputSize); +} + } // namespace latinime diff --git a/native/jni/src/proximity_info_state.h b/native/jni/src/proximity_info_state.h index 80b84e962..1d5777347 100644 --- a/native/jni/src/proximity_info_state.h +++ b/native/jni/src/proximity_info_state.h @@ -200,27 +200,26 @@ class ProximityInfoState { return mInputSize; } - int getInputX(int index) const { + int getInputX(const int index) const { return mInputXs[index]; } - int getInputY(int index) const { + int getInputY(const int index) const { return mInputYs[index]; } - int getLengthCache(int index) const { + int getLengthCache(const int index) const { return mLengthCache[index]; } - float getPointToKeyLength(int inputIndex, int charCode, float scale); + float getPointToKeyLength(const int inputIndex, const int charCode, const float scale) const; - int getKeyKeyDistance(int key0, int key1); - - int getSpaceY(); + int getSpaceY() const; int32_t getAllPossibleChars( - const size_t startIndex, int32_t *const filter, int32_t filterSize) const; + const size_t startIndex, int32_t *const filter, const int32_t filterSize) const; + float getAveragePointDuration() const; private: DISALLOW_COPY_AND_ASSIGN(ProximityInfoState); typedef hash_map_compat<int, float> NearKeysDistanceMap; diff --git a/native/jni/src/unigram_dictionary.cpp b/native/jni/src/unigram_dictionary.cpp index b7e245a6c..cf806c111 100644 --- a/native/jni/src/unigram_dictionary.cpp +++ b/native/jni/src/unigram_dictionary.cpp @@ -451,7 +451,7 @@ int UnigramDictionary::getSubStringSuggestion( const bool hasAutoCorrectionCandidate, const int currentWordIndex, const int inputWordStartPos, const int inputWordLength, const int outputWordStartPos, const bool isSpaceProximity, int *freqArray, - int*wordLengthArray, unsigned short *outputWord, int *outputWordLength) const { + int *wordLengthArray, unsigned short *outputWord, int *outputWordLength) const { if (inputWordLength > MULTIPLE_WORDS_SUGGESTION_MAX_WORD_LENGTH) { return FLAG_MULTIPLE_SUGGEST_ABORT; } @@ -546,9 +546,9 @@ int UnigramDictionary::getSubStringSuggestion( freq = score >> (nextWordLength + TWO_WORDS_PLUS_OTHER_ERROR_CORRECTION_DEMOTION_DIVIDER); } if (DEBUG_DICT) { - AKLOGI("Freq(%d): %d, length: %d, input length: %d, input start: %d (%d)" - , currentWordIndex, freq, nextWordLength, inputWordLength, inputWordStartPos, - wordLengthArray[0]); + AKLOGI("Freq(%d): %d, length: %d, input length: %d, input start: %d (%d)", + currentWordIndex, freq, nextWordLength, inputWordLength, inputWordStartPos, + (currentWordIndex > 0) ? wordLengthArray[0] : 0); } if (freq <= 0 || nextWordLength <= 0 || MAX_WORD_LENGTH <= (outputWordStartPos + nextWordLength)) { diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java index 6036562a8..523287b48 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java @@ -17,23 +17,22 @@ package com.android.inputmethod.latin.makedict; import com.android.inputmethod.latin.CollectionUtils; -import com.android.inputmethod.latin.makedict.BinaryDictInputOutput; -import com.android.inputmethod.latin.makedict.FusionDictionary; +import com.android.inputmethod.latin.UserHistoryDictIOUtils; +import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.FusionDictionaryBufferInterface; import com.android.inputmethod.latin.makedict.FusionDictionary.CharGroup; import com.android.inputmethod.latin.makedict.FusionDictionary.Node; -import com.android.inputmethod.latin.makedict.PendingAttribute; -import com.android.inputmethod.latin.makedict.UnsupportedFormatException; +import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString; import android.test.AndroidTestCase; import android.util.Log; import android.util.SparseArray; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; import java.io.File; -import java.io.FileOutputStream; import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -53,16 +52,76 @@ public class BinaryDictIOTests extends AndroidTestCase { private static final int BIGRAM_FREQ = 50; private static final int TOLERANCE_OF_BIGRAM_FREQ = 5; + private static final int USE_BYTE_ARRAY = 1; + private static final int USE_BYTE_BUFFER = 2; + + private static final List<String> sWords = CollectionUtils.newArrayList(); + private static final SparseArray<List<Integer>> sEmptyBigrams = + CollectionUtils.newSparseArray(); + private static final SparseArray<List<Integer>> sStarBigrams = CollectionUtils.newSparseArray(); + private static final SparseArray<List<Integer>> sChainBigrams = + CollectionUtils.newSparseArray(); + private static final BinaryDictInputOutput.FormatOptions VERSION2 = new BinaryDictInputOutput.FormatOptions(2); - private static final String[] CHARACTERS = - { + private static final String[] CHARACTERS = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" - }; + }; + + public BinaryDictIOTests() { + super(); + + final Random random = new Random(123456); + sWords.clear(); + generateWords(MAX_UNIGRAMS, random); + + for (int i = 0; i < sWords.size(); ++i) { + sChainBigrams.put(i, new ArrayList<Integer>()); + if (i > 0) { + sChainBigrams.get(i-1).add(i); + } + } + + sStarBigrams.put(0, new ArrayList<Integer>()); + for (int i = 1; i < sWords.size(); ++i) { + sStarBigrams.get(0).add(i); + } + } // Utilities for test + + /** + * Makes new buffer according to BUFFER_TYPE. + */ + private FusionDictionaryBufferInterface getBuffer(final File file,final int bufferType) { + FileInputStream inStream = null; + try { + inStream = new FileInputStream(file); + if (bufferType == USE_BYTE_ARRAY) { + final byte[] array = new byte[(int)file.length()]; + inStream.read(array); + return new UserHistoryDictIOUtils.ByteArrayWrapper(array); + } else if (bufferType == USE_BYTE_BUFFER){ + final ByteBuffer buffer = inStream.getChannel().map( + FileChannel.MapMode.READ_ONLY, 0, file.length()); + return new BinaryDictInputOutput.ByteBufferWrapper(buffer); + } + } catch (IOException e) { + Log.e(TAG, "IOException while making buffer: " + e); + } finally { + if (inStream != null) { + try { + inStream.close(); + } catch (IOException e) { + Log.e(TAG, "IOException while closing stream: " + e); + } + } + } + return null; + } + /** * Generates a random word. */ @@ -77,23 +136,29 @@ public class BinaryDictIOTests extends AndroidTestCase { return builder.toString(); } - private List<String> generateWords(final int number, final Random random) { + private void generateWords(final int number, final Random random) { final Set<String> wordSet = CollectionUtils.newHashSet(); while (wordSet.size() < number) { wordSet.add(generateWord(random.nextInt())); } - return new ArrayList<String>(wordSet); + sWords.addAll(wordSet); } /** * Adds unigrams to the dictionary. */ - private void addUnigrams(final int number, - final FusionDictionary dict, - final List<String> words) { + private void addUnigrams(final int number, final FusionDictionary dict, + final List<String> words, final Map<String, List<String>> shortcutMap) { for (int i = 0; i < number; ++i) { final String word = words.get(i); - dict.add(word, UNIGRAM_FREQ, null, false /* isNotAWord */); + final ArrayList<WeightedString> shortcuts = CollectionUtils.newArrayList(); + if (shortcutMap != null && shortcutMap.containsKey(word)) { + for (final String shortcut : shortcutMap.get(word)) { + shortcuts.add(new WeightedString(shortcut, UNIGRAM_FREQ)); + } + } + dict.add(word, UNIGRAM_FREQ, (shortcutMap == null) ? null : shortcuts, + false /* isNotAWord */); } } @@ -130,9 +195,8 @@ public class BinaryDictIOTests extends AndroidTestCase { return diff; } - private void checkDictionary(final FusionDictionary dict, - final List<String> words, - final SparseArray<List<Integer>> bigrams) { + private void checkDictionary(final FusionDictionary dict, final List<String> words, + final SparseArray<List<Integer>> bigrams, final Map<String, List<String>> shortcutMap) { assertNotNull(dict); // check unigram @@ -149,94 +213,93 @@ public class BinaryDictIOTests extends AndroidTestCase { assertNotNull(words.get(w1) + "," + words.get(w2), cg.getBigram(words.get(w2))); } } + + // check shortcut + if (shortcutMap != null) { + for (final Map.Entry<String, List<String>> entry : shortcutMap.entrySet()) { + final CharGroup group = FusionDictionary.findWordInTree(dict.mRoot, entry.getKey()); + for (final String word : entry.getValue()) { + assertNotNull("shortcut not found: " + entry.getKey() + ", " + word, + group.getShortcut(word)); + } + } + } } // Tests for readDictionaryBinary and writeDictionaryBinary private long timeReadingAndCheckDict(final File file, final List<String> words, - final SparseArray<List<Integer>> bigrams) { - + final SparseArray<List<Integer>> bigrams, final Map<String, List<String>> shortcutMap, + final int bufferType) { long now, diff = -1; + final FusionDictionaryBufferInterface buffer = getBuffer(file, bufferType); + assertNotNull(buffer); - FileInputStream inStream = null; + FusionDictionary dict = null; try { - inStream = new FileInputStream(file); - final ByteBuffer buffer = inStream.getChannel().map( - FileChannel.MapMode.READ_ONLY, 0, file.length()); - now = System.currentTimeMillis(); - - final FusionDictionary dict = - BinaryDictInputOutput.readDictionaryBinary(buffer, null); - - diff = System.currentTimeMillis() - now; - - checkDictionary(dict, words, bigrams); - return diff; - + dict = BinaryDictInputOutput.readDictionaryBinary(buffer, null); + diff = System.currentTimeMillis() - now; } catch (IOException e) { - Log.e(TAG, "raise IOException while reading file " + e); + Log.e(TAG, "IOException while reading dictionary: " + e); } catch (UnsupportedFormatException e) { - Log.e(TAG, "Unsupported format: " + e); - } finally { - if (inStream != null) { - try { - inStream.close(); - } catch (IOException e) { - // do nothing - } - } + Log.e(TAG, "Unsupported format: "+ e); } + checkDictionary(dict, words, bigrams, shortcutMap); return diff; } + // Tests for readDictionaryBinary and writeDictionaryBinary private String runReadAndWrite(final List<String> words, - final SparseArray<List<Integer>> bigrams, - final String message) { - final FusionDictionary dict = new FusionDictionary(new Node(), - new FusionDictionary.DictionaryOptions( - new HashMap<String,String>(), false, false)); - + final SparseArray<List<Integer>> bigrams, final Map<String, List<String>> shortcuts, + final int bufferType, final String message) { File file = null; try { file = File.createTempFile("runReadAndWrite", ".dict"); } catch (IOException e) { Log.e(TAG, "IOException: " + e); } - assertNotNull(file); - addUnigrams(words.size(), dict, words); + final FusionDictionary dict = new FusionDictionary(new Node(), + new FusionDictionary.DictionaryOptions( + new HashMap<String,String>(), false, false)); + addUnigrams(words.size(), dict, words, shortcuts); addBigrams(dict, words, bigrams); - // check original dictionary - checkDictionary(dict, words, bigrams); + checkDictionary(dict, words, bigrams, shortcuts); final long write = timeWritingDictToFile(file, dict); - final long read = timeReadingAndCheckDict(file, words, bigrams); + final long read = timeReadingAndCheckDict(file, words, bigrams, shortcuts, bufferType); - return "PROF: read=" + read + "ms, write=" + write + "ms :" + message; + return "PROF: read=" + read + "ms, write=" + write + "ms :" + message + + " : buffer type = " + bufferType; } - public void testReadAndWrite() { - final List<String> results = new ArrayList<String>(); + public void testReadAndWriteWithByteBuffer() { + final List<String> results = CollectionUtils.newArrayList(); - final Random random = new Random(123456); - final List<String> words = generateWords(MAX_UNIGRAMS, random); - final SparseArray<List<Integer>> emptyArray = CollectionUtils.newSparseArray(); + results.add(runReadAndWrite(sWords, sEmptyBigrams, null /* shortcuts */, USE_BYTE_BUFFER, + "unigram")); + results.add(runReadAndWrite(sWords, sChainBigrams, null /* shortcuts */, USE_BYTE_BUFFER, + "chain")); + results.add(runReadAndWrite(sWords, sStarBigrams, null /* shortcuts */, USE_BYTE_BUFFER, + "star")); - final SparseArray<List<Integer>> chain = CollectionUtils.newSparseArray(); - for (int i = 0; i < words.size(); ++i) chain.put(i, new ArrayList<Integer>()); - for (int i = 1; i < words.size(); ++i) chain.get(i-1).add(i); + for (final String result : results) { + Log.d(TAG, result); + } + } - final SparseArray<List<Integer>> star = CollectionUtils.newSparseArray(); - final List<Integer> list0 = CollectionUtils.newArrayList(); - star.put(0, list0); - for (int i = 1; i < words.size(); ++i) star.get(0).add(i); + public void testReadAndWriteWithByteArray() { + final List<String> results = CollectionUtils.newArrayList(); - results.add(runReadAndWrite(words, emptyArray, "only unigram")); - results.add(runReadAndWrite(words, chain, "chain")); - results.add(runReadAndWrite(words, star, "star")); + results.add(runReadAndWrite(sWords, sEmptyBigrams, null /* shortcuts */, USE_BYTE_ARRAY, + "unigram")); + results.add(runReadAndWrite(sWords, sChainBigrams, null /* shortcuts */, USE_BYTE_ARRAY, + "chain")); + results.add(runReadAndWrite(sWords, sStarBigrams, null /* shortcuts */, USE_BYTE_ARRAY, + "star")); for (final String result : results) { Log.d(TAG, result); @@ -292,7 +355,7 @@ public class BinaryDictIOTests extends AndroidTestCase { } private long timeAndCheckReadUnigramsAndBigramsBinary(final File file, final List<String> words, - final SparseArray<List<Integer>> bigrams) { + final SparseArray<List<Integer>> bigrams, final int bufferType) { FileInputStream inStream = null; final Map<Integer, String> resultWords = CollectionUtils.newTreeMap(); @@ -301,17 +364,13 @@ public class BinaryDictIOTests extends AndroidTestCase { final Map<Integer, Integer> resultFreqs = CollectionUtils.newTreeMap(); long now = -1, diff = -1; + final FusionDictionaryBufferInterface buffer = getBuffer(file, bufferType); + assertNotNull("Can't get buffer.", buffer); try { - inStream = new FileInputStream(file); - final ByteBuffer buffer = inStream.getChannel().map( - FileChannel.MapMode.READ_ONLY, 0, file.length()); - now = System.currentTimeMillis(); - BinaryDictInputOutput.readUnigramsAndBigramsBinary( - new BinaryDictInputOutput.ByteBufferWrapper(buffer), resultWords, resultFreqs, + BinaryDictInputOutput.readUnigramsAndBigramsBinary(buffer, resultWords, resultFreqs, resultBigrams); diff = System.currentTimeMillis() - now; - checkWordMap(words, bigrams, resultWords, resultFreqs, resultBigrams); } catch (IOException e) { Log.e(TAG, "IOException " + e); } catch (UnsupportedFormatException e) { @@ -326,50 +385,64 @@ public class BinaryDictIOTests extends AndroidTestCase { } } + checkWordMap(words, bigrams, resultWords, resultFreqs, resultBigrams); return diff; } - private void runReadUnigramsAndBigramsBinary(final List<String> words, - final SparseArray<List<Integer>> bigrams) { - - // making the dictionary from lists of words. - final FusionDictionary dict = new FusionDictionary(new Node(), - new FusionDictionary.DictionaryOptions( - new HashMap<String, String>(), false, false)); - + private String runReadUnigramsAndBigramsBinary(final List<String> words, + final SparseArray<List<Integer>> bigrams, final int bufferType, + final String message) { File file = null; try { file = File.createTempFile("runReadUnigrams", ".dict"); } catch (IOException e) { Log.e(TAG, "IOException: " + e); } - assertNotNull(file); - addUnigrams(words.size(), dict, words); + // making the dictionary from lists of words. + final FusionDictionary dict = new FusionDictionary(new Node(), + new FusionDictionary.DictionaryOptions( + new HashMap<String, String>(), false, false)); + addUnigrams(words.size(), dict, words, null /* shortcutMap */); addBigrams(dict, words, bigrams); + timeWritingDictToFile(file, dict); - long wordMap = timeAndCheckReadUnigramsAndBigramsBinary(file, words, bigrams); - long fullReading = timeReadingAndCheckDict(file, words, bigrams); + long wordMap = timeAndCheckReadUnigramsAndBigramsBinary(file, words, bigrams, bufferType); + long fullReading = timeReadingAndCheckDict(file, words, bigrams, null /* shortcutMap */, + bufferType); - Log.d(TAG, "read=" + fullReading + ", bytearray=" + wordMap); + return "readDictionaryBinary=" + fullReading + ", readUnigramsAndBigramsBinary=" + wordMap + + " : " + message + " : buffer type = " + bufferType; } - public void testReadUnigramsAndBigramsBinary() { - final List<String> results = new ArrayList<String>(); + public void testReadUnigramsAndBigramsBinaryWithByteBuffer() { + final List<String> results = CollectionUtils.newArrayList(); - final Random random = new Random(123456); - final List<String> words = generateWords(MAX_UNIGRAMS, random); - final SparseArray<List<Integer>> emptyArray = CollectionUtils.newSparseArray(); + results.add(runReadUnigramsAndBigramsBinary(sWords, sEmptyBigrams, USE_BYTE_BUFFER, + "unigram")); + results.add(runReadUnigramsAndBigramsBinary(sWords, sChainBigrams, USE_BYTE_BUFFER, + "chain")); + results.add(runReadUnigramsAndBigramsBinary(sWords, sStarBigrams, USE_BYTE_BUFFER, + "star")); + + for (final String result : results) { + Log.d(TAG, result); + } + } - runReadUnigramsAndBigramsBinary(words, emptyArray); + public void testReadUnigramsAndBigramsBinaryWithByteArray() { + final List<String> results = CollectionUtils.newArrayList(); - final SparseArray<List<Integer>> star = CollectionUtils.newSparseArray(); - for (int i = 1; i < words.size(); ++i) { - star.put(i-1, new ArrayList<Integer>()); - star.get(i-1).add(i); + results.add(runReadUnigramsAndBigramsBinary(sWords, sEmptyBigrams, USE_BYTE_ARRAY, + "unigram")); + results.add(runReadUnigramsAndBigramsBinary(sWords, sChainBigrams, USE_BYTE_ARRAY, + "chain")); + results.add(runReadUnigramsAndBigramsBinary(sWords, sStarBigrams, USE_BYTE_ARRAY, "star")); + + for (final String result : results) { + Log.d(TAG, result); } - runReadUnigramsAndBigramsBinary(words, star); } } |