aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--java/res/drawable-hdpi/ic_add_circle_wht_24dp.pngbin0 -> 436 bytes
-rw-r--r--java/res/drawable-mdpi/ic_add_circle_wht_24dp.pngbin0 -> 305 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_add_circle_wht_24dp.pngbin0 -> 466 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_add_circle_wht_24dp.pngbin0 -> 684 bytes
-rw-r--r--java/res/drawable/btn_keyboard_key_lxx_dark.xml5
-rw-r--r--java/res/drawable/btn_keyboard_key_lxx_light.xml5
-rw-r--r--java/res/menu/add_style.xml26
-rw-r--r--java/res/values/attrs.xml7
-rw-r--r--java/res/xml-sw600dp/key_styles_enter.xml1
-rw-r--r--java/res/xml/key_styles_enter.xml1
-rw-r--r--java/res/xml/method.xml4
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java100
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java75
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputConnection.java22
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java1
-rw-r--r--java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java6
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.cpp29
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.h14
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp7
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.cpp46
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h11
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h9
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp25
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h2
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp15
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h8
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp12
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/trie_map.h4
-rw-r--r--native/jni/src/utils/int_array_view.h19
-rw-r--r--native/jni/tests/utils/int_array_view_test.cpp33
-rw-r--r--tests/src/com/android/inputmethod/latin/InputLogicTestsReorderingMyanmar.java3
-rw-r--r--tests/src/com/android/inputmethod/latin/InputTestsBase.java10
-rw-r--r--tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java13
33 files changed, 304 insertions, 209 deletions
diff --git a/java/res/drawable-hdpi/ic_add_circle_wht_24dp.png b/java/res/drawable-hdpi/ic_add_circle_wht_24dp.png
new file mode 100644
index 000000000..314c52137
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_add_circle_wht_24dp.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_add_circle_wht_24dp.png b/java/res/drawable-mdpi/ic_add_circle_wht_24dp.png
new file mode 100644
index 000000000..11363b173
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_add_circle_wht_24dp.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_add_circle_wht_24dp.png b/java/res/drawable-xhdpi/ic_add_circle_wht_24dp.png
new file mode 100644
index 000000000..32a5b05ba
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_add_circle_wht_24dp.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_add_circle_wht_24dp.png b/java/res/drawable-xxhdpi/ic_add_circle_wht_24dp.png
new file mode 100644
index 000000000..a22c463f9
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_add_circle_wht_24dp.png
Binary files differ
diff --git a/java/res/drawable/btn_keyboard_key_lxx_dark.xml b/java/res/drawable/btn_keyboard_key_lxx_dark.xml
index bb1789ae3..c82c13829 100644
--- a/java/res/drawable/btn_keyboard_key_lxx_dark.xml
+++ b/java/res/drawable/btn_keyboard_key_lxx_dark.xml
@@ -15,6 +15,11 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Custom label action keys. -->
+ <item android:state_active="true" android:state_checked="true" android:state_pressed="true"
+ android:drawable="@color/key_background_pressed_lxx_dark" />
+ <item android:state_active="true" android:state_checked="true"
+ android:drawable="@color/key_background_lxx_dark" />
<!-- Action keys. -->
<item android:state_active="true" android:state_pressed="true"
android:drawable="@drawable/btn_keyboard_key_active_pressed_lxx_dark" />
diff --git a/java/res/drawable/btn_keyboard_key_lxx_light.xml b/java/res/drawable/btn_keyboard_key_lxx_light.xml
index 60fe02dd2..f237fbea9 100644
--- a/java/res/drawable/btn_keyboard_key_lxx_light.xml
+++ b/java/res/drawable/btn_keyboard_key_lxx_light.xml
@@ -15,6 +15,11 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Custom label action keys. -->
+ <item android:state_active="true" android:state_checked="true" android:state_pressed="true"
+ android:drawable="@color/key_background_pressed_lxx_light" />
+ <item android:state_active="true" android:state_checked="true"
+ android:drawable="@color/key_background_lxx_light" />
<!-- Action keys. -->
<item android:state_active="true" android:state_pressed="true"
android:drawable="@drawable/btn_keyboard_key_active_pressed_lxx_light" />
diff --git a/java/res/menu/add_style.xml b/java/res/menu/add_style.xml
new file mode 100644
index 000000000..d1cab4bb5
--- /dev/null
+++ b/java/res/menu/add_style.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/action_add_style"
+ android:icon="@drawable/ic_add_circle_wht_24dp"
+ android:title="@string/add_style"
+ android:showAsAction="always" />
+</menu> \ No newline at end of file
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 9a2227321..e6215c254 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -270,9 +270,10 @@
<enum name="empty" value="0" />
<enum name="normal" value="1" />
<enum name="functional" value="2" />
- <enum name="action" value="3" />
- <enum name="stickyOff" value="4" />
- <enum name="stickyOn" value="5" />
+ <enum name="stickyOff" value="3" />
+ <enum name="stickyOn" value="4" />
+ <enum name="action" value="5" />
+ <enum name="customAction" value="6" />
</attr>
<!-- The key action flags. -->
<attr name="keyActionFlags" format="integer">
diff --git a/java/res/xml-sw600dp/key_styles_enter.xml b/java/res/xml-sw600dp/key_styles_enter.xml
index 740bf3543..d0167d336 100644
--- a/java/res/xml-sw600dp/key_styles_enter.xml
+++ b/java/res/xml-sw600dp/key_styles_enter.xml
@@ -230,6 +230,7 @@
latin:styleName="enterKeyStyle"
latin:keySpec="dummy_label|!code/key_enter"
latin:keyLabelFlags="fromCustomActionLabel"
+ latin:backgroundType="customAction"
latin:parentStyle="defaultEnterKeyStyle" />
</case>
<!-- imeAction is either actionNone or actionUnspecified. -->
diff --git a/java/res/xml/key_styles_enter.xml b/java/res/xml/key_styles_enter.xml
index 770bf3876..960c79c18 100644
--- a/java/res/xml/key_styles_enter.xml
+++ b/java/res/xml/key_styles_enter.xml
@@ -398,6 +398,7 @@
latin:styleName="enterKeyStyle"
latin:keySpec="dummy_label|!code/key_enter"
latin:keyLabelFlags="fromCustomActionLabel"
+ latin:backgroundType="customAction"
latin:parentStyle="defaultEnterKeyStyle" />
</case>
<!-- imeAction is either actionNone or actionUnspecified. -->
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index 5021f33ee..cfe25d1c4 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -51,7 +51,7 @@
fr_CH: French (Switzerland)/swiss
gl_ES: Galician (Spain)/spanish
hi: Hindi/hindi
- (hi: Hindi/hindi_compact) # This is a preliminary keyboard layout.
+ hi: Hindi/hindi_compact
hr: Croatian/qwertz
hu: Hungarian/qwertz
hy_AM: Armenian (Armenia) Phonetic/armenian_phonetic
@@ -346,8 +346,6 @@
android:imeSubtypeExtraValue="KeyboardLayoutSet=hindi,EmojiCapable"
android:isAsciiCapable="false"
/>
- <!-- TODO: This hindi_compact keyboard is a preliminary layout.
- This isn't based on the final specification. -->
<subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic_compact"
android:subtypeId="0xe49c89a1"
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index af54fb674..55ce7dd34 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -123,9 +123,10 @@ public class Key implements Comparable<Key> {
public static final int BACKGROUND_TYPE_EMPTY = 0;
public static final int BACKGROUND_TYPE_NORMAL = 1;
public static final int BACKGROUND_TYPE_FUNCTIONAL = 2;
- public static final int BACKGROUND_TYPE_ACTION = 3;
- public static final int BACKGROUND_TYPE_STICKY_OFF = 4;
- public static final int BACKGROUND_TYPE_STICKY_ON = 5;
+ public static final int BACKGROUND_TYPE_STICKY_OFF = 3;
+ public static final int BACKGROUND_TYPE_STICKY_ON = 4;
+ public static final int BACKGROUND_TYPE_ACTION = 5;
+ public static final int BACKGROUND_TYPE_CUSTOM_ACTION = 6;
private final int mActionFlags;
private static final int ACTION_FLAGS_IS_REPEATABLE = 0x01;
@@ -483,9 +484,10 @@ public class Key implements Comparable<Key> {
case BACKGROUND_TYPE_EMPTY: return "empty";
case BACKGROUND_TYPE_NORMAL: return "normal";
case BACKGROUND_TYPE_FUNCTIONAL: return "functional";
- case BACKGROUND_TYPE_ACTION: return "action";
case BACKGROUND_TYPE_STICKY_OFF: return "stickyOff";
case BACKGROUND_TYPE_STICKY_ON: return "stickyOn";
+ case BACKGROUND_TYPE_ACTION: return "action";
+ case BACKGROUND_TYPE_CUSTOM_ACTION: return "customAction";
default: return null;
}
}
@@ -814,47 +816,37 @@ public class Key implements Comparable<Key> {
return dx * dx + dy * dy;
}
- private final static int[] KEY_STATE_NORMAL_HIGHLIGHT_ON = {
- android.R.attr.state_checkable,
- android.R.attr.state_checked
- };
-
- private final static int[] KEY_STATE_PRESSED_HIGHLIGHT_ON = {
- android.R.attr.state_pressed,
- android.R.attr.state_checkable,
- android.R.attr.state_checked
- };
-
- private final static int[] KEY_STATE_NORMAL_HIGHLIGHT_OFF = {
- android.R.attr.state_checkable
- };
-
- private final static int[] KEY_STATE_PRESSED_HIGHLIGHT_OFF = {
- android.R.attr.state_pressed,
- android.R.attr.state_checkable
- };
-
- private final static int[] KEY_STATE_NORMAL = {
- };
+ static class KeyBackgroundState {
+ private final int[] mReleasedState;
+ private final int[] mPressedState;
- private final static int[] KEY_STATE_PRESSED = {
- android.R.attr.state_pressed
- };
-
- private final static int[] KEY_STATE_EMPTY = {
- android.R.attr.state_empty
- };
+ private KeyBackgroundState(final int ... attrs) {
+ mReleasedState = attrs;
+ mPressedState = Arrays.copyOf(attrs, attrs.length + 1);
+ mPressedState[attrs.length] = android.R.attr.state_pressed;
+ }
- // action normal state (with properties)
- private static final int[] KEY_STATE_ACTIVE_NORMAL = {
- android.R.attr.state_active
- };
+ public int[] getState(final boolean pressed) {
+ return pressed ? mPressedState : mReleasedState;
+ }
- // action pressed state (with properties)
- private static final int[] KEY_STATE_ACTIVE_PRESSED = {
- android.R.attr.state_active,
- android.R.attr.state_pressed
- };
+ public static final KeyBackgroundState[] STATES = {
+ // 0: BACKGROUND_TYPE_EMPTY
+ new KeyBackgroundState(android.R.attr.state_empty),
+ // 1: BACKGROUND_TYPE_NORMAL
+ new KeyBackgroundState(),
+ // 2: BACKGROUND_TYPE_FUNCTIONAL
+ new KeyBackgroundState(),
+ // 3: BACKGROUND_TYPE_STICKY_OFF
+ new KeyBackgroundState(android.R.attr.state_checkable),
+ // 4: BACKGROUND_TYPE_STICKY_ON
+ new KeyBackgroundState(android.R.attr.state_checkable, android.R.attr.state_checked),
+ // 5: BACKGROUND_TYPE_ACTION
+ new KeyBackgroundState(android.R.attr.state_active),
+ // 6: BACKGROUND_TYPE_CUSTOM_ACTION
+ new KeyBackgroundState(android.R.attr.state_active, android.R.attr.state_checked)
+ };
+ }
/**
* Returns the background drawable for the key, based on the current state and type of the key.
@@ -871,28 +863,8 @@ public class Key implements Comparable<Key> {
} else {
background = keyBackground;
}
- final int[] stateSet;
- switch (mBackgroundType) {
- case BACKGROUND_TYPE_ACTION:
- stateSet = mPressed ? KEY_STATE_ACTIVE_PRESSED : KEY_STATE_ACTIVE_NORMAL;
- break;
- case BACKGROUND_TYPE_STICKY_OFF:
- stateSet = mPressed ? KEY_STATE_PRESSED_HIGHLIGHT_OFF : KEY_STATE_NORMAL_HIGHLIGHT_OFF;
- break;
- case BACKGROUND_TYPE_STICKY_ON:
- stateSet = mPressed ? KEY_STATE_PRESSED_HIGHLIGHT_ON : KEY_STATE_NORMAL_HIGHLIGHT_ON;
- break;
- case BACKGROUND_TYPE_EMPTY:
- stateSet = mPressed ? KEY_STATE_PRESSED : KEY_STATE_EMPTY;
- break;
- case BACKGROUND_TYPE_FUNCTIONAL:
- stateSet = mPressed ? KEY_STATE_PRESSED : KEY_STATE_NORMAL;
- break;
- default: /* BACKGROUND_TYPE_NORMAL */
- stateSet = mPressed ? KEY_STATE_PRESSED : KEY_STATE_NORMAL;
- break;
- }
- background.setState(stateSet);
+ final int[] state = KeyBackgroundState.STATES[mBackgroundType].getState(mPressed);
+ background.setState(state);
return background;
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 4adc28d7a..f67c2a356 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -752,30 +752,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
loadKeyboard();
}
- /**
- * A class that holds information to pass from onStartInputInternal to onStartInputViewInternal
- *
- * OnStartInput needs to reload the settings and that will prevent onStartInputViewInternal
- * from comparing the old settings with the new ones, so we use this memory to pass the
- * necessary information along.
- */
- private static class EditorChangeInfo {
- public final boolean mIsSameInputType;
- public final boolean mHasSameOrientation;
- public EditorChangeInfo(final boolean isSameInputType, final boolean hasSameOrientation) {
- mIsSameInputType = isSameInputType;
- mHasSameOrientation = hasSameOrientation;
- }
- }
-
- private EditorChangeInfo mLastEditorChangeInfo;
-
private void onStartInputInternal(final EditorInfo editorInfo, final boolean restarting) {
super.onStartInput(editorInfo, restarting);
- SettingsValues currentSettingsValues = mSettings.getCurrent();
- mLastEditorChangeInfo = new EditorChangeInfo(
- currentSettingsValues.isSameInputType(editorInfo),
- currentSettingsValues.hasSameOrientation(getResources().getConfiguration()));
}
@SuppressWarnings("deprecation")
@@ -785,6 +763,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final KeyboardSwitcher switcher = mKeyboardSwitcher;
switcher.updateKeyboardTheme();
final MainKeyboardView mainKeyboardView = switcher.getMainKeyboardView();
+ // If we are starting input in a different text field from before, we'll have to reload
+ // settings, so currentSettingsValues can't be final.
+ SettingsValues currentSettingsValues = mSettings.getCurrent();
if (editorInfo == null) {
Log.e(TAG, "Null EditorInfo in onStartInputView()");
@@ -827,7 +808,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
accessUtils.onStartInputViewInternal(mainKeyboardView, editorInfo, restarting);
}
- final boolean inputTypeChanged = !mLastEditorChangeInfo.mIsSameInputType;
+ final boolean inputTypeChanged = !currentSettingsValues.isSameInputType(editorInfo);
final boolean isDifferentTextField = !restarting || inputTypeChanged;
if (isDifferentTextField) {
mSubtypeSwitcher.updateParametersOnStartInputView();
@@ -872,12 +853,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
canReachInputConnection = true;
}
- if (isDifferentTextField || !mLastEditorChangeInfo.mHasSameOrientation) {
+ if (isDifferentTextField ||
+ !currentSettingsValues.hasSameOrientation(getResources().getConfiguration())) {
loadSettings();
}
- final SettingsValues currentSettingsValues = mSettings.getCurrent();
if (isDifferentTextField) {
mainKeyboardView.closing();
+ currentSettingsValues = mSettings.getCurrent();
if (currentSettingsValues.mAutoCorrectionEnabledPerUserSettings) {
suggest.setAutoCorrectionThreshold(
@@ -1250,10 +1232,26 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mSubtypeState.switchSubtype(token, mRichImm);
}
+ // TODO: Instead of checking for alphabetic keyboard here, separate keycodes for
+ // alphabetic shift and shift while in symbol layout and get rid of this method.
+ private int getCodePointForKeyboard(final int codePoint) {
+ if (Constants.CODE_SHIFT == codePoint) {
+ final Keyboard currentKeyboard = mKeyboardSwitcher.getKeyboard();
+ if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) {
+ return codePoint;
+ } else {
+ return Constants.CODE_SYMBOL_SHIFT;
+ }
+ } else {
+ return codePoint;
+ }
+ }
+
// Implementation of {@link KeyboardActionListener}.
@Override
public void onCodeInput(final int codePoint, final int x, final int y,
final boolean isKeyRepeat) {
+ // TODO: this processing does not belong inside LatinIME, the caller should be doing this.
final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
// x and y include some padding, but everything down the line (especially native
// code) needs the coordinates in the keyboard frame.
@@ -1262,30 +1260,23 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// this transformation, it should be done already before calling onCodeInput.
final int keyX = mainKeyboardView.getKeyX(x);
final int keyY = mainKeyboardView.getKeyY(y);
- final int codeToSend;
- if (Constants.CODE_SHIFT == codePoint) {
- // TODO: Instead of checking for alphabetic keyboard here, separate keycodes for
- // alphabetic shift and shift while in symbol layout.
- final Keyboard currentKeyboard = mKeyboardSwitcher.getKeyboard();
- if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) {
- codeToSend = codePoint;
- } else {
- codeToSend = Constants.CODE_SYMBOL_SHIFT;
- }
- } else {
- codeToSend = codePoint;
- }
- if (Constants.CODE_SHORTCUT == codePoint) {
+ final Event event = createSoftwareKeypressEvent(getCodePointForKeyboard(codePoint),
+ keyX, keyY, isKeyRepeat);
+ onEvent(event);
+ }
+
+ // This method is public for testability of LatinIME, but also in the future it should
+ // completely replace #onCodeInput.
+ public void onEvent(final Event event) {
+ if (Constants.CODE_SHORTCUT == event.mCodePoint) {
mSubtypeSwitcher.switchToShortcutIME(this);
- // Still call the *#onCodeInput methods for readability.
}
- final Event event = createSoftwareKeypressEvent(codeToSend, keyX, keyY, isKeyRepeat);
final InputTransaction completeInputTransaction =
mInputLogic.onCodeInput(mSettings.getCurrent(), event,
mKeyboardSwitcher.getKeyboardShiftMode(),
mKeyboardSwitcher.getCurrentKeyboardScriptId(), mHandler);
updateStateAfterInputTransaction(completeInputTransaction);
- mKeyboardSwitcher.onCodeInput(codePoint, getCurrentAutoCapsState(),
+ mKeyboardSwitcher.onCodeInput(event.mCodePoint, getCurrentAutoCapsState(),
getCurrentRecapitalizeState());
}
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index a6b3b710b..ea63cef02 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -17,6 +17,7 @@
package com.android.inputmethod.latin;
import android.inputmethodservice.InputMethodService;
+import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
@@ -811,4 +812,25 @@ public final class RichInputConnection {
public boolean isCursorPositionKnown() {
return INVALID_CURSOR_POSITION != mExpectedSelStart;
}
+
+ /**
+ * Work around a bug that was present before Jelly Bean upon rotation.
+ *
+ * Before Jelly Bean, there is a bug where setComposingRegion and other committing
+ * functions on the input connection get ignored until the cursor moves. This method works
+ * around the bug by wiggling the cursor first, which reactivates the connection and has
+ * the subsequent methods work, then restoring it to its original position.
+ *
+ * On platforms on which this method is not present, this is a no-op.
+ */
+ public void maybeMoveTheCursorAroundAndRestoreToWorkaroundABug() {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
+ if (mExpectedSelStart > 0) {
+ mIC.setSelection(mExpectedSelStart - 1, mExpectedSelStart - 1);
+ } else {
+ mIC.setSelection(mExpectedSelStart + 1, mExpectedSelStart + 1);
+ }
+ mIC.setSelection(mExpectedSelStart, mExpectedSelEnd);
+ }
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 97457b2f7..418866ae1 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -1437,6 +1437,7 @@ public final class InputLogic {
mLatinIME.getCoordinatesForCurrentKeyboard(codePoints));
mWordComposer.setCursorPositionWithinWord(
typedWord.codePointCount(0, numberOfCharsInWordBeforeCursor));
+ mConnection.maybeMoveTheCursorAroundAndRestoreToWorkaroundABug();
mConnection.setComposingRegion(expectedCursorPosition - numberOfCharsInWordBeforeCursor,
expectedCursorPosition + range.getNumberOfCharsInWordAfterCursor());
if (suggestions.size() <= (shouldIncludeResumedWordInSuggestions ? 1 : 0)) {
diff --git a/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java
index 21f2afd01..6d7f53cf0 100644
--- a/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java
@@ -63,7 +63,6 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
private AlertDialog mSubtypeEnablerNotificationDialog;
private String mSubtypePreferenceKeyForSubtypeEnabler;
- private static final int MENU_ADD_SUBTYPE = Menu.FIRST;
private static final String KEY_IS_ADDING_NEW_SUBTYPE = "is_adding_new_subtype";
private static final String KEY_IS_SUBTYPE_ENABLER_NOTIFICATION_DIALOG_OPEN =
"is_subtype_enabler_notification_dialog_open";
@@ -581,14 +580,13 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
- final MenuItem addSubtypeMenu = menu.add(0, MENU_ADD_SUBTYPE, 0, R.string.add_style);
- addSubtypeMenu.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+ inflater.inflate(R.menu.add_style, menu);
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
final int itemId = item.getItemId();
- if (itemId == MENU_ADD_SUBTYPE) {
+ if (itemId == R.id.action_add_style) {
final SubtypePreference newSubtype =
SubtypePreference.newIncompleteSubtypePreference(getActivity(), mSubtypeProxy);
getPreferenceScreen().addPreference(newSubtype);
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.cpp
index 4220a9561..278f2b199 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.cpp
@@ -231,30 +231,31 @@ bool Ver4PatriciaTrieNodeWriter::writeNewTerminalPtNodeAndAdvancePosition(
&probabilityEntryToWrite);
}
-bool Ver4PatriciaTrieNodeWriter::addNewBigramEntry(
- const PtNodeParams *const sourcePtNodeParams, const PtNodeParams *const targetPtNodeParam,
- const BigramProperty *const bigramProperty, bool *const outAddedNewBigram) {
- if (!mBigramPolicy->addNewEntry(sourcePtNodeParams->getTerminalId(),
- targetPtNodeParam->getTerminalId(), bigramProperty, outAddedNewBigram)) {
+bool Ver4PatriciaTrieNodeWriter::addNgramEntry(const WordIdArrayView prevWordIds, const int wordId,
+ const BigramProperty *const bigramProperty, bool *const outAddedNewEntry) {
+ if (!mBigramPolicy->addNewEntry(prevWordIds[0], wordId, bigramProperty, outAddedNewEntry)) {
AKLOGE("Cannot add new bigram entry. terminalId: %d, targetTerminalId: %d",
sourcePtNodeParams->getTerminalId(), targetPtNodeParam->getTerminalId());
return false;
}
- if (!sourcePtNodeParams->hasBigrams()) {
+ const int ptNodePos =
+ mBuffers->getTerminalPositionLookupTable()->getTerminalPtNodePosition(prevWordIds[0]);
+ const PtNodeParams sourcePtNodeParams =
+ mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos(ptNodePos);
+ if (!sourcePtNodeParams.hasBigrams()) {
// Update has bigrams flag.
- return updatePtNodeFlags(sourcePtNodeParams->getHeadPos(),
- sourcePtNodeParams->isBlacklisted(), sourcePtNodeParams->isNotAWord(),
- sourcePtNodeParams->isTerminal(), sourcePtNodeParams->hasShortcutTargets(),
+ return updatePtNodeFlags(sourcePtNodeParams.getHeadPos(),
+ sourcePtNodeParams.isBlacklisted(), sourcePtNodeParams.isNotAWord(),
+ sourcePtNodeParams.isTerminal(), sourcePtNodeParams.hasShortcutTargets(),
true /* hasBigrams */,
- sourcePtNodeParams->getCodePointCount() > 1 /* hasMultipleChars */);
+ sourcePtNodeParams.getCodePointCount() > 1 /* hasMultipleChars */);
}
return true;
}
-bool Ver4PatriciaTrieNodeWriter::removeBigramEntry(
- const PtNodeParams *const sourcePtNodeParams, const PtNodeParams *const targetPtNodeParam) {
- return mBigramPolicy->removeEntry(sourcePtNodeParams->getTerminalId(),
- targetPtNodeParam->getTerminalId());
+bool Ver4PatriciaTrieNodeWriter::removeNgramEntry(const WordIdArrayView prevWordIds,
+ const int wordId) {
+ return mBigramPolicy->removeEntry(prevWordIds[0], wordId);
}
bool Ver4PatriciaTrieNodeWriter::updateAllBigramEntriesAndDeleteUselessEntries(
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.h b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.h
index 08226ea26..d49d9a666 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_node_writer.h
@@ -29,6 +29,7 @@
#include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h"
#include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h"
#include "suggest/policyimpl/dictionary/structure/backward/v402/content/probability_entry.h"
+#include "utils/int_array_view.h"
namespace latinime {
namespace backward {
@@ -61,8 +62,8 @@ class Ver4PatriciaTrieNodeWriter : public PtNodeWriter {
const PtNodeArrayReader *const ptNodeArrayReader,
Ver4BigramListPolicy *const bigramPolicy, Ver4ShortcutListPolicy *const shortcutPolicy)
: mTrieBuffer(trieBuffer), mBuffers(buffers), mHeaderPolicy(headerPolicy),
- mReadingHelper(ptNodeReader, ptNodeArrayReader), mBigramPolicy(bigramPolicy),
- mShortcutPolicy(shortcutPolicy) {}
+ mPtNodeReader(ptNodeReader), mReadingHelper(ptNodeReader, ptNodeArrayReader),
+ mBigramPolicy(bigramPolicy), mShortcutPolicy(shortcutPolicy) {}
virtual ~Ver4PatriciaTrieNodeWriter() {}
@@ -92,12 +93,10 @@ class Ver4PatriciaTrieNodeWriter : public PtNodeWriter {
virtual bool writeNewTerminalPtNodeAndAdvancePosition(const PtNodeParams *const ptNodeParams,
const UnigramProperty *const unigramProperty, int *const ptNodeWritingPos);
- virtual bool addNewBigramEntry(const PtNodeParams *const sourcePtNodeParams,
- const PtNodeParams *const targetPtNodeParam, const BigramProperty *const bigramProperty,
- bool *const outAddedNewBigram);
+ virtual bool addNgramEntry(const WordIdArrayView prevWordIds, const int wordId,
+ const BigramProperty *const bigramProperty, bool *const outAddedNewEntry);
- virtual bool removeBigramEntry(const PtNodeParams *const sourcePtNodeParams,
- const PtNodeParams *const targetPtNodeParam);
+ virtual bool removeNgramEntry(const WordIdArrayView prevWordIds, const int wordId);
virtual bool updateAllBigramEntriesAndDeleteUselessEntries(
const PtNodeParams *const sourcePtNodeParams, int *const outBigramEntryCount);
@@ -135,6 +134,7 @@ class Ver4PatriciaTrieNodeWriter : public PtNodeWriter {
BufferWithExtendableBuffer *const mTrieBuffer;
Ver4DictBuffers *const mBuffers;
const HeaderPolicy *const mHeaderPolicy;
+ const PtNodeReader *const mPtNodeReader;
DynamicPtReadingHelper mReadingHelper;
Ver4BigramListPolicy *const mBigramPolicy;
Ver4ShortcutListPolicy *const mShortcutPolicy;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp
index baa0c0c37..1296b8acd 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp
@@ -309,8 +309,8 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI
return false;
}
bool addedNewBigram = false;
- if (mUpdatingHelper.addBigramWords(prevWordsPtNodePos[0], word1Pos, bigramProperty,
- &addedNewBigram)) {
+ if (mUpdatingHelper.addNgramEntry(PtNodePosArrayView::fromObject(prevWordsPtNodePos),
+ word1Pos, bigramProperty, &addedNewBigram)) {
if (addedNewBigram) {
mBigramCount++;
}
@@ -350,7 +350,8 @@ bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWor
if (wordPos == NOT_A_DICT_POS) {
return false;
}
- if (mUpdatingHelper.removeBigramWords(prevWordsPtNodePos[0], wordPos)) {
+ if (mUpdatingHelper.removeNgramEntry(
+ PtNodePosArrayView::fromObject(prevWordsPtNodePos), wordPos)) {
mBigramCount--;
return true;
} else {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.cpp
index f31c914d2..3c62e2e56 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.cpp
@@ -84,23 +84,39 @@ bool DynamicPtUpdatingHelper::addUnigramWord(
unigramProperty, &pos);
}
-bool DynamicPtUpdatingHelper::addBigramWords(const int word0Pos, const int word1Pos,
- const BigramProperty *const bigramProperty, bool *const outAddedNewBigram) {
- const PtNodeParams sourcePtNodeParams(
- mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos(word0Pos));
- const PtNodeParams targetPtNodeParams(
- mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos(word1Pos));
- return mPtNodeWriter->addNewBigramEntry(&sourcePtNodeParams, &targetPtNodeParams,
- bigramProperty, outAddedNewBigram);
+bool DynamicPtUpdatingHelper::addNgramEntry(const PtNodePosArrayView prevWordsPtNodePos,
+ const int wordPos, const BigramProperty *const bigramProperty,
+ bool *const outAddedNewEntry) {
+ if (prevWordsPtNodePos.empty()) {
+ return false;
+ }
+ ASSERT(prevWordsPtNodePos.size() <= MAX_PREV_WORD_COUNT_FOR_N_GRAM);
+ int prevWordTerminalIds[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
+ for (size_t i = 0; i < prevWordsPtNodePos.size(); ++i) {
+ prevWordTerminalIds[i] = mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos(
+ prevWordsPtNodePos[i]).getTerminalId();
+ }
+ const WordIdArrayView prevWordIds(prevWordTerminalIds, prevWordsPtNodePos.size());
+ const int wordId =
+ mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos(wordPos).getTerminalId();
+ return mPtNodeWriter->addNgramEntry(prevWordIds, wordId, bigramProperty, outAddedNewEntry);
}
-// Remove a bigram relation from word0Pos to word1Pos.
-bool DynamicPtUpdatingHelper::removeBigramWords(const int word0Pos, const int word1Pos) {
- const PtNodeParams sourcePtNodeParams(
- mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos(word0Pos));
- const PtNodeParams targetPtNodeParams(
- mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos(word1Pos));
- return mPtNodeWriter->removeBigramEntry(&sourcePtNodeParams, &targetPtNodeParams);
+bool DynamicPtUpdatingHelper::removeNgramEntry(const PtNodePosArrayView prevWordsPtNodePos,
+ const int wordPos) {
+ if (prevWordsPtNodePos.empty()) {
+ return false;
+ }
+ ASSERT(prevWordsPtNodePos.size() <= MAX_PREV_WORD_COUNT_FOR_N_GRAM);
+ int prevWordTerminalIds[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
+ for (size_t i = 0; i < prevWordsPtNodePos.size(); ++i) {
+ prevWordTerminalIds[i] = mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos(
+ prevWordsPtNodePos[i]).getTerminalId();
+ }
+ const WordIdArrayView prevWordIds(prevWordTerminalIds, prevWordsPtNodePos.size());
+ const int wordId =
+ mPtNodeReader->fetchPtNodeParamsInBufferFromPtNodePos(wordPos).getTerminalId();
+ return mPtNodeWriter->removeNgramEntry(prevWordIds, wordId);
}
bool DynamicPtUpdatingHelper::addShortcutTarget(const int wordPos,
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h
index f10d15a9b..97c05c1ea 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_updating_helper.h
@@ -19,6 +19,7 @@
#include "defines.h"
#include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h"
+#include "utils/int_array_view.h"
namespace latinime {
@@ -42,12 +43,12 @@ class DynamicPtUpdatingHelper {
const int *const wordCodePoints, const int codePointCount,
const UnigramProperty *const unigramProperty, bool *const outAddedNewUnigram);
- // Add a bigram relation from word0Pos to word1Pos.
- bool addBigramWords(const int word0Pos, const int word1Pos,
- const BigramProperty *const bigramProperty, bool *const outAddedNewBigram);
+ // Add an n-gram entry.
+ bool addNgramEntry(const PtNodePosArrayView prevWordsPtNodePos, const int wordPos,
+ const BigramProperty *const bigramProperty, bool *const outAddedNewEntry);
- // Remove a bigram relation from word0Pos to word1Pos.
- bool removeBigramWords(const int word0Pos, const int word1Pos);
+ // Remove an n-gram entry.
+ bool removeNgramEntry(const PtNodePosArrayView prevWordsPtNodePos, const int wordPos);
// Add a shortcut target.
bool addShortcutTarget(const int wordPos, const int *const targetCodePoints,
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h
index a8029f73f..955d779ac 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h
@@ -21,6 +21,7 @@
#include "defines.h"
#include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h"
+#include "utils/int_array_view.h"
namespace latinime {
@@ -70,12 +71,10 @@ class PtNodeWriter {
virtual bool writeNewTerminalPtNodeAndAdvancePosition(const PtNodeParams *const ptNodeParams,
const UnigramProperty *const unigramProperty, int *const ptNodeWritingPos) = 0;
- virtual bool addNewBigramEntry(const PtNodeParams *const sourcePtNodeParams,
- const PtNodeParams *const targetPtNodeParam, const BigramProperty *const bigramProperty,
- bool *const outAddedNewBigram) = 0;
+ virtual bool addNgramEntry(const WordIdArrayView prevWordIds, const int wordId,
+ const BigramProperty *const bigramProperty, bool *const outAddedNewEntry) = 0;
- virtual bool removeBigramEntry(const PtNodeParams *const sourcePtNodeParams,
- const PtNodeParams *const targetPtNodeParam) = 0;
+ virtual bool removeNgramEntry(const WordIdArrayView prevWordIds, const int wordId) = 0;
virtual bool updateAllBigramEntriesAndDeleteUselessEntries(
const PtNodeParams *const sourcePtNodeParams, int *const outBigramEntryCount) = 0;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp
index 07e1051bc..5dc91ba10 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.cpp
@@ -32,11 +32,11 @@ bool LanguageModelDictContent::runGC(
ProbabilityEntry LanguageModelDictContent::getNgramProbabilityEntry(
const WordIdArrayView prevWordIds, const int wordId) const {
- if (!prevWordIds.empty()) {
- // TODO: Read n-gram entry.
+ const int bitmapEntryIndex = getBitmapEntryIndex(prevWordIds);
+ if (bitmapEntryIndex == TrieMap::INVALID_INDEX) {
return ProbabilityEntry();
}
- const TrieMap::Result result = mTrieMap.getRoot(wordId);
+ const TrieMap::Result result = mTrieMap.get(wordId, bitmapEntryIndex);
if (!result.mIsValid) {
// Not found.
return ProbabilityEntry();
@@ -46,14 +46,13 @@ ProbabilityEntry LanguageModelDictContent::getNgramProbabilityEntry(
bool LanguageModelDictContent::setNgramProbabilityEntry(const WordIdArrayView prevWordIds,
const int terminalId, const ProbabilityEntry *const probabilityEntry) {
- if (!prevWordIds.empty()) {
- // TODO: Add n-gram entry.
+ const int bitmapEntryIndex = getBitmapEntryIndex(prevWordIds);
+ if (bitmapEntryIndex == TrieMap::INVALID_INDEX) {
return false;
}
- return mTrieMap.putRoot(terminalId, probabilityEntry->encode(mHasHistoricalInfo));
+ return mTrieMap.put(terminalId, probabilityEntry->encode(mHasHistoricalInfo), bitmapEntryIndex);
}
-
bool LanguageModelDictContent::runGCInner(
const TerminalPositionLookupTable::TerminalIdMap *const terminalIdMap,
const TrieMap::TrieMapRange trieMapRange,
@@ -81,4 +80,16 @@ bool LanguageModelDictContent::runGCInner(
return true;
}
+int LanguageModelDictContent::getBitmapEntryIndex(const WordIdArrayView prevWordIds) const {
+ int bitmapEntryIndex = mTrieMap.getRootBitmapEntryIndex();
+ for (const int wordId : prevWordIds) {
+ const TrieMap::Result result = mTrieMap.get(wordId, bitmapEntryIndex);
+ if (!result.mIsValid) {
+ return TrieMap::INVALID_INDEX;
+ }
+ bitmapEntryIndex = result.mNextLevelBitmapEntryIndex;
+ }
+ return bitmapEntryIndex;
+}
+
} // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h
index f181dfeee..18f2e0170 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/language_model_dict_content.h
@@ -76,6 +76,8 @@ class LanguageModelDictContent {
bool runGCInner(const TerminalPositionLookupTable::TerminalIdMap *const terminalIdMap,
const TrieMap::TrieMapRange trieMapRange, const int nextLevelBitmapEntryIndex,
int *const outNgramCount);
+
+ int getBitmapEntryIndex(const WordIdArrayView prevWordIds) const;
};
} // namespace latinime
#endif /* LATINIME_LANGUAGE_MODEL_DICT_CONTENT_H */
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp
index 1a311b156..857222f5d 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp
@@ -222,22 +222,19 @@ bool Ver4PatriciaTrieNodeWriter::writeNewTerminalPtNodeAndAdvancePosition(
terminalId, &probabilityEntryToWrite);
}
-bool Ver4PatriciaTrieNodeWriter::addNewBigramEntry(
- const PtNodeParams *const sourcePtNodeParams, const PtNodeParams *const targetPtNodeParam,
+bool Ver4PatriciaTrieNodeWriter::addNgramEntry(const WordIdArrayView prevWordIds, const int wordId,
const BigramProperty *const bigramProperty, bool *const outAddedNewBigram) {
- if (!mBigramPolicy->addNewEntry(sourcePtNodeParams->getTerminalId(),
- targetPtNodeParam->getTerminalId(), bigramProperty, outAddedNewBigram)) {
+ if (!mBigramPolicy->addNewEntry(prevWordIds[0], wordId, bigramProperty, outAddedNewBigram)) {
AKLOGE("Cannot add new bigram entry. terminalId: %d, targetTerminalId: %d",
- sourcePtNodeParams->getTerminalId(), targetPtNodeParam->getTerminalId());
+ prevWordIds[0], wordId);
return false;
}
return true;
}
-bool Ver4PatriciaTrieNodeWriter::removeBigramEntry(
- const PtNodeParams *const sourcePtNodeParams, const PtNodeParams *const targetPtNodeParam) {
- return mBigramPolicy->removeEntry(sourcePtNodeParams->getTerminalId(),
- targetPtNodeParam->getTerminalId());
+bool Ver4PatriciaTrieNodeWriter::removeNgramEntry(const WordIdArrayView prevWordIds,
+ const int wordId) {
+ return mBigramPolicy->removeEntry(prevWordIds[0], wordId);
}
bool Ver4PatriciaTrieNodeWriter::updateAllBigramEntriesAndDeleteUselessEntries(
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h
index 162dc9b1d..6703dba04 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h
@@ -75,12 +75,10 @@ class Ver4PatriciaTrieNodeWriter : public PtNodeWriter {
virtual bool writeNewTerminalPtNodeAndAdvancePosition(const PtNodeParams *const ptNodeParams,
const UnigramProperty *const unigramProperty, int *const ptNodeWritingPos);
- virtual bool addNewBigramEntry(const PtNodeParams *const sourcePtNodeParams,
- const PtNodeParams *const targetPtNodeParam, const BigramProperty *const bigramProperty,
- bool *const outAddedNewBigram);
+ virtual bool addNgramEntry(const WordIdArrayView prevWordIds, const int wordId,
+ const BigramProperty *const bigramProperty, bool *const outAddedNewEntry);
- virtual bool removeBigramEntry(const PtNodeParams *const sourcePtNodeParams,
- const PtNodeParams *const targetPtNodeParam);
+ virtual bool removeNgramEntry(const WordIdArrayView prevWordIds, const int wordId);
virtual bool updateAllBigramEntriesAndDeleteUselessEntries(
const PtNodeParams *const sourcePtNodeParams, int *const outBigramEntryCount);
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp
index 2b92d5bea..723808399 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp
@@ -292,6 +292,7 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI
int prevWordsPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
prevWordsInfo->getPrevWordsTerminalPtNodePos(this, prevWordsPtNodePos,
false /* tryLowerCaseSearch */);
+ const auto prevWordsPtNodePosView = PtNodePosArrayView::fromFixedSizeArray(prevWordsPtNodePos);
// TODO: Support N-gram.
if (prevWordsPtNodePos[0] == NOT_A_DICT_POS) {
if (prevWordsInfo->isNthPrevWordBeginningOfSentence(1 /* n */)) {
@@ -319,10 +320,10 @@ bool Ver4PatriciaTriePolicy::addNgramEntry(const PrevWordsInfo *const prevWordsI
if (word1Pos == NOT_A_DICT_POS) {
return false;
}
- bool addedNewBigram = false;
- if (mUpdatingHelper.addBigramWords(prevWordsPtNodePos[0], word1Pos, bigramProperty,
- &addedNewBigram)) {
- if (addedNewBigram) {
+ bool addedNewEntry = false;
+ if (mUpdatingHelper.addNgramEntry(prevWordsPtNodePosView, word1Pos, bigramProperty,
+ &addedNewEntry)) {
+ if (addedNewEntry) {
mBigramCount++;
}
return true;
@@ -352,6 +353,7 @@ bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWor
int prevWordsPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
prevWordsInfo->getPrevWordsTerminalPtNodePos(this, prevWordsPtNodePos,
false /* tryLowerCaseSerch */);
+ const auto prevWordsPtNodePosView = PtNodePosArrayView::fromFixedSizeArray(prevWordsPtNodePos);
// TODO: Support N-gram.
if (prevWordsPtNodePos[0] == NOT_A_DICT_POS) {
return false;
@@ -361,7 +363,7 @@ bool Ver4PatriciaTriePolicy::removeNgramEntry(const PrevWordsInfo *const prevWor
if (wordPos == NOT_A_DICT_POS) {
return false;
}
- if (mUpdatingHelper.removeBigramWords(prevWordsPtNodePos[0], wordPos)) {
+ if (mUpdatingHelper.removeNgramEntry(prevWordsPtNodePosView, wordPos)) {
mBigramCount--;
return true;
} else {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/trie_map.h b/native/jni/src/suggest/policyimpl/dictionary/utils/trie_map.h
index a294ab876..3e5c4010c 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/trie_map.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/trie_map.h
@@ -169,6 +169,10 @@ class TrieMap {
return mBuffer.isNearSizeLimit();
}
+ int getRootBitmapEntryIndex() const {
+ return ROOT_BITMAP_ENTRY_INDEX;
+ }
+
// Returns bitmapEntryIndex. Create the next level map if it doesn't exist.
int getNextLevelBitmapEntryIndex(const int key) {
return getNextLevelBitmapEntryIndex(key, ROOT_BITMAP_ENTRY_INDEX);
diff --git a/native/jni/src/utils/int_array_view.h b/native/jni/src/utils/int_array_view.h
index 4bc2487ae..c1ddc9812 100644
--- a/native/jni/src/utils/int_array_view.h
+++ b/native/jni/src/utils/int_array_view.h
@@ -56,6 +56,16 @@ class IntArrayView {
explicit IntArrayView(const std::vector<int> &vector)
: mPtr(vector.data()), mSize(vector.size()) {}
+ template <int N>
+ AK_FORCE_INLINE static IntArrayView fromFixedSizeArray(const int (&array)[N]) {
+ return IntArrayView(array, N);
+ }
+
+ // Returns a view that points one int object. Does not take ownership of the given object.
+ AK_FORCE_INLINE static IntArrayView fromObject(const int *const object) {
+ return IntArrayView(object, 1);
+ }
+
AK_FORCE_INLINE int operator[](const size_t index) const {
ASSERT(index < mSize);
return mPtr[index];
@@ -73,6 +83,14 @@ class IntArrayView {
return mPtr;
}
+ AK_FORCE_INLINE const int *begin() const {
+ return mPtr;
+ }
+
+ AK_FORCE_INLINE const int *end() const {
+ return mPtr + mSize;
+ }
+
private:
DISALLOW_ASSIGNMENT_OPERATOR(IntArrayView);
@@ -81,6 +99,7 @@ class IntArrayView {
};
using WordIdArrayView = IntArrayView;
+using PtNodePosArrayView = IntArrayView;
} // namespace latinime
#endif // LATINIME_MEMORY_VIEW_H
diff --git a/native/jni/tests/utils/int_array_view_test.cpp b/native/jni/tests/utils/int_array_view_test.cpp
index 9aa8cdc8c..bd843ab02 100644
--- a/native/jni/tests/utils/int_array_view_test.cpp
+++ b/native/jni/tests/utils/int_array_view_test.cpp
@@ -23,16 +23,39 @@
namespace latinime {
namespace {
-TEST(MemoryViewTest, TestAccess) {
- static const int DATA_SIZE = 10000;
-
- std::vector<int> intVector = {3, 2, 1, 0, -1, -2};
+TEST(IntArrayViewTest, TestAccess) {
+ const std::vector<int> intVector = {3, 2, 1, 0, -1, -2};
IntArrayView intArrayView(intVector);
EXPECT_EQ(intVector.size(), intArrayView.size());
- for (int i = 0; i < DATA_SIZE; ++i) {
+ for (int i = 0; i < static_cast<int>(intVector.size()); ++i) {
EXPECT_EQ(intVector[i], intArrayView[i]);
}
}
+TEST(IntArrayViewTest, TestIteration) {
+ const std::vector<int> intVector = {3, 2, 1, 0, -1, -2};
+ IntArrayView intArrayView(intVector);
+ size_t expectedIndex = 0;
+ for (const int element : intArrayView) {
+ EXPECT_EQ(intVector[expectedIndex], element);
+ ++expectedIndex;
+ }
+ EXPECT_EQ(expectedIndex, intArrayView.size());
+}
+
+TEST(IntArrayViewTest, TestConstructFromArray) {
+ const size_t ARRAY_SIZE = 100;
+ int intArray[ARRAY_SIZE];
+ const auto intArrayView = IntArrayView::fromFixedSizeArray(intArray);
+ EXPECT_EQ(ARRAY_SIZE, intArrayView.size());
+}
+
+TEST(IntArrayViewTest, TestConstructFromObject) {
+ const int object = 10;
+ const auto intArrayView = IntArrayView::fromObject(&object);
+ EXPECT_EQ(1, intArrayView.size());
+ EXPECT_EQ(object, intArrayView[0]);
+}
+
} // namespace
} // namespace latinime
diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTestsReorderingMyanmar.java b/tests/src/com/android/inputmethod/latin/InputLogicTestsReorderingMyanmar.java
index 61eae4e8b..ab69c8592 100644
--- a/tests/src/com/android/inputmethod/latin/InputLogicTestsReorderingMyanmar.java
+++ b/tests/src/com/android/inputmethod/latin/InputLogicTestsReorderingMyanmar.java
@@ -17,6 +17,7 @@
package com.android.inputmethod.latin;
import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.util.Pair;
/*
@@ -77,6 +78,8 @@ import android.util.Pair;
*/
@LargeTest
+// These tests are inactive until the combining code for Myanmar Reordering is sorted out.
+@Suppress
@SuppressWarnings("rawtypes")
public class InputLogicTestsReorderingMyanmar extends InputTestsBase {
// The tests are formatted as follows.
diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
index 986fb1097..18671fbe8 100644
--- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
@@ -36,6 +36,7 @@ import android.widget.EditText;
import android.widget.FrameLayout;
import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils;
+import com.android.inputmethod.event.Event;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
@@ -263,14 +264,17 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
// but keep them in mind if something breaks. Commenting them out as is should work.
//mLatinIME.onPressKey(codePoint, 0 /* repeatCount */, true /* isSinglePointer */);
final Key key = mKeyboard.getKey(codePoint);
+ final Event event;
if (key == null) {
- mLatinIME.onCodeInput(codePoint, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE,
- isKeyRepeat);
+ event = Event.createSoftwareKeypressEvent(codePoint, Event.NOT_A_KEY_CODE,
+ Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, isKeyRepeat);
} else {
final int x = key.getX() + key.getWidth() / 2;
final int y = key.getY() + key.getHeight() / 2;
- mLatinIME.onCodeInput(codePoint, x, y, isKeyRepeat);
+ event = Event.createSoftwareKeypressEvent(codePoint, Event.NOT_A_KEY_CODE,
+ x, y, isKeyRepeat);
}
+ mLatinIME.onEvent(event);
// Also see the comment at the top of this function about onReleaseKey
//mLatinIME.onReleaseKey(codePoint, false /* withSliding */);
}
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
index 084371944..eabd8d722 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
@@ -802,20 +802,13 @@ public class BinaryDictEncoderUtils {
}
MakedictLog.i("Statistics:\n"
- + " total file size " + size + "\n"
+ + " Total file size " + size + "\n"
+ " " + ptNodeArrays.size() + " node arrays\n"
+ " " + ptNodes + " PtNodes (" + ((float)ptNodes / ptNodeArrays.size())
+ " PtNodes per node)\n"
- + " first terminal at " + firstTerminalAddress + "\n"
- + " last terminal at " + lastTerminalAddress + "\n"
+ + " First terminal at " + firstTerminalAddress + "\n"
+ + " Last terminal at " + lastTerminalAddress + "\n"
+ " PtNode stats : max = " + maxNodes);
- for (int i = 0; i < ptNodeCounts.length; ++i) {
- MakedictLog.i(" " + i + " : " + ptNodeCounts[i]);
- }
- MakedictLog.i(" Character run stats : max = " + maxRuns);
- for (int i = 0; i < runCounts.length; ++i) {
- MakedictLog.i(" " + i + " : " + runCounts[i]);
- }
}
/**