aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--java-overridable/src/com/android/inputmethod/latin/define/ProductionFlags.java8
-rw-r--r--java/AndroidManifest.xml3
-rw-r--r--java/res/raw/setup_welcome_image.pngbin50389 -> 16980 bytes
-rw-r--r--java/res/raw/setup_welcome_video.mp4bin549513 -> 378604 bytes
-rw-r--r--java/res/xml/method.xml14
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java18
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardId.java9
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java6
-rw-r--r--java/src/com/android/inputmethod/keyboard/MainKeyboardView.java5
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java31
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/LanguageOnSpacebarHelper.java8
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitator.java43
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java53
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java11
-rw-r--r--java/src/com/android/inputmethod/latin/SubtypeSwitcher.java30
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java11
-rw-r--r--java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java54
-rw-r--r--java/src/com/android/inputmethod/latin/setup/SetupActivity.java4
-rw-r--r--java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java5
-rw-r--r--java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java11
-rw-r--r--native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp3
-rw-r--r--native/jni/src/defines.h2
-rw-r--r--native/jni/src/suggest/core/dictionary/dictionary.cpp3
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp8
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h31
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.cpp85
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h2
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp5
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.cpp55
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h5
-rw-r--r--tests/src/com/android/inputmethod/keyboard/action/KlpActionLabelTests.java34
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/tests/KeyboardLayoutSetSubtypesCountTests.java4
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliBD.java4
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHinglish.java4
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMyanmarMM.java4
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbianLatin.java4
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbianLatinQwerty.java4
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUzbek.java4
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUzbekQwerty.java4
-rw-r--r--tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java8
-rw-r--r--tests/src/com/android/inputmethod/latin/personalization/ContextualDictionaryTests.java5
-rw-r--r--tests/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryTests.java5
-rw-r--r--tests/src/com/android/inputmethod/latin/utils/SpacebarLanguageUtilsTests.java46
-rw-r--r--tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java50
-rw-r--r--tools/dicttool/compat/android/util/Pair.java7
45 files changed, 393 insertions, 317 deletions
diff --git a/java-overridable/src/com/android/inputmethod/latin/define/ProductionFlags.java b/java-overridable/src/com/android/inputmethod/latin/define/ProductionFlags.java
index 9d7258de7..5738ea2b2 100644
--- a/java-overridable/src/com/android/inputmethod/latin/define/ProductionFlags.java
+++ b/java-overridable/src/com/android/inputmethod/latin/define/ProductionFlags.java
@@ -24,14 +24,6 @@ public final class ProductionFlags {
public static final boolean IS_HARDWARE_KEYBOARD_SUPPORTED = false;
/**
- * When true, enable {@link InputMethodService#onUpdateCursorAnchorInfo} callback via
- * {@link InputConnection#requestUpdateCursorAnchorInfo}. This flag has no effect in API
- * Level 20 and prior. In general, this callback provides detailed positional information,
- * even though an explicit support is required by the editor.
- */
- public static final boolean ENABLE_CURSOR_ANCHOR_INFO_CALLBACK = true;
-
- /**
* Include all suggestions from all dictionaries in {@link SuggestedWords#mRawSuggestions}.
*/
public static final boolean INCLUDE_RAW_SUGGESTIONS = false;
diff --git a/java/AndroidManifest.xml b/java/AndroidManifest.xml
index 25fa0f9e3..ee1cef6b5 100644
--- a/java/AndroidManifest.xml
+++ b/java/AndroidManifest.xml
@@ -89,8 +89,7 @@
<activity android:name=".settings.SettingsActivity"
android:theme="@style/platformSettingsTheme"
- android:label="@string/english_ime_settings"
- android:uiOptions="splitActionBarWhenNarrow">
+ android:label="@string/english_ime_settings">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
diff --git a/java/res/raw/setup_welcome_image.png b/java/res/raw/setup_welcome_image.png
index 98e731331..b72618114 100644
--- a/java/res/raw/setup_welcome_image.png
+++ b/java/res/raw/setup_welcome_image.png
Binary files differ
diff --git a/java/res/raw/setup_welcome_video.mp4 b/java/res/raw/setup_welcome_video.mp4
index 224bf250c..09be565e4 100644
--- a/java/res/raw/setup_welcome_video.mp4
+++ b/java/res/raw/setup_welcome_video.mp4
Binary files differ
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index 8cc66425c..77a46f9c7 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -183,6 +183,7 @@
/>
<!-- TODO: This Bengali (Bangladesh) 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"
android:subtypeId="0xa2144b0c"
@@ -191,6 +192,7 @@
android:imeSubtypeExtraValue="KeyboardLayoutSet=bengali_akkhor,EmojiCapable"
android:isAsciiCapable="false"
/>
+ -->
<subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xbff5986c"
@@ -369,6 +371,7 @@
/>
<!-- TODO: This Hinglish 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_hi_ZZ"
android:subtypeId="0x352eb37c"
@@ -377,6 +380,7 @@
android:imeSubtypeExtraValue="AsciiCapable,KeyboardLayoutSet=qwerty,EmojiCapable"
android:isAsciiCapable="true"
/>
+ -->
<subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x35b7526a"
@@ -549,6 +553,7 @@
/>
<!-- TODO: This Myanmar 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"
android:subtypeId="0xea266ea4"
@@ -557,6 +562,7 @@
android:imeSubtypeExtraValue="KeyboardLayoutSet=myanmar,EmojiCapable,CombiningRules=MyanmarReordering"
android:isAsciiCapable="false"
/>
+ -->
<subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x3f12ee14"
@@ -639,6 +645,7 @@
/>
<!-- TODO: This Sinhala 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"
android:subtypeId="0x5c6b3bde"
@@ -647,6 +654,7 @@
android:imeSubtypeExtraValue="KeyboardLayoutSet=sinhala,EmojiCapable"
android:isAsciiCapable="false"
/>
+ -->
<subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x8e94d413"
@@ -673,6 +681,7 @@
/>
<!-- TODO: This Serbian Latin 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_sr_ZZ"
android:subtypeId="0xf4a5569c"
@@ -681,6 +690,7 @@
android:imeSubtypeExtraValue="KeyboardLayoutSet=serbian_qwertz,AsciiCapable,EmojiCapable"
android:isAsciiCapable="true"
/>
+ -->
<subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x48b4ff43"
@@ -706,6 +716,7 @@
android:isAsciiCapable="false"
/>
<!-- TODO: Enabling/Disabling ta_LK subtype must be aligned with si_LK subtype. -->
+ <!--
<subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x6ca12d84"
@@ -714,6 +725,7 @@
android:imeSubtypeExtraValue="KeyboardLayoutSet=tamil,EmojiCapable"
android:isAsciiCapable="false"
/>
+ -->
<subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x785abbd9"
@@ -764,6 +776,7 @@
/>
<!-- TODO: This Uzbek 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"
android:subtypeId="0xad5cf7f6"
@@ -772,6 +785,7 @@
android:imeSubtypeExtraValue="KeyboardLayoutSet=uzbek,AsciiCapable,EmojiCapable"
android:isAsciiCapable="true"
/>
+ -->
<subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x93972eee"
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index bf29b5ffe..45ce6a85f 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -278,8 +278,8 @@ public class Key implements Comparable<Key> {
mLabelFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags)
| row.getDefaultKeyLabelFlags();
- final boolean needsToUpperCase = needsToUpperCase(mLabelFlags, params.mId.mElementId);
- final Locale locale = params.mId.mLocale;
+ final boolean needsToUpcase = needsToUpcase(mLabelFlags, params.mId.mElementId);
+ final Locale localeForUpcasing = params.mId.getLocales()[0];
int actionFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
@@ -321,7 +321,7 @@ public class Key implements Comparable<Key> {
actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS;
mMoreKeys = new MoreKeySpec[moreKeys.length];
for (int i = 0; i < moreKeys.length; i++) {
- mMoreKeys[i] = new MoreKeySpec(moreKeys[i], needsToUpperCase, locale);
+ mMoreKeys[i] = new MoreKeySpec(moreKeys[i], needsToUpcase, localeForUpcasing);
}
} else {
mMoreKeys = null;
@@ -342,16 +342,16 @@ public class Key implements Comparable<Key> {
mLabel = new StringBuilder().appendCodePoint(code).toString();
} else {
mLabel = StringUtils.toUpperCaseOfStringForLocale(
- KeySpecParser.getLabel(keySpec), needsToUpperCase, locale);
+ KeySpecParser.getLabel(keySpec), needsToUpcase, localeForUpcasing);
}
if ((mLabelFlags & LABEL_FLAGS_DISABLE_HINT_LABEL) != 0) {
mHintLabel = null;
} else {
mHintLabel = StringUtils.toUpperCaseOfStringForLocale(style.getString(keyAttr,
- R.styleable.Keyboard_Key_keyHintLabel), needsToUpperCase, locale);
+ R.styleable.Keyboard_Key_keyHintLabel), needsToUpcase, localeForUpcasing);
}
String outputText = StringUtils.toUpperCaseOfStringForLocale(
- KeySpecParser.getOutputText(keySpec), needsToUpperCase, locale);
+ KeySpecParser.getOutputText(keySpec), needsToUpcase, localeForUpcasing);
// Choose the first letter of the label as primary code if not specified.
if (code == CODE_UNSPECIFIED && TextUtils.isEmpty(outputText)
&& !TextUtils.isEmpty(mLabel)) {
@@ -377,12 +377,12 @@ public class Key implements Comparable<Key> {
mCode = CODE_OUTPUT_TEXT;
}
} else {
- mCode = StringUtils.toUpperCaseOfCodeForLocale(code, needsToUpperCase, locale);
+ mCode = StringUtils.toUpperCaseOfCodeForLocale(code, needsToUpcase, localeForUpcasing);
}
final int altCodeInAttr = KeySpecParser.parseCode(
style.getString(keyAttr, R.styleable.Keyboard_Key_altCode), CODE_UNSPECIFIED);
final int altCode = StringUtils.toUpperCaseOfCodeForLocale(
- altCodeInAttr, needsToUpperCase, locale);
+ altCodeInAttr, needsToUpcase, localeForUpcasing);
mOptionalAttributes = OptionalAttributes.newInstance(outputText, altCode,
disabledIconId, visualInsetsLeft, visualInsetsRight);
mKeyVisualAttributes = KeyVisualAttributes.newInstance(keyAttr);
@@ -432,7 +432,7 @@ public class Key implements Comparable<Key> {
return (filteredMoreKeys == moreKeys) ? key : new Key(key, filteredMoreKeys);
}
- private static boolean needsToUpperCase(final int labelFlags, final int keyboardElementId) {
+ private static boolean needsToUpcase(final int labelFlags, final int keyboardElementId) {
if ((labelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0) return false;
switch (keyboardElementId) {
case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED:
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index f9cf3535e..ab0d63306 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -63,7 +63,6 @@ public final class KeyboardId {
public static final int ELEMENT_EMOJI_CATEGORY6 = 16;
public final RichInputMethodSubtype mSubtype;
- public final Locale mLocale;
public final int mWidth;
public final int mHeight;
public final int mMode;
@@ -79,7 +78,6 @@ public final class KeyboardId {
public KeyboardId(final int elementId, final KeyboardLayoutSet.Params params) {
mSubtype = params.mSubtype;
- mLocale = SubtypeLocaleUtils.getSubtypeLocale(mSubtype);
mWidth = params.mKeyboardWidth;
mHeight = params.mKeyboardHeight;
mMode = params.mMode;
@@ -167,6 +165,10 @@ public final class KeyboardId {
return InputTypeUtils.getImeOptionsActionIdFromEditorInfo(mEditorInfo);
}
+ public Locale[] getLocales() {
+ return mSubtype.getLocales();
+ }
+
@Override
public boolean equals(final Object other) {
return other instanceof KeyboardId && equals((KeyboardId) other);
@@ -181,7 +183,8 @@ public final class KeyboardId {
public String toString() {
return String.format(Locale.ROOT, "[%s %s:%s %dx%d %s %s%s%s%s%s%s%s%s%s]",
elementIdToName(mElementId),
- mLocale, mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET),
+ Arrays.deepToString(mSubtype.getLocales()),
+ mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET),
mWidth, mHeight,
modeName(mMode),
actionName(imeAction()),
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 7f2957fff..93123d1ec 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -120,7 +120,9 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
mKeyboardLayoutSet = builder.build();
try {
mState.onLoadKeyboard(currentAutoCapsState, currentRecapitalizeState);
- mKeyboardTextsSet.setLocale(mSubtypeSwitcher.getCurrentSubtypeLocale(), mThemeContext);
+ // TODO: revisit this for multi-lingual input
+ mKeyboardTextsSet.setLocale(mSubtypeSwitcher.getCurrentSubtypeLocales()[0],
+ mThemeContext);
} catch (KeyboardLayoutSetException e) {
Log.w(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause());
return;
@@ -161,7 +163,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
currentSettingsValues.mKeyPreviewDismissDuration);
keyboardView.updateShortcutKey(mSubtypeSwitcher.isShortcutImeReady());
final boolean subtypeChanged = (oldKeyboard == null)
- || !keyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale);
+ || !keyboard.mId.mSubtype.equals(oldKeyboard.mId.mSubtype);
final int languageOnSpacebarFormatType = mSubtypeSwitcher.getLanguageOnSpacebarFormatType(
keyboard.mId.mSubtype);
final boolean hasMultipleEnabledIMEsOrSubtypes = RichInputMethodManager.getInstance()
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index cded2cb8c..ad30b746e 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -875,6 +875,11 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
// Layout language name on spacebar.
private String layoutLanguageOnSpacebar(final Paint paint,
final RichInputMethodSubtype subtype, final int width) {
+ if (mLanguageOnSpacebarFormatType == LanguageOnSpacebarHelper.FORMAT_TYPE_MULTIPLE) {
+ // TODO: return an appropriate string
+ return "";
+ }
+
// Choose appropriate language name to fit into the width.
if (mLanguageOnSpacebarFormatType == LanguageOnSpacebarHelper.FORMAT_TYPE_FULL_LOCALE) {
final String fullText = subtype.getFullDisplayName();
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index 50385555c..f4e010c4d 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -45,6 +45,7 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.Arrays;
+import java.util.Locale;
/**
* Keyboard Building helper.
@@ -281,7 +282,8 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
params.mThemeId = keyboardAttr.getInt(R.styleable.Keyboard_themeId, 0);
params.mIconsSet.loadIcons(keyboardAttr);
- params.mTextsSet.setLocale(params.mId.mLocale, mContext);
+ // TODO: this needs to be revisited for multi-lingual input.
+ params.mTextsSet.setLocale(params.mId.getLocales()[0], mContext);
final int resourceId = keyboardAttr.getResourceId(
R.styleable.Keyboard_touchPositionCorrectionData, 0);
@@ -672,12 +674,10 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
R.styleable.Keyboard_Case_imeAction, id.imeAction());
final boolean isIconDefinedMatched = isIconDefined(caseAttr,
R.styleable.Keyboard_Case_isIconDefined, mParams.mIconsSet);
- final boolean localeCodeMatched = matchString(caseAttr,
- R.styleable.Keyboard_Case_localeCode, id.mLocale.toString());
- final boolean languageCodeMatched = matchString(caseAttr,
- R.styleable.Keyboard_Case_languageCode, id.mLocale.getLanguage());
- final boolean countryCodeMatched = matchString(caseAttr,
- R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry());
+ final Locale[] locales = id.getLocales();
+ final boolean localeCodeMatched = matchLocaleCodes(caseAttr, locales);
+ final boolean languageCodeMatched = matchLanguageCodes(caseAttr, locales);
+ final boolean countryCodeMatched = matchCountryCodes(caseAttr, locales);
final boolean splitLayoutMatched = matchBoolean(caseAttr,
R.styleable.Keyboard_Case_isSplitLayout, id.mIsSplitLayout);
final boolean selected = keyboardLayoutSetMatched && keyboardLayoutSetElementMatched
@@ -733,6 +733,23 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
}
}
+ private boolean matchLocaleCodes(TypedArray caseAttr, final Locale[] locales) {
+ // TODO: adujst this for multilingual input
+ return matchString(caseAttr, R.styleable.Keyboard_Case_localeCode, locales[0].toString());
+ }
+
+ private boolean matchLanguageCodes(TypedArray caseAttr, Locale[] locales) {
+ // TODO: adujst this for multilingual input
+ return matchString(caseAttr, R.styleable.Keyboard_Case_languageCode,
+ locales[0].getLanguage());
+ }
+
+ private boolean matchCountryCodes(TypedArray caseAttr, Locale[] locales) {
+ // TODO: adujst this for multilingual input
+ return matchString(caseAttr, R.styleable.Keyboard_Case_countryCode,
+ locales[0].getCountry());
+ }
+
private static boolean matchInteger(final TypedArray a, final int index, final int value) {
// If <case> does not have "index" attribute, that means this <case> is wild-card for
// the attribute.
diff --git a/java/src/com/android/inputmethod/keyboard/internal/LanguageOnSpacebarHelper.java b/java/src/com/android/inputmethod/keyboard/internal/LanguageOnSpacebarHelper.java
index 72ad2bd97..21eaed950 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/LanguageOnSpacebarHelper.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/LanguageOnSpacebarHelper.java
@@ -23,6 +23,7 @@ import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
/**
* This class determines that the language name on the spacebar should be displayed in what format.
@@ -31,6 +32,7 @@ public final class LanguageOnSpacebarHelper {
public static final int FORMAT_TYPE_NONE = 0;
public static final int FORMAT_TYPE_LANGUAGE_ONLY = 1;
public static final int FORMAT_TYPE_FULL_LOCALE = 2;
+ public static final int FORMAT_TYPE_MULTIPLE = 3;
private List<InputMethodSubtype> mEnabledSubtypes = Collections.emptyList();
private boolean mIsSystemLanguageSameAsInputLanguage;
@@ -43,7 +45,11 @@ public final class LanguageOnSpacebarHelper {
if (mEnabledSubtypes.size() < 2 && mIsSystemLanguageSameAsInputLanguage) {
return FORMAT_TYPE_NONE;
}
- final String keyboardLanguage = SubtypeLocaleUtils.getSubtypeLocale(subtype).getLanguage();
+ final Locale[] locales = subtype.getLocales();
+ if (1 < locales.length) {
+ return FORMAT_TYPE_MULTIPLE;
+ }
+ final String keyboardLanguage = locales[0].getLanguage();
final String keyboardLayout = SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype);
int sameLanguageAndLayoutCount = 0;
for (final InputMethodSubtype ims : mEnabledSubtypes) {
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index 1f0317288..4a218d550 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -416,33 +416,38 @@ public class DictionaryFacilitator {
}
@UsedForTesting
- public void resetDictionariesForTesting(final Context context, final Locale locale,
+ public void resetDictionariesForTesting(final Context context, final Locale[] locales,
final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles,
final Map<String, Map<String, String>> additionalDictAttributes) {
Dictionary mainDictionary = null;
final Map<String, ExpandableBinaryDictionary> subDicts = new HashMap<>();
- for (final String dictType : dictionaryTypes) {
- if (dictType.equals(Dictionary.TYPE_MAIN)) {
- mainDictionary = DictionaryFactory.createMainDictionaryFromManager(context, locale);
- } else {
- final File dictFile = dictionaryFiles.get(dictType);
- final ExpandableBinaryDictionary dict = getSubDict(
- dictType, context, locale, dictFile, "" /* dictNamePrefix */);
- if (additionalDictAttributes.containsKey(dictType)) {
- dict.clearAndFlushDictionaryWithAdditionalAttributes(
- additionalDictAttributes.get(dictType));
- }
- if (dict == null) {
- throw new RuntimeException("Unknown dictionary type: " + dictType);
+ final DictionaryGroup[] dictionaryGroups = new DictionaryGroup[locales.length];
+ for (int i = 0; i < locales.length; ++i) {
+ final Locale locale = locales[i];
+ for (final String dictType : dictionaryTypes) {
+ if (dictType.equals(Dictionary.TYPE_MAIN)) {
+ mainDictionary = DictionaryFactory.createMainDictionaryFromManager(context,
+ locale);
+ } else {
+ final File dictFile = dictionaryFiles.get(dictType);
+ final ExpandableBinaryDictionary dict = getSubDict(
+ dictType, context, locale, dictFile, "" /* dictNamePrefix */);
+ if (additionalDictAttributes.containsKey(dictType)) {
+ dict.clearAndFlushDictionaryWithAdditionalAttributes(
+ additionalDictAttributes.get(dictType));
+ }
+ if (dict == null) {
+ throw new RuntimeException("Unknown dictionary type: " + dictType);
+ }
+ dict.reloadDictionaryIfRequired();
+ dict.waitAllTasksForTests();
+ subDicts.put(dictType, dict);
}
- dict.reloadDictionaryIfRequired();
- dict.waitAllTasksForTests();
- subDicts.put(dictType, dict);
}
+ dictionaryGroups[i] = new DictionaryGroup(locale, mainDictionary, subDicts);
}
- mDictionaryGroups = new DictionaryGroup[] {
- new DictionaryGroup(locale, mainDictionary, subDicts) };
+ mDictionaryGroups = dictionaryGroups;
}
public void closeDictionaries() {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index be2efb2dc..8e93761a2 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -102,7 +102,7 @@ import com.android.inputmethod.latin.utils.ViewLayoutUtils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
@@ -575,18 +575,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Has to be package-visible for unit tests
@UsedForTesting
void loadSettings() {
- final Locale locale = mSubtypeSwitcher.getCurrentSubtypeLocale();
+ final Locale[] locales = mSubtypeSwitcher.getCurrentSubtypeLocales();
final EditorInfo editorInfo = getCurrentInputEditorInfo();
final InputAttributes inputAttributes = new InputAttributes(
editorInfo, isFullscreenMode(), getPackageName());
- mSettings.loadSettings(this, locale, inputAttributes);
+ // TODO: pass the array instead
+ mSettings.loadSettings(this, locales[0], inputAttributes);
final SettingsValues currentSettingsValues = mSettings.getCurrent();
AudioAndHapticFeedbackManager.getInstance().onSettingsChanged(currentSettingsValues);
// This method is called on startup and language switch, before the new layout has
// been displayed. Opening dictionaries never affects responsivity as dictionaries are
// asynchronously loaded.
if (!mHandler.hasPendingReopenDictionaries()) {
- resetDictionaryFacilitatorForLocale(locale);
+ resetDictionaryFacilitatorForLocale(locales);
}
mDictionaryFacilitator.updateEnabledSubtypes(mRichImm.getMyEnabledInputMethodSubtypeList(
true /* allowsImplicitlySelectedSubtypes */));
@@ -628,35 +629,34 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
private void resetDictionaryFacilitatorIfNecessary() {
- final Locale switcherSubtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
- if (mDictionaryFacilitator.isForLocales(new Locale[] { switcherSubtypeLocale })) {
+ final Locale[] subtypeSwitcherLocales = mSubtypeSwitcher.getCurrentSubtypeLocales();
+ if (mDictionaryFacilitator.isForLocales(subtypeSwitcherLocales)) {
return;
}
- final String switcherLocaleStr = switcherSubtypeLocale.toString();
- final Locale subtypeLocale;
- if (TextUtils.isEmpty(switcherLocaleStr)) {
+ final Locale[] subtypeLocales;
+ if (0 == subtypeSwitcherLocales.length) {
// This happens in very rare corner cases - for example, immediately after a switch
// to LatinIME has been requested, about a frame later another switch happens. In this
// case, we are about to go down but we still don't know it, however the system tells
- // us there is no current subtype so the locale is the empty string. Take the best
- // possible guess instead -- it's bound to have no consequences, and we have no way
- // of knowing anyway.
+ // us there is no current subtype.
Log.e(TAG, "System is reporting no current subtype.");
- subtypeLocale = getResources().getConfiguration().locale;
+ subtypeLocales = new Locale[] { getResources().getConfiguration().locale };
} else {
- subtypeLocale = switcherSubtypeLocale;
+ subtypeLocales = subtypeSwitcherLocales;
}
- resetDictionaryFacilitatorForLocale(subtypeLocale);
+ resetDictionaryFacilitatorForLocale(subtypeLocales);
}
/**
- * Reset the facilitator by loading dictionaries for the locale and the current settings values.
+ * Reset the facilitator by loading dictionaries for the locales and the current settings values
*
- * @param locale the locale
+ * @param locales the locales
*/
- // TODO: make sure the current settings always have the right locale, and read from them
- private void resetDictionaryFacilitatorForLocale(final Locale locale) {
+ // TODO: make sure the current settings always have the right locales, and read from them
+ private void resetDictionaryFacilitatorForLocale(final Locale[] locales) {
final SettingsValues settingsValues = mSettings.getCurrent();
+ // TODO: pass the array instead
+ final Locale locale = locales[0];
mDictionaryFacilitator.resetDictionaries(this /* context */, locale,
settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts,
false /* forceReloadMainDictionary */, this);
@@ -755,12 +755,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (prevExtractEditText == nextExtractEditText) {
return;
}
- if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK && prevExtractEditText != null) {
+ if (prevExtractEditText != null) {
prevExtractEditText.getViewTreeObserver().removeOnPreDrawListener(
mExtractTextViewPreDrawListener);
}
mExtractEditText = nextExtractEditText;
- if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK && mExtractEditText != null) {
+ if (mExtractEditText != null) {
mExtractEditText.getViewTreeObserver().addOnPreDrawListener(
mExtractTextViewPreDrawListener);
}
@@ -776,8 +776,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
};
private void onExtractTextViewPreDraw() {
- if (!ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK || !isFullscreenMode()
- || mExtractEditText == null) {
+ if (!isFullscreenMode() || mExtractEditText == null) {
return;
}
final CursorAnchorInfo info = CursorAnchorInfoUtils.getCursorAnchorInfo(mExtractEditText);
@@ -881,7 +880,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Update to a gesture consumer with the current editor and IME state.
mGestureConsumer = GestureConsumer.newInstance(editorInfo,
mInputLogic.getPrivateCommandPerformer(),
- Collections.singletonList(mSubtypeSwitcher.getCurrentSubtypeLocale()),
+ Arrays.asList(mSubtypeSwitcher.getCurrentSubtypeLocales()),
switcher.getKeyboard());
// Forward this event to the accessibility utilities, if enabled.
@@ -1060,7 +1059,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// We cannot mark this method as @Override until new SDK becomes publicly available.
// @Override
public void onUpdateCursorAnchorInfo(final CursorAnchorInfo info) {
- if (!ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK || isFullscreenMode()) {
+ if (isFullscreenMode()) {
return;
}
mInputLogic.onUpdateCursorAnchorInfo(CursorAnchorInfoCompatWrapper.fromObject(info));
@@ -1434,7 +1433,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void onStartBatchInput() {
mInputLogic.onStartBatchInput(mSettings.getCurrent(), mKeyboardSwitcher, mHandler);
mGestureConsumer.onGestureStarted(
- Collections.singletonList(mSubtypeSwitcher.getCurrentSubtypeLocale()),
+ Arrays.asList(mSubtypeSwitcher.getCurrentSubtypeLocales()),
mKeyboardSwitcher.getKeyboard());
}
@@ -1558,7 +1557,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// We should clear the contextual strip if there is no suggestion from dictionaries.
|| noSuggestionsFromDictionaries) {
mSuggestionStripView.setSuggestions(suggestedWords,
- SubtypeLocaleUtils.isRtlLanguage(mSubtypeSwitcher.getCurrentSubtype()));
+ mSubtypeSwitcher.getCurrentSubtype().isRtlSubtype());
}
}
diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java b/java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java
index 0b08c48e5..8d055531c 100644
--- a/java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java
+++ b/java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java
@@ -114,10 +114,13 @@ public final class RichInputMethodSubtype {
return "Multi-lingual subtype: " + mSubtype.toString() + ", " + Arrays.toString(mLocales);
}
- // TODO: remove this method! We can always have several locales. Multi-lingual input will only
- // be done when this method is gone.
- public String getLocale() {
- return mSubtype.getLocale();
+ public Locale[] getLocales() {
+ return mLocales;
+ }
+
+ public boolean isRtlSubtype() {
+ // The subtype is considered RTL if the language of the main subtype is RTL.
+ return SubtypeLocaleUtils.isRtlLanguage(mLocales[0]);
}
// TODO: remove this method
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index 45d67ff88..c339e96fb 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -170,15 +170,21 @@ public final class SubtypeSwitcher {
Log.w(TAG, "onSubtypeChanged: " + newSubtype.getNameForLogging());
}
- final Locale newLocale = SubtypeLocaleUtils.getSubtypeLocale(newSubtype);
- final Locale systemLocale = mResources.getConfiguration().locale;
- final boolean sameLocale = systemLocale.equals(newLocale);
- final boolean sameLanguage = systemLocale.getLanguage().equals(newLocale.getLanguage());
- final boolean implicitlyEnabled = mRichImm
- .checkIfSubtypeBelongsToThisImeAndImplicitlyEnabled(newSubtype.getRawSubtype());
- mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(
- sameLocale || (sameLanguage && implicitlyEnabled));
-
+ final Locale[] newLocales = newSubtype.getLocales();
+ if (newLocales.length > 1) {
+ // In multi-locales mode, the system language is never the same as the input language
+ // because there is no single input language.
+ mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(false);
+ } else {
+ final Locale newLocale = newLocales[0];
+ final Locale systemLocale = mResources.getConfiguration().locale;
+ final boolean sameLocale = systemLocale.equals(newLocale);
+ final boolean sameLanguage = systemLocale.getLanguage().equals(newLocale.getLanguage());
+ final boolean implicitlyEnabled = mRichImm
+ .checkIfSubtypeBelongsToThisImeAndImplicitlyEnabled(newSubtype.getRawSubtype());
+ mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(
+ sameLocale || (sameLanguage && implicitlyEnabled));
+ }
updateShortcutIME();
}
@@ -284,11 +290,11 @@ public final class SubtypeSwitcher {
sForcedSubtypeForTesting = new RichInputMethodSubtype(subtype);
}
- public Locale getCurrentSubtypeLocale() {
+ public Locale[] getCurrentSubtypeLocales() {
if (null != sForcedSubtypeForTesting) {
- return LocaleUtils.constructLocaleFromString(sForcedSubtypeForTesting.getLocale());
+ return sForcedSubtypeForTesting.getLocales();
}
- return SubtypeLocaleUtils.getSubtypeLocale(getCurrentSubtype());
+ return getCurrentSubtype().getLocales();
}
public RichInputMethodSubtype getCurrentSubtype() {
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 1b1d5e7e5..f67a9a6ef 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -169,14 +169,11 @@ public final class InputLogic {
mInputLogicHandler.reset();
}
- if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK) {
- // AcceptTypedWord feature relies on CursorAnchorInfo.
- if (settingsValues.mShouldShowUiToAcceptTypedWord) {
- mConnection.requestCursorUpdates(true /* enableMonitor */,
- true /* requestImmediateCallback */);
- }
- mTextDecorator.reset();
+ if (settingsValues.mShouldShowUiToAcceptTypedWord) {
+ mConnection.requestCursorUpdates(true /* enableMonitor */,
+ true /* requestImmediateCallback */);
}
+ mTextDecorator.reset();
}
/**
diff --git a/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java
index 2174f5224..c633fc167 100644
--- a/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java
@@ -33,7 +33,6 @@ import android.preference.PreferenceGroup;
import android.support.v4.view.ViewCompat;
import android.text.TextUtils;
import android.util.Log;
-import android.util.Pair;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -80,25 +79,26 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
"is_subtype_enabler_notification_dialog_open";
private static final String KEY_SUBTYPE_FOR_SUBTYPE_ENABLER = "subtype_for_subtype_enabler";
- static final class SubtypeLocaleItem extends Pair<String, String>
- implements Comparable<SubtypeLocaleItem> {
- public SubtypeLocaleItem(final String localeString, final String displayName) {
- super(localeString, displayName);
- }
+ static final class SubtypeLocaleItem implements Comparable<SubtypeLocaleItem> {
+ public final String mLocaleString;
+ private final String mDisplayName;
- public SubtypeLocaleItem(final String localeString) {
- this(localeString,
- SubtypeLocaleUtils.getSubtypeLocaleDisplayNameInSystemLocale(localeString));
+ public SubtypeLocaleItem(final InputMethodSubtype subtype) {
+ mLocaleString = subtype.getLocale();
+ mDisplayName = SubtypeLocaleUtils.getSubtypeLocaleDisplayNameInSystemLocale(
+ mLocaleString);
}
+ // {@link ArrayAdapter<T>} that hosts the instance of this class needs {@link #toString()}
+ // to get display name.
@Override
public String toString() {
- return second;
+ return mDisplayName;
}
@Override
public int compareTo(final SubtypeLocaleItem o) {
- return first.compareTo(o.first);
+ return mLocaleString.compareTo(o.mLocaleString);
}
}
@@ -121,32 +121,28 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype)));
}
if (InputMethodSubtypeCompatUtils.isAsciiCapable(subtype)) {
- items.add(createItem(context, subtype.getLocale()));
+ items.add(new SubtypeLocaleItem(subtype));
}
}
// TODO: Should filter out already existing combinations of locale and layout.
addAll(items);
}
-
- public static SubtypeLocaleItem createItem(final Context context,
- final String localeString) {
- if (localeString.equals(SubtypeLocaleUtils.NO_LANGUAGE)) {
- final String displayName = context.getString(R.string.subtype_no_language);
- return new SubtypeLocaleItem(localeString, displayName);
- }
- return new SubtypeLocaleItem(localeString);
- }
}
- static final class KeyboardLayoutSetItem extends Pair<String, String> {
+ static final class KeyboardLayoutSetItem {
+ public final String mLayoutName;
+ private final String mDisplayName;
+
public KeyboardLayoutSetItem(final InputMethodSubtype subtype) {
- super(SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype),
- SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype));
+ mLayoutName = SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype);
+ mDisplayName = SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype);
}
+ // {@link ArrayAdapter<T>} that hosts the instance of this class needs {@link #toString()}
+ // to get display name.
@Override
public String toString() {
- return second;
+ return mDisplayName;
}
}
@@ -255,7 +251,6 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
@Override
protected void onPrepareDialogBuilder(final AlertDialog.Builder builder) {
- final Context context = builder.getContext();
builder.setCancelable(true).setOnCancelListener(this);
if (isIncomplete()) {
builder.setPositiveButton(R.string.add, this)
@@ -264,8 +259,7 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
builder.setPositiveButton(R.string.save, this)
.setNeutralButton(android.R.string.cancel, this)
.setNegativeButton(R.string.remove, this);
- final SubtypeLocaleItem localeItem = SubtypeLocaleAdapter.createItem(
- context, mSubtype.getLocale());
+ final SubtypeLocaleItem localeItem = new SubtypeLocaleItem(mSubtype);
final KeyboardLayoutSetItem layoutItem = new KeyboardLayoutSetItem(mSubtype);
setSpinnerPosition(mSubtypeLocaleSpinner, localeItem);
setSpinnerPosition(mKeyboardLayoutSetSpinner, layoutItem);
@@ -303,7 +297,7 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
(KeyboardLayoutSetItem) mKeyboardLayoutSetSpinner.getSelectedItem();
final InputMethodSubtype subtype =
AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
- locale.first, layout.first);
+ locale.mLocaleString, layout.mLayoutName);
setSubtype(subtype);
notifyChanged();
if (isEditing) {
@@ -469,8 +463,6 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
KEY_IS_SUBTYPE_ENABLER_NOTIFICATION_DIALOG_OPEN)) {
mSubtypePreferenceKeyForSubtypeEnabler = savedInstanceState.getString(
KEY_SUBTYPE_FOR_SUBTYPE_ENABLER);
- final SubtypePreference subtypePref = (SubtypePreference)findPreference(
- mSubtypePreferenceKeyForSubtypeEnabler);
mSubtypeEnablerNotificationDialog = createDialog();
mSubtypeEnablerNotificationDialog.show();
}
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
index b770ea512..7607429f8 100644
--- a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
+++ b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
@@ -17,12 +17,8 @@
package com.android.inputmethod.latin.setup;
import android.app.Activity;
-import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.provider.Settings;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodManager;
public final class SetupActivity extends Activity {
@Override
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
index e455e53d3..54562f39d 100644
--- a/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
+++ b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
@@ -46,6 +46,8 @@ import java.util.ArrayList;
public final class SetupWizardActivity extends Activity implements View.OnClickListener {
static final String TAG = SetupWizardActivity.class.getSimpleName();
+ // For debugging purpose.
+ private static final boolean FORCE_TO_SHOW_WELCOME_SCREEN = false;
private static final boolean ENABLE_WELCOME_VIDEO = true;
private InputMethodManager mImm;
@@ -304,6 +306,9 @@ public final class SetupWizardActivity extends Activity implements View.OnClickL
private int determineSetupStepNumber() {
mHandler.cancelPollingImeSettings();
+ if (FORCE_TO_SHOW_WELCOME_SCREEN) {
+ return STEP_1;
+ }
if (!UncachedInputMethodManagerUtils.isThisImeEnabled(this, mImm)) {
return STEP_1;
}
diff --git a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
index 5a7f7662c..61661cd52 100644
--- a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
@@ -293,13 +293,6 @@ public final class SubtypeLocaleUtils {
return LocaleUtils.constructLocaleFromString(localeString);
}
- // TODO: remove this. When RichInputMethodSubtype#getLocale is removed we can do away with this
- // method at the same time.
- public static Locale getSubtypeLocale(final RichInputMethodSubtype subtype) {
- final String localeString = subtype.getLocale();
- return LocaleUtils.constructLocaleFromString(localeString);
- }
-
public static String getKeyboardLayoutSetDisplayName(final InputMethodSubtype subtype) {
final String layoutName = getKeyboardLayoutSetName(subtype);
return getKeyboardLayoutSetDisplayName(layoutName);
@@ -348,10 +341,6 @@ public final class SubtypeLocaleUtils {
return Arrays.binarySearch(SORTED_RTL_LANGUAGES, language) >= 0;
}
- public static boolean isRtlLanguage(final RichInputMethodSubtype subtype) {
- return isRtlLanguage(getSubtypeLocale(subtype));
- }
-
public static String getCombiningRulesExtraValue(final InputMethodSubtype subtype) {
return subtype.getExtraValueOf(Constants.Subtype.ExtraValue.COMBINING_RULES);
}
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index 365217a60..76c7fdd6f 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -252,6 +252,9 @@ static void latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jclass clazz,
} else {
dictionary->getPredictions(&prevWordsInfo, &suggestionResults);
}
+ if (DEBUG_DICT) {
+ suggestionResults.dumpSuggestions();
+ }
suggestionResults.outputSuggestions(env, outSuggestionCount, outCodePointsArray,
outScoresArray, outSpaceIndicesArray, outTypesArray,
outAutoCommitFirstWordConfidenceArray, inOutWeightOfLangModelVsSpatialModel);
diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h
index e55c9eb8a..885118524 100644
--- a/native/jni/src/defines.h
+++ b/native/jni/src/defines.h
@@ -119,7 +119,7 @@ static inline void dumpWordInfo(const int *word, const int length, const int ran
const int probability) {
static char charBuf[50];
const int N = intArrayToCharArray(word, length, charBuf, NELEMS(charBuf));
- if (N > 1) {
+ if (N > 0) {
AKLOGI("%2d [ %s ] (%d)", rank, charBuf, probability);
}
}
diff --git a/native/jni/src/suggest/core/dictionary/dictionary.cpp b/native/jni/src/suggest/core/dictionary/dictionary.cpp
index 8d3f8a9f8..7a69d3ceb 100644
--- a/native/jni/src/suggest/core/dictionary/dictionary.cpp
+++ b/native/jni/src/suggest/core/dictionary/dictionary.cpp
@@ -55,9 +55,6 @@ void Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession
suggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
ycoordinates, times, pointerIds, inputCodePoints, inputSize,
weightOfLangModelVsSpatialModel, outSuggestionResults);
- if (DEBUG_DICT) {
- outSuggestionResults->dumpSuggestions();
- }
}
Dictionary::NgramListenerForPrediction::NgramListenerForPrediction(
diff --git a/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp
index 6ed65d921..4c4dfc578 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp
@@ -35,23 +35,15 @@ const char *const HeaderPolicy::EXTENDED_REGION_SIZE_KEY = "EXTENDED_REGION_SIZE
// count.
const char *const HeaderPolicy::HAS_HISTORICAL_INFO_KEY = "HAS_HISTORICAL_INFO";
const char *const HeaderPolicy::LOCALE_KEY = "locale"; // match Java declaration
-const char *const HeaderPolicy::FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP_KEY =
- "FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP";
const char *const HeaderPolicy::FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID_KEY =
"FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID";
-const char *const HeaderPolicy::FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS_KEY =
- "FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS";
const char *const HeaderPolicy::MAX_UNIGRAM_COUNT_KEY = "MAX_UNIGRAM_COUNT";
const char *const HeaderPolicy::MAX_BIGRAM_COUNT_KEY = "MAX_BIGRAM_COUNT";
const int HeaderPolicy::DEFAULT_MULTIPLE_WORDS_DEMOTION_RATE = 100;
const float HeaderPolicy::MULTIPLE_WORD_COST_MULTIPLIER_SCALE = 100.0f;
-const int HeaderPolicy::DEFAULT_FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP = 2;
const int HeaderPolicy::DEFAULT_FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID = 3;
-// 30 days
-const int HeaderPolicy::DEFAULT_FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS =
- 30 * 24 * 60 * 60;
const int HeaderPolicy::DEFAULT_MAX_UNIGRAM_COUNT = 10000;
const int HeaderPolicy::DEFAULT_MAX_BIGRAM_COUNT = 10000;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h b/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h
index daf40d4f9..bc8eaded3 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.h
@@ -53,15 +53,9 @@ class HeaderPolicy : public DictionaryHeaderStructurePolicy {
EXTENDED_REGION_SIZE_KEY, 0 /* defaultValue */)),
mHasHistoricalInfoOfWords(HeaderReadWriteUtils::readBoolAttributeValue(
&mAttributeMap, HAS_HISTORICAL_INFO_KEY, false /* defaultValue */)),
- mForgettingCurveOccurrencesToLevelUp(HeaderReadWriteUtils::readIntAttributeValue(
- &mAttributeMap, FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP_KEY,
- DEFAULT_FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP)),
mForgettingCurveProbabilityValuesTableId(HeaderReadWriteUtils::readIntAttributeValue(
&mAttributeMap, FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID_KEY,
DEFAULT_FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID)),
- mForgettingCurveDurationToLevelDown(HeaderReadWriteUtils::readIntAttributeValue(
- &mAttributeMap, FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS_KEY,
- DEFAULT_FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS)),
mMaxUnigramCount(HeaderReadWriteUtils::readIntAttributeValue(
&mAttributeMap, MAX_UNIGRAM_COUNT_KEY, DEFAULT_MAX_UNIGRAM_COUNT)),
mMaxBigramCount(HeaderReadWriteUtils::readIntAttributeValue(
@@ -86,15 +80,9 @@ class HeaderPolicy : public DictionaryHeaderStructurePolicy {
mUnigramCount(0), mBigramCount(0), mExtendedRegionSize(0),
mHasHistoricalInfoOfWords(HeaderReadWriteUtils::readBoolAttributeValue(
&mAttributeMap, HAS_HISTORICAL_INFO_KEY, false /* defaultValue */)),
- mForgettingCurveOccurrencesToLevelUp(HeaderReadWriteUtils::readIntAttributeValue(
- &mAttributeMap, FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP_KEY,
- DEFAULT_FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP)),
mForgettingCurveProbabilityValuesTableId(HeaderReadWriteUtils::readIntAttributeValue(
&mAttributeMap, FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID_KEY,
DEFAULT_FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID)),
- mForgettingCurveDurationToLevelDown(HeaderReadWriteUtils::readIntAttributeValue(
- &mAttributeMap, FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS_KEY,
- DEFAULT_FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS)),
mMaxUnigramCount(HeaderReadWriteUtils::readIntAttributeValue(
&mAttributeMap, MAX_UNIGRAM_COUNT_KEY, DEFAULT_MAX_UNIGRAM_COUNT)),
mMaxBigramCount(HeaderReadWriteUtils::readIntAttributeValue(
@@ -113,12 +101,8 @@ class HeaderPolicy : public DictionaryHeaderStructurePolicy {
mUnigramCount(headerPolicy->mUnigramCount), mBigramCount(headerPolicy->mBigramCount),
mExtendedRegionSize(headerPolicy->mExtendedRegionSize),
mHasHistoricalInfoOfWords(headerPolicy->mHasHistoricalInfoOfWords),
- mForgettingCurveOccurrencesToLevelUp(
- headerPolicy->mForgettingCurveOccurrencesToLevelUp),
mForgettingCurveProbabilityValuesTableId(
headerPolicy->mForgettingCurveProbabilityValuesTableId),
- mForgettingCurveDurationToLevelDown(
- headerPolicy->mForgettingCurveDurationToLevelDown),
mMaxUnigramCount(headerPolicy->mMaxUnigramCount),
mMaxBigramCount(headerPolicy->mMaxBigramCount),
mCodePointTable(headerPolicy->mCodePointTable) {}
@@ -130,8 +114,7 @@ class HeaderPolicy : public DictionaryHeaderStructurePolicy {
mRequiresGermanUmlautProcessing(false), mIsDecayingDict(false),
mDate(0), mLastDecayedTime(0), mUnigramCount(0), mBigramCount(0),
mExtendedRegionSize(0), mHasHistoricalInfoOfWords(false),
- mForgettingCurveOccurrencesToLevelUp(0), mForgettingCurveProbabilityValuesTableId(0),
- mForgettingCurveDurationToLevelDown(0), mMaxUnigramCount(0), mMaxBigramCount(0),
+ mForgettingCurveProbabilityValuesTableId(0), mMaxUnigramCount(0), mMaxBigramCount(0),
mCodePointTable(nullptr) {}
~HeaderPolicy() {}
@@ -217,18 +200,10 @@ class HeaderPolicy : public DictionaryHeaderStructurePolicy {
return &mAttributeMap;
}
- AK_FORCE_INLINE int getForgettingCurveOccurrencesToLevelUp() const {
- return mForgettingCurveOccurrencesToLevelUp;
- }
-
AK_FORCE_INLINE int getForgettingCurveProbabilityValuesTableId() const {
return mForgettingCurveProbabilityValuesTableId;
}
- AK_FORCE_INLINE int getForgettingCurveDurationToLevelDown() const {
- return mForgettingCurveDurationToLevelDown;
- }
-
AK_FORCE_INLINE int getMaxUnigramCount() const {
return mMaxUnigramCount;
}
@@ -280,9 +255,7 @@ class HeaderPolicy : public DictionaryHeaderStructurePolicy {
static const char *const MAX_BIGRAM_COUNT_KEY;
static const int DEFAULT_MULTIPLE_WORDS_DEMOTION_RATE;
static const float MULTIPLE_WORD_COST_MULTIPLIER_SCALE;
- static const int DEFAULT_FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP;
static const int DEFAULT_FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID;
- static const int DEFAULT_FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS;
static const int DEFAULT_MAX_UNIGRAM_COUNT;
static const int DEFAULT_MAX_BIGRAM_COUNT;
@@ -300,9 +273,7 @@ class HeaderPolicy : public DictionaryHeaderStructurePolicy {
const int mBigramCount;
const int mExtendedRegionSize;
const bool mHasHistoricalInfoOfWords;
- const int mForgettingCurveOccurrencesToLevelUp;
const int mForgettingCurveProbabilityValuesTableId;
- const int mForgettingCurveDurationToLevelDown;
const int mMaxUnigramCount;
const int mMaxBigramCount;
const int *const mCodePointTable;
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 11f7b305f..36eafa1e9 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
@@ -146,18 +146,15 @@ const WordAttributes Ver4PatriciaTriePolicy::getWordAttributes(const int probabi
int Ver4PatriciaTriePolicy::getProbability(const int unigramProbability,
const int bigramProbability) const {
- if (mHeaderPolicy->isDecayingDict()) {
- // Both probabilities are encoded. Decode them and get probability.
- return ForgettingCurveUtils::getProbability(unigramProbability, bigramProbability);
- } else {
- if (unigramProbability == NOT_A_PROBABILITY) {
- return NOT_A_PROBABILITY;
- } else if (bigramProbability == NOT_A_PROBABILITY) {
- return ProbabilityUtils::backoff(unigramProbability);
- } else {
- return bigramProbability;
- }
+ // In the v4 format, bigramProbability is a conditional probability.
+ const int bigramConditionalProbability = bigramProbability;
+ if (unigramProbability == NOT_A_PROBABILITY) {
+ return NOT_A_PROBABILITY;
}
+ if (bigramConditionalProbability == NOT_A_PROBABILITY) {
+ return ProbabilityUtils::backoff(unigramProbability);
+ }
+ return bigramConditionalProbability;
}
int Ver4PatriciaTriePolicy::getProbabilityOfWord(const WordIdArrayView prevWordIds,
@@ -170,37 +167,66 @@ int Ver4PatriciaTriePolicy::getProbabilityOfWord(const WordIdArrayView prevWordI
if (ptNodeParams.isDeleted() || ptNodeParams.isBlacklisted() || ptNodeParams.isNotAWord()) {
return NOT_A_PROBABILITY;
}
- if (!prevWordIds.empty()) {
- const int bigramsPosition = getBigramsPositionOfPtNode(
- getTerminalPtNodePosFromWordId(prevWordIds[0]));
- BinaryDictionaryBigramsIterator bigramsIt(&mBigramPolicy, bigramsPosition);
- while (bigramsIt.hasNext()) {
- bigramsIt.next();
- if (bigramsIt.getBigramPos() == ptNodePos
- && bigramsIt.getProbability() != NOT_A_PROBABILITY) {
- return getProbability(ptNodeParams.getProbability(), bigramsIt.getProbability());
- }
- }
+ if (prevWordIds.empty()) {
+ return getProbability(ptNodeParams.getProbability(), NOT_A_PROBABILITY);
+ }
+ if (prevWordIds[0] == NOT_A_WORD_ID) {
return NOT_A_PROBABILITY;
}
- return getProbability(ptNodeParams.getProbability(), NOT_A_PROBABILITY);
+ const PtNodeParams prevWordPtNodeParams =
+ mNodeReader.fetchPtNodeParamsInBufferFromPtNodePos(prevWordIds[0]);
+ if (prevWordPtNodeParams.isDeleted()) {
+ return getProbability(ptNodeParams.getProbability(), NOT_A_PROBABILITY);
+ }
+ const int bigramsPosition = mBuffers->getBigramDictContent()->getBigramListHeadPos(
+ prevWordPtNodeParams.getTerminalId());
+ BinaryDictionaryBigramsIterator bigramsIt(&mBigramPolicy, bigramsPosition);
+ while (bigramsIt.hasNext()) {
+ bigramsIt.next();
+ if (bigramsIt.getBigramPos() == ptNodePos
+ && bigramsIt.getProbability() != NOT_A_PROBABILITY) {
+ const int bigramConditionalProbability = getBigramConditionalProbability(
+ prevWordPtNodeParams.getProbability(), bigramsIt.getProbability());
+ return getProbability(ptNodeParams.getProbability(), bigramConditionalProbability);
+ }
+ }
+ return NOT_A_PROBABILITY;
}
void Ver4PatriciaTriePolicy::iterateNgramEntries(const WordIdArrayView prevWordIds,
NgramListener *const listener) const {
- if (prevWordIds.empty()) {
+ if (prevWordIds.firstOrDefault(NOT_A_DICT_POS) == NOT_A_DICT_POS) {
+ return;
+ }
+ const PtNodeParams prevWordPtNodeParams =
+ mNodeReader.fetchPtNodeParamsInBufferFromPtNodePos(prevWordIds[0]);
+ if (prevWordPtNodeParams.isDeleted()) {
return;
}
- const int bigramsPosition = getBigramsPositionOfPtNode(
- getTerminalPtNodePosFromWordId(prevWordIds[0]));
+ const int bigramsPosition = mBuffers->getBigramDictContent()->getBigramListHeadPos(
+ prevWordPtNodeParams.getTerminalId());
BinaryDictionaryBigramsIterator bigramsIt(&mBigramPolicy, bigramsPosition);
while (bigramsIt.hasNext()) {
bigramsIt.next();
- listener->onVisitEntry(bigramsIt.getProbability(),
+ const int bigramConditionalProbability = getBigramConditionalProbability(
+ prevWordPtNodeParams.getProbability(), bigramsIt.getProbability());
+ listener->onVisitEntry(bigramConditionalProbability,
getWordIdFromTerminalPtNodePos(bigramsIt.getBigramPos()));
}
}
+int Ver4PatriciaTriePolicy::getBigramConditionalProbability(const int prevWordUnigramProbability,
+ const int bigramProbability) const {
+ if (mHeaderPolicy->hasHistoricalInfoOfWords()) {
+ // Calculate conditional probability.
+ return std::min(MAX_PROBABILITY - prevWordUnigramProbability + bigramProbability,
+ MAX_PROBABILITY);
+ } else {
+ // bigramProbability is a conditional probability.
+ return bigramProbability;
+ }
+}
+
BinaryDictionaryShortcutIterator Ver4PatriciaTriePolicy::getShortcutIterator(
const int wordId) const {
const int shortcutPos = getShortcutPositionOfPtNode(getTerminalPtNodePosFromWordId(wordId));
@@ -428,7 +454,10 @@ bool Ver4PatriciaTriePolicy::updateCounter(const PrevWordsInfo *const prevWordsI
AKLOGE("Cannot update unigarm entry in updateCounter().");
return false;
}
- const NgramProperty ngramProperty(wordCodePoints.toVector(), probability, historicalInfo);
+ const int probabilityForNgram = prevWordsInfo->isNthPrevWordBeginningOfSentence(1 /* n */)
+ ? NOT_A_PROBABILITY : probability;
+ const NgramProperty ngramProperty(wordCodePoints.toVector(), probabilityForNgram,
+ historicalInfo);
if (!addNgramEntry(prevWordsInfo, &ngramProperty)) {
AKLOGE("Cannot update unigarm entry in updateCounter().");
return false;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h
index 995d7764f..b82563e61 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/backward/v402/ver4_patricia_trie_policy.h
@@ -174,6 +174,8 @@ class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
int getTerminalPtNodePosFromWordId(const int wordId) const;
const WordAttributes getWordAttributes(const int probability,
const PtNodeParams &ptNodeParams) const;
+ int getBigramConditionalProbability(const int prevWordUnigramProbability,
+ const int bigramProbability) const;
};
} // namespace v402
} // namespace backward
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 41b109f95..036197c41 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
@@ -378,7 +378,10 @@ bool Ver4PatriciaTriePolicy::updateCounter(const PrevWordsInfo *const prevWordsI
AKLOGE("Cannot update unigarm entry in updateCounter().");
return false;
}
- const NgramProperty ngramProperty(wordCodePoints.toVector(), probability, historicalInfo);
+ const int probabilityForNgram = prevWordsInfo->isNthPrevWordBeginningOfSentence(1 /* n */)
+ ? NOT_A_PROBABILITY : probability;
+ const NgramProperty ngramProperty(wordCodePoints.toVector(), probabilityForNgram,
+ historicalInfo);
for (size_t i = 1; i <= prevWordsInfo->getPrevWordCount(); ++i) {
const PrevWordsInfo trimmedPrevWordsInfo(prevWordsInfo->getTrimmedPrevWordsInfo(i));
if (!addNgramEntry(&trimmedPrevWordsInfo, &ngramProperty)) {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.cpp
index af4bc186a..e5ef2abf8 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.cpp
@@ -29,10 +29,14 @@ namespace latinime {
const int ForgettingCurveUtils::MULTIPLIER_TWO_IN_PROBABILITY_SCALE = 8;
const int ForgettingCurveUtils::DECAY_INTERVAL_SECONDS = 2 * 60 * 60;
-const int ForgettingCurveUtils::MAX_LEVEL = 3;
-const int ForgettingCurveUtils::MIN_VISIBLE_LEVEL = 1;
-const int ForgettingCurveUtils::MAX_ELAPSED_TIME_STEP_COUNT = 15;
-const int ForgettingCurveUtils::DISCARD_LEVEL_ZERO_ENTRY_TIME_STEP_COUNT_THRESHOLD = 14;
+const int ForgettingCurveUtils::MAX_LEVEL = 15;
+const int ForgettingCurveUtils::MIN_VISIBLE_LEVEL = 2;
+const int ForgettingCurveUtils::MAX_ELAPSED_TIME_STEP_COUNT = 31;
+const int ForgettingCurveUtils::DISCARD_LEVEL_ZERO_ENTRY_TIME_STEP_COUNT_THRESHOLD = 30;
+const int ForgettingCurveUtils::OCCURRENCES_TO_RAISE_THE_LEVEL = 1;
+// TODO: Evaluate whether this should be 7.5 days.
+// 15 days
+const int ForgettingCurveUtils::DURATION_TO_LOWER_THE_LEVEL_IN_SECONDS = 15 * 24 * 60 * 60;
const float ForgettingCurveUtils::UNIGRAM_COUNT_HARD_LIMIT_WEIGHT = 1.2;
const float ForgettingCurveUtils::BIGRAM_COUNT_HARD_LIMIT_WEIGHT = 1.2;
@@ -54,19 +58,23 @@ const ForgettingCurveUtils::ProbabilityTable ForgettingCurveUtils::sProbabilityT
|| (originalHistoricalInfo->getLevel() == newHistoricalInfo->getLevel()
&& originalHistoricalInfo->getCount() < newHistoricalInfo->getCount())) {
// Initial information.
+ int count = newHistoricalInfo->getCount();
+ if (count >= OCCURRENCES_TO_RAISE_THE_LEVEL) {
+ const int level = clampToValidLevelRange(newHistoricalInfo->getLevel() + 1);
+ return HistoricalInfo(timestamp, level, 0 /* count */);
+ }
const int level = clampToValidLevelRange(newHistoricalInfo->getLevel());
- const int count = clampToValidCountRange(newHistoricalInfo->getCount(), headerPolicy);
- return HistoricalInfo(timestamp, level, count);
+ return HistoricalInfo(timestamp, level, clampToValidCountRange(count, headerPolicy));
} else {
const int updatedCount = originalHistoricalInfo->getCount() + 1;
- if (updatedCount >= headerPolicy->getForgettingCurveOccurrencesToLevelUp()) {
+ if (updatedCount >= OCCURRENCES_TO_RAISE_THE_LEVEL) {
// The count exceeds the max value the level can be incremented.
if (originalHistoricalInfo->getLevel() >= MAX_LEVEL) {
// The level is already max.
return HistoricalInfo(timestamp,
originalHistoricalInfo->getLevel(), originalHistoricalInfo->getCount());
} else {
- // Level up.
+ // Raise the level.
return HistoricalInfo(timestamp,
originalHistoricalInfo->getLevel() + 1, 0 /* count */);
}
@@ -79,31 +87,18 @@ const ForgettingCurveUtils::ProbabilityTable ForgettingCurveUtils::sProbabilityT
/* static */ int ForgettingCurveUtils::decodeProbability(
const HistoricalInfo *const historicalInfo, const HeaderPolicy *const headerPolicy) {
const int elapsedTimeStepCount = getElapsedTimeStepCount(historicalInfo->getTimestamp(),
- headerPolicy->getForgettingCurveDurationToLevelDown());
+ DURATION_TO_LOWER_THE_LEVEL_IN_SECONDS);
return sProbabilityTable.getProbability(
headerPolicy->getForgettingCurveProbabilityValuesTableId(),
clampToValidLevelRange(historicalInfo->getLevel()),
clampToValidTimeStepCountRange(elapsedTimeStepCount));
}
-/* static */ int ForgettingCurveUtils::getProbability(const int unigramProbability,
- const int bigramProbability) {
- if (unigramProbability == NOT_A_PROBABILITY) {
- return NOT_A_PROBABILITY;
- } else if (bigramProbability == NOT_A_PROBABILITY) {
- return std::min(backoff(unigramProbability), MAX_PROBABILITY);
- } else {
- // TODO: Investigate better way to handle bigram probability.
- return std::min(std::max(unigramProbability,
- bigramProbability + MULTIPLIER_TWO_IN_PROBABILITY_SCALE), MAX_PROBABILITY);
- }
-}
-
/* static */ bool ForgettingCurveUtils::needsToKeep(const HistoricalInfo *const historicalInfo,
const HeaderPolicy *const headerPolicy) {
return historicalInfo->getLevel() > 0
|| getElapsedTimeStepCount(historicalInfo->getTimestamp(),
- headerPolicy->getForgettingCurveDurationToLevelDown())
+ DURATION_TO_LOWER_THE_LEVEL_IN_SECONDS)
< DISCARD_LEVEL_ZERO_ENTRY_TIME_STEP_COUNT_THRESHOLD;
}
@@ -113,14 +108,14 @@ const ForgettingCurveUtils::ProbabilityTable ForgettingCurveUtils::sProbabilityT
if (originalHistoricalInfo->getTimestamp() == NOT_A_TIMESTAMP) {
return HistoricalInfo();
}
- const int durationToLevelDownInSeconds = headerPolicy->getForgettingCurveDurationToLevelDown();
+ const int durationToLevelDownInSeconds = DURATION_TO_LOWER_THE_LEVEL_IN_SECONDS;
const int elapsedTimeStep = getElapsedTimeStepCount(
originalHistoricalInfo->getTimestamp(), durationToLevelDownInSeconds);
if (elapsedTimeStep <= MAX_ELAPSED_TIME_STEP_COUNT) {
// No need to update historical info.
return *originalHistoricalInfo;
}
- // Level down.
+ // Lower the level.
const int maxLevelDownAmonut = elapsedTimeStep / (MAX_ELAPSED_TIME_STEP_COUNT + 1);
const int levelDownAmount = (maxLevelDownAmonut >= originalHistoricalInfo->getLevel()) ?
originalHistoricalInfo->getLevel() : maxLevelDownAmonut;
@@ -170,7 +165,7 @@ const ForgettingCurveUtils::ProbabilityTable ForgettingCurveUtils::sProbabilityT
/* static */ int ForgettingCurveUtils::clampToValidCountRange(const int count,
const HeaderPolicy *const headerPolicy) {
- return std::min(std::max(count, 0), headerPolicy->getForgettingCurveOccurrencesToLevelUp() - 1);
+ return std::min(std::max(count, 0), OCCURRENCES_TO_RAISE_THE_LEVEL - 1);
}
/* static */ int ForgettingCurveUtils::clampToValidLevelRange(const int level) {
@@ -187,9 +182,9 @@ const int ForgettingCurveUtils::ProbabilityTable::MODEST_PROBABILITY_TABLE_ID =
const int ForgettingCurveUtils::ProbabilityTable::STRONG_PROBABILITY_TABLE_ID = 2;
const int ForgettingCurveUtils::ProbabilityTable::AGGRESSIVE_PROBABILITY_TABLE_ID = 3;
const int ForgettingCurveUtils::ProbabilityTable::WEAK_MAX_PROBABILITY = 127;
-const int ForgettingCurveUtils::ProbabilityTable::MODEST_BASE_PROBABILITY = 32;
-const int ForgettingCurveUtils::ProbabilityTable::STRONG_BASE_PROBABILITY = 35;
-const int ForgettingCurveUtils::ProbabilityTable::AGGRESSIVE_BASE_PROBABILITY = 40;
+const int ForgettingCurveUtils::ProbabilityTable::MODEST_BASE_PROBABILITY = 8;
+const int ForgettingCurveUtils::ProbabilityTable::STRONG_BASE_PROBABILITY = 9;
+const int ForgettingCurveUtils::ProbabilityTable::AGGRESSIVE_BASE_PROBABILITY = 10;
ForgettingCurveUtils::ProbabilityTable::ProbabilityTable() : mTables() {
@@ -202,7 +197,7 @@ ForgettingCurveUtils::ProbabilityTable::ProbabilityTable() : mTables() {
const float endProbability = getBaseProbabilityForLevel(tableId, level - 1);
for (int timeStepCount = 0; timeStepCount <= MAX_ELAPSED_TIME_STEP_COUNT;
++timeStepCount) {
- if (level == 0) {
+ if (level < MIN_VISIBLE_LEVEL) {
mTables[tableId][level][timeStepCount] = NOT_A_PROBABILITY;
continue;
}
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h b/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h
index 10abb405a..ccbc4a98d 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h
@@ -39,9 +39,6 @@ class ForgettingCurveUtils {
static int decodeProbability(const HistoricalInfo *const historicalInfo,
const HeaderPolicy *const headerPolicy);
- static int getProbability(const int encodedUnigramProbability,
- const int encodedBigramProbability);
-
static bool needsToKeep(const HistoricalInfo *const historicalInfo,
const HeaderPolicy *const headerPolicy);
@@ -101,6 +98,8 @@ class ForgettingCurveUtils {
static const int MIN_VISIBLE_LEVEL;
static const int MAX_ELAPSED_TIME_STEP_COUNT;
static const int DISCARD_LEVEL_ZERO_ENTRY_TIME_STEP_COUNT_THRESHOLD;
+ static const int OCCURRENCES_TO_RAISE_THE_LEVEL;
+ static const int DURATION_TO_LOWER_THE_LEVEL_IN_SECONDS;
static const float UNIGRAM_COUNT_HARD_LIMIT_WEIGHT;
static const float BIGRAM_COUNT_HARD_LIMIT_WEIGHT;
diff --git a/tests/src/com/android/inputmethod/keyboard/action/KlpActionLabelTests.java b/tests/src/com/android/inputmethod/keyboard/action/KlpActionLabelTests.java
index 74343cb6a..07c604e59 100644
--- a/tests/src/com/android/inputmethod/keyboard/action/KlpActionLabelTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/action/KlpActionLabelTests.java
@@ -131,7 +131,7 @@ public class KlpActionLabelTests extends KlpActionTestsBase {
textsSet.getText("label_done_key"));
final ExpectedActionKey previousKey = ExpectedActionKey.newLabelKey(
textsSet.getText("label_previous_key"));
- final String tag = "label=hi_ZZ system=" + systemLocale
+ final String tag = "label=" + subtype.getLocale() + " system=" + systemLocale
+ " " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype);
final RunInLocale<Void> job = new RunInLocale<Void>() {
@Override
@@ -147,26 +147,34 @@ public class KlpActionLabelTests extends KlpActionTestsBase {
public void testHinglishActionLabel() {
final RichInputMethodManager richImm = RichInputMethodManager.getInstance();
final Locale hi_ZZ = new Locale("hi", "ZZ");
- final InputMethodSubtype hinglish = richImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+ final InputMethodSubtype hiLatn = richImm.findSubtypeByLocaleAndKeyboardLayoutSet(
hi_ZZ.toString(), SubtypeLocaleUtils.QWERTY);
+ // This is a preliminary subtype and may not exist.
+ if (hiLatn == null) {
+ return;
+ }
// An action label should be displayed in subtype's locale regardless of the system locale.
- doTestActionKeysInLocaleWithKeyboardTextsSet(hinglish, hi_ZZ, hi_ZZ);
- doTestActionKeysInLocaleWithKeyboardTextsSet(hinglish, hi_ZZ, Locale.US);
- doTestActionKeysInLocaleWithKeyboardTextsSet(hinglish, hi_ZZ, Locale.FRENCH);
- doTestActionKeysInLocaleWithKeyboardTextsSet(hinglish, hi_ZZ, Locale.ITALIAN);
- doTestActionKeysInLocaleWithKeyboardTextsSet(hinglish, hi_ZZ, Locale.JAPANESE);
+ doTestActionKeysInLocaleWithKeyboardTextsSet(hiLatn, hi_ZZ, new Locale("hi"));
+ doTestActionKeysInLocaleWithKeyboardTextsSet(hiLatn, hi_ZZ, Locale.US);
+ doTestActionKeysInLocaleWithKeyboardTextsSet(hiLatn, hi_ZZ, Locale.FRENCH);
+ doTestActionKeysInLocaleWithKeyboardTextsSet(hiLatn, hi_ZZ, Locale.ITALIAN);
+ doTestActionKeysInLocaleWithKeyboardTextsSet(hiLatn, hi_ZZ, Locale.JAPANESE);
}
public void testSerbianLatinActionLabel() {
final RichInputMethodManager richImm = RichInputMethodManager.getInstance();
final Locale sr_ZZ = new Locale("sr", "ZZ");
- final InputMethodSubtype hinglish = richImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+ final InputMethodSubtype srLatn = richImm.findSubtypeByLocaleAndKeyboardLayoutSet(
sr_ZZ.toString(), "serbian_qwertz");
+ // This is a preliminary subtype and may not exist.
+ if (srLatn == null) {
+ return;
+ }
// An action label should be displayed in subtype's locale regardless of the system locale.
- doTestActionKeysInLocaleWithKeyboardTextsSet(hinglish, sr_ZZ, sr_ZZ);
- doTestActionKeysInLocaleWithKeyboardTextsSet(hinglish, sr_ZZ, Locale.US);
- doTestActionKeysInLocaleWithKeyboardTextsSet(hinglish, sr_ZZ, Locale.FRENCH);
- doTestActionKeysInLocaleWithKeyboardTextsSet(hinglish, sr_ZZ, Locale.ITALIAN);
- doTestActionKeysInLocaleWithKeyboardTextsSet(hinglish, sr_ZZ, Locale.JAPANESE);
+ doTestActionKeysInLocaleWithKeyboardTextsSet(srLatn, sr_ZZ, new Locale("sr"));
+ doTestActionKeysInLocaleWithKeyboardTextsSet(srLatn, sr_ZZ, Locale.US);
+ doTestActionKeysInLocaleWithKeyboardTextsSet(srLatn, sr_ZZ, Locale.FRENCH);
+ doTestActionKeysInLocaleWithKeyboardTextsSet(srLatn, sr_ZZ, Locale.ITALIAN);
+ doTestActionKeysInLocaleWithKeyboardTextsSet(srLatn, sr_ZZ, Locale.JAPANESE);
}
}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/KeyboardLayoutSetSubtypesCountTests.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/KeyboardLayoutSetSubtypesCountTests.java
index 6f747b377..2134eb5fe 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/KeyboardLayoutSetSubtypesCountTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/KeyboardLayoutSetSubtypesCountTests.java
@@ -27,8 +27,8 @@ import java.util.ArrayList;
@SmallTest
public class KeyboardLayoutSetSubtypesCountTests extends KeyboardLayoutSetTestsBase {
- private static final int NUMBER_OF_SUBTYPES = 85;
- private static final int NUMBER_OF_ASCII_CAPABLE_SUBTYPES = 50;
+ private static final int NUMBER_OF_SUBTYPES = 78;
+ private static final int NUMBER_OF_ASCII_CAPABLE_SUBTYPES = 47;
private static final int NUMBER_OF_PREDEFINED_ADDITIONAL_SUBTYPES = 2;
@Override
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliBD.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliBD.java
index 62625890e..c39a392eb 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliBD.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliBD.java
@@ -16,7 +16,7 @@
package com.android.inputmethod.keyboard.layout.tests;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
import com.android.inputmethod.keyboard.layout.BengaliAkkhor;
import com.android.inputmethod.keyboard.layout.LayoutBase;
@@ -29,7 +29,7 @@ import java.util.Locale;
/**
* bn_BD: Bengali (Bangladesh)/bengali_akkhor
*/
-@SmallTest
+@Suppress
public final class TestsBengaliBD extends LayoutTestsBase {
private static final Locale LOCALE = new Locale("bn", "BD");
private static final LayoutBase LAYOUT = new BengaliAkkhor(new BengaliBDCustomzier(LOCALE));
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHinglish.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHinglish.java
index 613b3bbc2..a8e872316 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHinglish.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHinglish.java
@@ -16,7 +16,7 @@
package com.android.inputmethod.keyboard.layout.tests;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
import com.android.inputmethod.keyboard.layout.LayoutBase;
import com.android.inputmethod.keyboard.layout.Qwerty;
@@ -30,7 +30,7 @@ import java.util.Locale;
/*
* hi_ZZ: Hinglish/qwerty
*/
-@SmallTest
+@Suppress
public final class TestsHinglish extends LayoutTestsBase {
private static final Locale LOCALE = new Locale("hi", "ZZ");
private static final LayoutBase LAYOUT = new Qwerty(new HinglishCustomizer(LOCALE));
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMyanmarMM.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMyanmarMM.java
index b581e4a12..18baa6152 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMyanmarMM.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMyanmarMM.java
@@ -16,7 +16,7 @@
package com.android.inputmethod.keyboard.layout.tests;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
import com.android.inputmethod.keyboard.layout.LayoutBase;
import com.android.inputmethod.keyboard.layout.Myanmar;
@@ -26,7 +26,7 @@ import java.util.Locale;
/**
* my_MM: Myanmar (Myanmar)/myanmar
*/
-@SmallTest
+@Suppress
public final class TestsMyanmarMM extends LayoutTestsBase {
private static final Locale LOCALE = new Locale("my", "MM");
private static final LayoutBase LAYOUT = new Myanmar(LOCALE);
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbianLatin.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbianLatin.java
index 7490d30ab..ea957e44f 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbianLatin.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbianLatin.java
@@ -16,7 +16,7 @@
package com.android.inputmethod.keyboard.layout.tests;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
import com.android.inputmethod.keyboard.layout.LayoutBase;
import com.android.inputmethod.keyboard.layout.SerbianQwertz;
@@ -27,7 +27,7 @@ import java.util.Locale;
/**
* sr_ZZ: Serbian (Latin)/serbian_qwertz
*/
-@SmallTest
+@Suppress
public final class TestsSerbianLatin extends LayoutTestsBase {
private static final Locale LOCALE = new Locale("sr", "ZZ");
private static final LayoutBase LAYOUT = new SerbianQwertz(new SerbianLatinCustomizer(LOCALE));
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbianLatinQwerty.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbianLatinQwerty.java
index 6d9351c9d..a1984735d 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbianLatinQwerty.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbianLatinQwerty.java
@@ -16,7 +16,7 @@
package com.android.inputmethod.keyboard.layout.tests;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
import com.android.inputmethod.keyboard.layout.LayoutBase;
import com.android.inputmethod.keyboard.layout.Qwerty;
@@ -29,7 +29,7 @@ import java.util.Locale;
/**
* sr_ZZ: Serbian (Latin)/qwerty
*/
-@SmallTest
+@Suppress
public final class TestsSerbianLatinQwerty extends LayoutTestsBase {
private static final Locale LOCALE = new Locale("sr", "ZZ");
private static final LayoutBase LAYOUT = new Qwerty(new SerbianLatinQwertyCustomizer(LOCALE));
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUzbek.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUzbek.java
index fd12a6a82..169de1f31 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUzbek.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUzbek.java
@@ -16,7 +16,7 @@
package com.android.inputmethod.keyboard.layout.tests;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
import com.android.inputmethod.keyboard.layout.LayoutBase;
import com.android.inputmethod.keyboard.layout.Uzbek;
@@ -27,7 +27,7 @@ import java.util.Locale;
/**
* uz_UZ: Uzbek (Uzbekistan)/uzbek
*/
-@SmallTest
+@Suppress
public final class TestsUzbek extends LayoutTestsBase {
private static final Locale LOCALE = new Locale("uz", "UZ");
private static final LayoutBase LAYOUT = new Uzbek(new UzbekCustomizer(LOCALE));
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUzbekQwerty.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUzbekQwerty.java
index 4c33a8cc1..c210da163 100644
--- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUzbekQwerty.java
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUzbekQwerty.java
@@ -16,7 +16,7 @@
package com.android.inputmethod.keyboard.layout.tests;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
import com.android.inputmethod.keyboard.layout.LayoutBase;
import com.android.inputmethod.keyboard.layout.Qwerty;
@@ -28,7 +28,7 @@ import java.util.Locale;
/**
* uz_UZ: Uzbek (Uzbekistan)/qwerty
*/
-@SmallTest
+@Suppress
public final class TestsUzbekQwerty extends LayoutTestsBase {
private static final Locale LOCALE = new Locale("uz", "UZ");
private static final LayoutBase LAYOUT = new Qwerty(new UzbekQwertyCustomizer(LOCALE));
diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
index c3c2bb2fd..0e58b7211 100644
--- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
+++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
@@ -611,17 +611,23 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
mCurrentTime);
final NgramContext beginningOfSentenceContext = NgramContext.BEGINNING_OF_SENTENCE;
onInputWordWithBeginningOfSentenceContext(binaryDictionary, "aaa", true /* isValidWord */);
+ assertFalse(binaryDictionary.isValidNgram(beginningOfSentenceContext, "aaa"));
+ onInputWordWithBeginningOfSentenceContext(binaryDictionary, "aaa", true /* isValidWord */);
assertTrue(binaryDictionary.isValidNgram(beginningOfSentenceContext, "aaa"));
onInputWordWithBeginningOfSentenceContext(binaryDictionary, "aaa", true /* isValidWord */);
onInputWordWithBeginningOfSentenceContext(binaryDictionary, "bbb", true /* isValidWord */);
+ assertFalse(binaryDictionary.isValidNgram(beginningOfSentenceContext, "bbb"));
onInputWordWithBeginningOfSentenceContext(binaryDictionary, "bbb", true /* isValidWord */);
assertTrue(binaryDictionary.isValidNgram(beginningOfSentenceContext, "aaa"));
assertTrue(binaryDictionary.isValidNgram(beginningOfSentenceContext, "bbb"));
forcePassingLongTime(binaryDictionary);
assertFalse(binaryDictionary.isValidNgram(beginningOfSentenceContext, "aaa"));
assertFalse(binaryDictionary.isValidNgram(beginningOfSentenceContext, "bbb"));
-
onInputWordWithBeginningOfSentenceContext(binaryDictionary, "aaa", true /* isValidWord */);
+ assertFalse(binaryDictionary.isValidNgram(beginningOfSentenceContext, "aaa"));
+ onInputWordWithBeginningOfSentenceContext(binaryDictionary, "aaa", true /* isValidWord */);
+ onInputWordWithBeginningOfSentenceContext(binaryDictionary, "bbb", true /* isValidWord */);
+ assertFalse(binaryDictionary.isValidNgram(beginningOfSentenceContext, "bbb"));
onInputWordWithBeginningOfSentenceContext(binaryDictionary, "bbb", true /* isValidWord */);
assertTrue(binaryDictionary.isValidNgram(beginningOfSentenceContext, "aaa"));
assertTrue(binaryDictionary.isValidNgram(beginningOfSentenceContext, "bbb"));
diff --git a/tests/src/com/android/inputmethod/latin/personalization/ContextualDictionaryTests.java b/tests/src/com/android/inputmethod/latin/personalization/ContextualDictionaryTests.java
index 565fadb2a..011309942 100644
--- a/tests/src/com/android/inputmethod/latin/personalization/ContextualDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/personalization/ContextualDictionaryTests.java
@@ -42,8 +42,9 @@ public class ContextualDictionaryTests extends AndroidTestCase {
final ArrayList<String> dictTypes = new ArrayList<>();
dictTypes.add(Dictionary.TYPE_CONTEXTUAL);
final DictionaryFacilitator dictionaryFacilitator = new DictionaryFacilitator();
- dictionaryFacilitator.resetDictionariesForTesting(getContext(), LOCALE_EN_US, dictTypes,
- new HashMap<String, File>(), new HashMap<String, Map<String, String>>());
+ dictionaryFacilitator.resetDictionariesForTesting(getContext(),
+ new Locale[] { LOCALE_EN_US }, dictTypes, new HashMap<String, File>(),
+ new HashMap<String, Map<String, String>>());
return dictionaryFacilitator;
}
diff --git a/tests/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryTests.java b/tests/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryTests.java
index 4e7e8140a..afabbbd38 100644
--- a/tests/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryTests.java
@@ -55,8 +55,9 @@ public class PersonalizationDictionaryTests extends AndroidTestCase {
dictTypes.add(Dictionary.TYPE_MAIN);
dictTypes.add(Dictionary.TYPE_PERSONALIZATION);
final DictionaryFacilitator dictionaryFacilitator = new DictionaryFacilitator(getContext());
- dictionaryFacilitator.resetDictionariesForTesting(getContext(), LOCALE_EN_US, dictTypes,
- new HashMap<String, File>(), new HashMap<String, Map<String, String>>());
+ dictionaryFacilitator.resetDictionariesForTesting(getContext(),
+ new Locale[] { LOCALE_EN_US }, dictTypes, new HashMap<String, File>(),
+ new HashMap<String, Map<String, String>>());
// Set subtypes.
RichInputMethodManager.init(getContext());
final RichInputMethodManager richImm = RichInputMethodManager.getInstance();
diff --git a/tests/src/com/android/inputmethod/latin/utils/SpacebarLanguageUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/SpacebarLanguageUtilsTests.java
index b766ab2e7..e6131cf65 100644
--- a/tests/src/com/android/inputmethod/latin/utils/SpacebarLanguageUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/SpacebarLanguageUtilsTests.java
@@ -45,7 +45,6 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
RichInputMethodSubtype FR_CH;
RichInputMethodSubtype DE;
RichInputMethodSubtype DE_CH;
- RichInputMethodSubtype HI_ZZ;
RichInputMethodSubtype ZZ;
RichInputMethodSubtype DE_QWERTY;
RichInputMethodSubtype FR_QWERTZ;
@@ -55,6 +54,9 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
RichInputMethodSubtype ZZ_AZERTY;
RichInputMethodSubtype ZZ_PC;
+ // This is a preliminary subtype and may not exist.
+ RichInputMethodSubtype HI_LATN;
+
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -87,8 +89,6 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
Locale.GERMAN.toString(), "qwertz"));
DE_CH = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
"de_CH", "swiss"));
- HI_ZZ = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
- "hi_ZZ", "qwerty"));
ZZ = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
SubtypeLocaleUtils.NO_LANGUAGE, "qwerty"));
DE_QWERTY = new RichInputMethodSubtype(
@@ -112,6 +112,12 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
ZZ_PC = new RichInputMethodSubtype(
AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
SubtypeLocaleUtils.NO_LANGUAGE, "pcqwerty"));
+
+ final InputMethodSubtype hiLatn = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+ "hi_ZZ", "qwerty");
+ if (hiLatn != null) {
+ HI_LATN = new RichInputMethodSubtype(hiLatn);
+ }
}
public void testAllFullDisplayNameForSpacebar() {
@@ -119,12 +125,17 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
final String subtypeName = SubtypeLocaleUtils
.getSubtypeDisplayNameInSystemLocale(subtype.getRawSubtype());
final String spacebarText = subtype.getFullDisplayName();
- final String languageName = SubtypeLocaleUtils
- .getSubtypeLocaleDisplayName(subtype.getLocale());
- if (subtype.isNoLanguage()) {
- assertFalse(subtypeName, spacebarText.contains(languageName));
+ final Locale[] locales = subtype.getLocales();
+ if (1 == locales.length) {
+ final String languageName = SubtypeLocaleUtils
+ .getSubtypeLocaleDisplayName(locales[0].toString());
+ if (subtype.isNoLanguage()) {
+ assertFalse(subtypeName, spacebarText.contains(languageName));
+ } else {
+ assertTrue(subtypeName, spacebarText.contains(languageName));
+ }
} else {
- assertTrue(subtypeName, spacebarText.contains(languageName));
+ // TODO: test multi-lingual subtype spacebar display
}
}
}
@@ -133,8 +144,14 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
for (final RichInputMethodSubtype subtype : mSubtypesList) {
final String subtypeName = SubtypeLocaleUtils
.getSubtypeDisplayNameInSystemLocale(subtype.getRawSubtype());
+ final Locale[] locales = subtype.getLocales();
+ if (locales.length > 1) {
+ // TODO: test multi-lingual subtype spacebar display
+ continue;
+ }
+ final Locale locale = locales[0];
if (SubtypeLocaleUtils.sExceptionalLocaleDisplayedInRootLocale.contains(
- subtype.getLocale())) {
+ locale.toString())) {
// Skip test because the language part of this locale string doesn't represent
// the locale to be displayed on the spacebar (for example hi_ZZ and Hinglish).
continue;
@@ -144,7 +161,6 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
assertEquals(subtypeName, SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(
subtype.getRawSubtype()), spacebarText);
} else {
- final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
assertEquals(subtypeName,
SubtypeLocaleUtils.getSubtypeLocaleDisplayName(locale.getLanguage()),
spacebarText);
@@ -182,8 +198,11 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
assertEquals("fr_CH", "Français (Suisse)", FR_CH.getFullDisplayName());
assertEquals("de", "Deutsch", DE.getFullDisplayName());
assertEquals("de_CH", "Deutsch (Schweiz)", DE_CH.getFullDisplayName());
- assertEquals("hi_ZZ", "Hinglish", HI_ZZ.getFullDisplayName());
assertEquals("zz", "QWERTY", ZZ.getFullDisplayName());
+ // This is a preliminary subtype and may not exist.
+ if (HI_LATN != null) {
+ assertEquals("hi_ZZ", "Hinglish", HI_LATN.getFullDisplayName());
+ }
assertEquals("en_US", "English", EN_US.getMiddleDisplayName());
assertEquals("en_GB", "English", EN_GB.getMiddleDisplayName());
@@ -193,8 +212,11 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
assertEquals("fr_CH", "Français", FR_CH.getMiddleDisplayName());
assertEquals("de", "Deutsch", DE.getMiddleDisplayName());
assertEquals("de_CH", "Deutsch", DE_CH.getMiddleDisplayName());
- assertEquals("hi_ZZ", "Hinglish", HI_ZZ.getMiddleDisplayName());
assertEquals("zz", "QWERTY", ZZ.getMiddleDisplayName());
+ // This is a preliminary subtype and may not exist.
+ if (HI_LATN != null) {
+ assertEquals("hi_ZZ", "Hinglish", HI_LATN.getMiddleDisplayName());
+ }
return null;
}
};
diff --git a/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java
index c095e6831..dfc3fecfd 100644
--- a/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java
@@ -45,7 +45,6 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
InputMethodSubtype FR_CH;
InputMethodSubtype DE;
InputMethodSubtype DE_CH;
- InputMethodSubtype HI_ZZ;
InputMethodSubtype ZZ;
InputMethodSubtype DE_QWERTY;
InputMethodSubtype FR_QWERTZ;
@@ -55,6 +54,9 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
InputMethodSubtype ZZ_AZERTY;
InputMethodSubtype ZZ_PC;
+ // This is a preliminary subtype and may not exist.
+ InputMethodSubtype HI_LATN;
+
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -87,8 +89,6 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
Locale.GERMAN.toString(), "qwertz");
DE_CH = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
"de_CH", "swiss");
- HI_ZZ = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
- "hi_ZZ", "qwerty");
ZZ = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
SubtypeLocaleUtils.NO_LANGUAGE, "qwerty");
DE_QWERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
@@ -105,20 +105,27 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
SubtypeLocaleUtils.NO_LANGUAGE, "azerty");
ZZ_PC = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
SubtypeLocaleUtils.NO_LANGUAGE, "pcqwerty");
+
+ HI_LATN = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet("hi_ZZ", "qwerty");
}
public void testAllFullDisplayName() {
for (final RichInputMethodSubtype subtype : mSubtypesList) {
final String subtypeName = SubtypeLocaleUtils
.getSubtypeDisplayNameInSystemLocale(subtype.getRawSubtype());
- if (subtype.isNoLanguage()) {
- final String layoutName = SubtypeLocaleUtils
- .getKeyboardLayoutSetDisplayName(subtype.getRawSubtype());
- assertTrue(subtypeName, subtypeName.contains(layoutName));
+ final Locale[] locales = subtype.getLocales();
+ if (1 == locales.length) {
+ if (subtype.isNoLanguage()) {
+ final String layoutName = SubtypeLocaleUtils
+ .getKeyboardLayoutSetDisplayName(subtype.getRawSubtype());
+ assertTrue(subtypeName, subtypeName.contains(layoutName));
+ } else {
+ final String languageName = SubtypeLocaleUtils
+ .getSubtypeLocaleDisplayNameInSystemLocale(locales[0].toString());
+ assertTrue(subtypeName, subtypeName.contains(languageName));
+ }
} else {
- final String languageName = SubtypeLocaleUtils
- .getSubtypeLocaleDisplayNameInSystemLocale(subtype.getLocale());
- assertTrue(subtypeName, subtypeName.contains(languageName));
+ // TODO: test multi-lingual subtype spacebar display
}
}
}
@@ -132,8 +139,11 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
assertEquals("fr_CH", "swiss", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR_CH));
assertEquals("de", "qwertz", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE));
assertEquals("de_CH", "swiss", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE_CH));
- assertEquals("hi_ZZ", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(HI_ZZ));
assertEquals("zz", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(ZZ));
+ // This is a preliminary subtype and may not exist.
+ if (HI_LATN != null) {
+ assertEquals("hi_ZZ", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(HI_LATN));
+ }
assertEquals("de qwerty", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE_QWERTY));
assertEquals("fr qwertz", "qwertz", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR_QWERTZ));
@@ -188,10 +198,13 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE));
assertEquals("de_CH", "German (Switzerland)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_CH));
- assertEquals("hi_ZZ", "Hinglish",
- SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(HI_ZZ));
assertEquals("zz", "Alphabet (QWERTY)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ));
+ // This is a preliminary subtype and may not exist.
+ if (HI_LATN != null) {
+ assertEquals("hi_ZZ", "Hinglish",
+ SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(HI_LATN));
+ }
return null;
}
};
@@ -263,10 +276,13 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE));
assertEquals("de_CH", "Allemand (Suisse)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_CH));
- assertEquals("hi_ZZ", "Hindi/Anglais",
- SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(HI_ZZ));
assertEquals("zz", "Alphabet latin (QWERTY)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ));
+ // This is a preliminary subtype and may not exist.
+ if (HI_LATN != null) {
+ assertEquals("hi_ZZ", "Hindi/Anglais",
+ SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(HI_LATN));
+ }
return null;
}
};
@@ -315,9 +331,9 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
.getSubtypeDisplayNameInSystemLocale(rawSubtype);
if (rawSubtype.equals(ARABIC) || rawSubtype.equals(FARSI)
|| rawSubtype.equals(HEBREW)) {
- assertTrue(subtypeName, SubtypeLocaleUtils.isRtlLanguage(subtype));
+ assertTrue(subtypeName, subtype.isRtlSubtype());
} else {
- assertFalse(subtypeName, SubtypeLocaleUtils.isRtlLanguage(subtype));
+ assertFalse(subtypeName, subtype.isRtlSubtype());
}
}
}
diff --git a/tools/dicttool/compat/android/util/Pair.java b/tools/dicttool/compat/android/util/Pair.java
index 5bf34848d..ab6096ee3 100644
--- a/tools/dicttool/compat/android/util/Pair.java
+++ b/tools/dicttool/compat/android/util/Pair.java
@@ -17,6 +17,7 @@
package android.util;
import java.util.Arrays;
+import java.util.Objects;
public class Pair<T1, T2> {
public final T1 mFirst;
@@ -29,7 +30,8 @@ public class Pair<T1, T2> {
@Override
public int hashCode() {
- return Arrays.hashCode(new Object[] { mFirst, mSecond });
+ return (mFirst == null ? 0 : mFirst.hashCode())
+ ^ (mSecond == null ? 0 : mSecond.hashCode());
}
@Override
@@ -37,7 +39,6 @@ public class Pair<T1, T2> {
if (o == this) return true;
if (!(o instanceof Pair)) return false;
Pair<?, ?> p = (Pair<?, ?>)o;
- return ((mFirst == null && p.mFirst == null) || mFirst.equals(p.mFirst))
- && ((mSecond == null && p.mSecond == null) || mSecond.equals(p.mSecond));
+ return Objects.equals(mFirst, p.mFirst) && Objects.equals(mSecond, p.mSecond);
}
}