aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java106
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java12
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryStats.java35
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java11
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java30
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputMethodManager.java3
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FormatSpec.java93
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java6
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java208
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java10
-rw-r--r--java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java22
11 files changed, 270 insertions, 266 deletions
diff --git a/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java b/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java
index be7bf402d..862ec8a58 100644
--- a/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java
@@ -16,67 +16,35 @@
package com.android.inputmethod.compat;
-import android.util.Log;
import android.view.inputmethod.InputConnection;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
+import android.view.inputmethod.InputMethodManager;
public final class InputConnectionCompatUtils {
- private static final String TAG = InputConnectionCompatUtils.class.getSimpleName();
-
- // Note that CursorAnchorInfoRequest is supposed to be available in API level 21 and later.
- private static Class<?> getCursorAnchorInfoRequestClass() {
- try {
- return Class.forName("android.view.inputmethod.CursorAnchorInfoRequest");
- } catch (ClassNotFoundException e) {
- return null;
- }
- }
-
- private static final Class<?> TYPE_CursorAnchorInfoRequest;
- private static final Constructor<?> CONSTRUCTOR_CursorAnchorInfoRequest;
- private static final Method METHOD_requestCursorAnchorInfo;
+ private static final CompatUtils.ClassWrapper sInputConnectionType;
+ private static final CompatUtils.ToBooleanMethodWrapper sRequestUpdateCursorAnchorInfoMethod;
static {
- TYPE_CursorAnchorInfoRequest = getCursorAnchorInfoRequestClass();
- CONSTRUCTOR_CursorAnchorInfoRequest = CompatUtils.getConstructor(
- TYPE_CursorAnchorInfoRequest, int.class, int.class);
- METHOD_requestCursorAnchorInfo = CompatUtils.getMethod(InputConnection.class,
- "requestCursorAnchorInfo", TYPE_CursorAnchorInfoRequest);
+ sInputConnectionType = new CompatUtils.ClassWrapper(InputConnection.class);
+ sRequestUpdateCursorAnchorInfoMethod = sInputConnectionType.getPrimitiveMethod(
+ "requestUpdateCursorAnchorInfo", false, int.class);
}
- public static boolean isRequestCursorAnchorInfoAvailable() {
- return METHOD_requestCursorAnchorInfo != null &&
- CONSTRUCTOR_CursorAnchorInfoRequest != null;
+ public static boolean isRequestUpdateCursorAnchorInfoAvailable() {
+ return sRequestUpdateCursorAnchorInfoMethod != null;
}
/**
* Local copies of some constants in CursorAnchorInfoRequest until the SDK becomes publicly
* available.
*/
- private final static int RESULT_NOT_HANDLED = 0;
- private final static int RESULT_SCHEDULED = 1;
- private final static int TYPE_CURSOR_ANCHOR_INFO = 1;
- private final static int FLAG_CURSOR_ANCHOR_INFO_MONITOR = 1;
- private final static int FLAG_CURSOR_ANCHOR_INFO_IMMEDIATE = 2;
- private final static int TYPE_CURSOR_RECT = 2;
- private final static int FLAG_CURSOR_RECT_MONITOR = 1;
- private final static int FLAG_CURSOR_RECT_IN_SCREEN_COORDINATES = 2;
- private final static int FLAG_CURSOR_RECT_WITH_VIEW_MATRIX = 4;
+ private static int REQUEST_UPDATE_CURSOR_UPDATE_IMMEDIATE = 1 << 0;
+ private static int REQUEST_UPDATE_CURSOR_UPDATE_MONITOR = 1 << 1;
- private static int requestCursorAnchorInfoImpl(final InputConnection inputConnection,
- final int type, final int flags) {
- if (!isRequestCursorAnchorInfoAvailable()) {
- return RESULT_NOT_HANDLED;
- }
- final Object requestObject = CompatUtils.newInstance(
- CONSTRUCTOR_CursorAnchorInfoRequest, type, flags);
- if (requestObject == null) {
- return RESULT_NOT_HANDLED;
+ private static boolean requestUpdateCursorAnchorInfoImpl(final InputConnection inputConnection,
+ final int cursorUpdateMode) {
+ if (!isRequestUpdateCursorAnchorInfoAvailable()) {
+ return false;
}
- return (Integer) CompatUtils.invoke(inputConnection,
- RESULT_NOT_HANDLED /* defaultValue */,
- METHOD_requestCursorAnchorInfo, requestObject);
+ return sRequestUpdateCursorAnchorInfoMethod.invoke(inputConnection, cursorUpdateMode);
}
/**
@@ -88,47 +56,11 @@ public final class InputConnectionCompatUtils {
* as soon as possible to notify the current cursor/anchor position to the input method.
* @return {@code false} if the request is not handled. Otherwise returns {@code true}.
*/
- public static boolean requestCursorAnchorInfo(final InputConnection inputConnection,
+ public static boolean requestUpdateCursorAnchorInfo(final InputConnection inputConnection,
final boolean enableMonitor, final boolean requestImmediateCallback) {
- final int requestFlags = (enableMonitor ? FLAG_CURSOR_ANCHOR_INFO_MONITOR : 0)
- | (requestImmediateCallback ? FLAG_CURSOR_ANCHOR_INFO_IMMEDIATE : 0);
- final int requestResult = requestCursorAnchorInfoImpl(inputConnection,
- TYPE_CURSOR_ANCHOR_INFO, requestFlags);
- switch (requestResult) {
- case RESULT_NOT_HANDLED:
- return false;
- case RESULT_SCHEDULED:
- return true;
- default:
- Log.w(TAG, "requestCursorAnchorInfo returned unknown result=" + requestResult
- + " for type=TYPE_CURSOR_ANCHOR_INFO flags=" + requestFlags);
- return true;
- }
+ final int cursorUpdateMode = (enableMonitor ? REQUEST_UPDATE_CURSOR_UPDATE_MONITOR : 0)
+ | (requestImmediateCallback ? REQUEST_UPDATE_CURSOR_UPDATE_IMMEDIATE : 0);
+ return requestUpdateCursorAnchorInfoImpl(inputConnection, cursorUpdateMode);
}
- /**
- * Requests the editor to call back {@link InputMethodManager#updateCursor}.
- * @param inputConnection the input connection to which the request is to be sent.
- * @param enableMonitor {@code true} to request the editor to call back the method whenever the
- * cursor position is changed.
- * @return {@code false} if the request is not handled. Otherwise returns {@code true}.
- */
- public static boolean requestCursorRect(final InputConnection inputConnection,
- final boolean enableMonitor) {
- final int requestFlags = enableMonitor ?
- FLAG_CURSOR_RECT_MONITOR | FLAG_CURSOR_RECT_IN_SCREEN_COORDINATES |
- FLAG_CURSOR_RECT_WITH_VIEW_MATRIX : 0;
- final int requestResult = requestCursorAnchorInfoImpl(inputConnection, TYPE_CURSOR_RECT,
- requestFlags);
- switch (requestResult) {
- case RESULT_NOT_HANDLED:
- return false;
- case RESULT_SCHEDULED:
- return true;
- default:
- Log.w(TAG, "requestCursorAnchorInfo returned unknown result=" + requestResult
- + " for type=TYPE_CURSOR_RECT flags=" + requestFlags);
- return true;
- }
- }
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
index 31bc549ca..0e3acff84 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
@@ -94,7 +94,7 @@ public final class KeyboardTextsTable {
/* 8:22 */ "morekeys_n",
/* 9:22 */ "single_quotes",
/* 10:20 */ "morekeys_s",
- /* 11:17 */ "keyspec_currency",
+ /* 11:18 */ "keyspec_currency",
/* 12:14 */ "morekeys_y",
/* 13:13 */ "morekeys_d",
/* 14:12 */ "morekeys_z",
@@ -1874,6 +1874,15 @@ public final class KeyboardTextsTable {
/* additional_morekeys_symbols_0 */ "0",
};
+ /* Locale hi_ZZ: Hindi (ZZ) */
+ private static final String[] TEXTS_hi_ZZ = {
+ /* morekeys_a ~ */
+ null, null, null, null, null, null, null, null, null, null, null,
+ /* ~ morekeys_s */
+ // U+20B9: "₹" INDIAN RUPEE SIGN
+ /* keyspec_currency */ "\u20B9",
+ };
+
/* Locale hr: Croatian */
private static final String[] TEXTS_hr = {
/* morekeys_a ~ */
@@ -3957,6 +3966,7 @@ public final class KeyboardTextsTable {
"fr" , TEXTS_fr, /* 13/ 62 French */
"gl_ES" , TEXTS_gl_ES, /* 7/ 9 Gallegan (Spain) */
"hi" , TEXTS_hi, /* 23/ 53 Hindi */
+ "hi_ZZ" , TEXTS_hi_ZZ, /* 1/ 12 Hindi (ZZ) */
"hr" , TEXTS_hr, /* 9/ 20 Croatian */
"hu" , TEXTS_hu, /* 9/ 20 Hungarian */
"hy_AM" , TEXTS_hy_AM, /* 9/126 Armenian (Armenia) */
diff --git a/java/src/com/android/inputmethod/latin/DictionaryStats.java b/java/src/com/android/inputmethod/latin/DictionaryStats.java
new file mode 100644
index 000000000..75aa2411d
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/DictionaryStats.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin;
+
+import java.io.File;
+import java.util.Locale;
+
+public class DictionaryStats {
+ public final Locale mLocale;
+ public final String mDictName;
+ public final String mDictFilePath;
+ public final long mDictFileSize;
+ // TODO: Add more members.
+
+ public DictionaryStats(final Locale locale, final String dictName, final File dictFile) {
+ mLocale = locale;
+ mDictName = dictName;
+ mDictFilePath = dictFile.getAbsolutePath();
+ mDictFileSize = dictFile.length();
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 22b91700c..de384037f 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -644,6 +644,17 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
});
}
+ public DictionaryStats getDictionaryStats() {
+ reloadDictionaryIfRequired();
+ mLock.readLock().lock();
+ try {
+ // TODO: Get stats form the dictionary.
+ return new DictionaryStats(mLocale, mDictName, mDictFile);
+ } finally {
+ mLock.readLock().unlock();
+ }
+ }
+
@UsedForTesting
public void waitAllTasksForTests() {
final CountDownLatch countDownLatch = new CountDownLatch(1);
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 8768e126e..e1d809907 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -420,18 +420,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (latinIme != null) {
executePendingImsCallback(latinIme, editorInfo, restarting);
latinIme.onStartInputInternal(editorInfo, restarting);
- if (ProductionFlags.ENABLE_CURSOR_RECT_CALLBACK) {
- InputConnectionCompatUtils.requestCursorRect(
- latinIme.getCurrentInputConnection(), true /* enableMonitor */);
- }
- if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK) {
- // AcceptTypedWord feature relies on CursorAnchorInfo.
- if (latinIme.mSettings.getCurrent().mShouldShowUiToAcceptTypedWord) {
- InputConnectionCompatUtils.requestCursorAnchorInfo(
- latinIme.getCurrentInputConnection(), true /* enableMonitor */,
- true /* requestImmediateCallback */);
- }
- }
}
}
}
@@ -573,7 +561,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
DictionaryDecayBroadcastReciever.setUpIntervalAlarmForDictionaryDecaying(this);
- StatsUtils.onCreate(mSettings.getCurrent());
+ StatsUtils.onCreate(mSettings.getCurrent(), mRichImm);
}
// Has to be package-visible for unit tests
@@ -766,6 +754,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void onStartInputInternal(final EditorInfo editorInfo, final boolean restarting) {
super.onStartInput(editorInfo, restarting);
+ if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK) {
+ // AcceptTypedWord feature relies on CursorAnchorInfo.
+ if (mSettings.getCurrent().mShouldShowUiToAcceptTypedWord) {
+ InputConnectionCompatUtils.requestUpdateCursorAnchorInfo(
+ getCurrentInputConnection(), true /* enableMonitor */,
+ true /* requestImmediateCallback */);
+ }
+ }
}
@SuppressWarnings("deprecation")
@@ -970,14 +966,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- @Override
- public void onUpdateCursor(final Rect rect) {
- if (DEBUG) {
- Log.i(TAG, "onUpdateCursor:" + rect.toShortString());
- }
- super.onUpdateCursor(rect);
- }
-
// We cannot mark this method as @Override until new SDK becomes publicly available.
// @Override
public void onUpdateCursorAnchorInfo(final CursorAnchorInfo info) {
diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
index 7cf4eff92..e43c18255 100644
--- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
+++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
@@ -40,7 +40,8 @@ import java.util.List;
/**
* Enrichment class for InputMethodManager to simplify interaction and add functionality.
*/
-public final class RichInputMethodManager {
+// non final for easy mocking.
+public class RichInputMethodManager {
private static final String TAG = RichInputMethodManager.class.getSimpleName();
private RichInputMethodManager() {
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index a2ae74b20..ec3c6e291 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -36,9 +36,7 @@ public final class FormatSpec {
* sion
*
* o |
- * p | not used 3 bits
- * t | each unigram and bigram entry has a time stamp?
- * i | 1 bit, 1 = yes, 0 = no : CONTAINS_TIMESTAMP_FLAG
+ * p | not used, 2 bytes.
* o |
* nflags
*
@@ -48,7 +46,7 @@ public final class FormatSpec {
* d |
* ersize
*
- * | attributes list
+ * attributes list
*
* attributes list is:
* <key> = | string of characters at the char format described below, with the terminator used
@@ -86,11 +84,10 @@ public final class FormatSpec {
*/
/* Node (FusionDictionary.PtNode) layout is as follows:
- * | is moved ? 2 bits, 11 = no : FLAG_IS_NOT_MOVED
- * | This must be the same as FLAG_CHILDREN_ADDRESS_TYPE_THREEBYTES
- * | 01 = yes : FLAG_IS_MOVED
- * f | the new address is stored in the same place as the parent address
- * l | is deleted? 10 = yes : FLAG_IS_DELETED
+ * | CHILDREN_ADDRESS_TYPE 2 bits, 11 : FLAG_CHILDREN_ADDRESS_TYPE_THREEBYTES
+ * | 10 : FLAG_CHILDREN_ADDRESS_TYPE_TWOBYTES
+ * f | 01 : FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE
+ * l | 00 : FLAG_CHILDREN_ADDRESS_TYPE_NOADDRESS
* a | has several chars ? 1 bit, 1 = yes, 0 = no : FLAG_HAS_MULTIPLE_CHARS
* g | has a terminal ? 1 bit, 1 = yes, 0 = no : FLAG_IS_TERMINAL
* s | has shortcut targets ? 1 bit, 1 = yes, 0 = no : FLAG_HAS_SHORTCUT_TARGETS
@@ -98,16 +95,6 @@ public final class FormatSpec {
* | is not a word ? 1 bit, 1 = yes, 0 = no : FLAG_IS_NOT_A_WORD
* | is blacklisted ? 1 bit, 1 = yes, 0 = no : FLAG_IS_BLACKLISTED
*
- * p |
- * a | parent address, 3byte
- * r | 1 byte = bbbbbbbb match
- * e | case 1xxxxxxx => -((0xxxxxxx << 16) + (next byte << 8) + next byte)
- * n | otherwise => (bbbbbbbb << 16) + (next byte << 8) + next byte
- * t | This address is relative to the head of the PtNode.
- * a | If the node doesn't have a parent, this field is set to 0.
- * d |
- * dress
- *
* c | IF FLAG_HAS_MULTIPLE_CHARS
* h | char, char, char, char n * (1 or 3 bytes) : use PtNodeInfo for i/o helpers
* a | end 1 byte, = 0
@@ -121,15 +108,10 @@ public final class FormatSpec {
* q |
*
* c |
- * h | children address, 3 bytes
- * i | 1 byte = bbbbbbbb match
- * l | case 1xxxxxxx => -((0xxxxxxx << 16) + (next byte << 8) + next byte)
- * d | otherwise => (bbbbbbbb<<16) + (next byte << 8) + next byte
- * r | if this node doesn't have children, this field is set to 0.
- * e | (see BinaryDictEncoderUtils#writeVariableSignedAddress)
- * n | This address is relative to the position of this field.
- * a |
- * ddress
+ * h | children address, CHILDREN_ADDRESS_TYPE bytes
+ * i | This address is relative to the position of this field.
+ * l |
+ * drenaddress
*
* | IF FLAG_IS_TERMINAL && FLAG_HAS_SHORTCUT_TARGETS
* | shortcut string list
@@ -179,8 +161,6 @@ public final class FormatSpec {
public static final int MAGIC_NUMBER = 0x9BC13AFE;
static final int NOT_A_VERSION_NUMBER = -1;
- static final int FIRST_VERSION_WITH_DYNAMIC_UPDATE = 3;
- static final int FIRST_VERSION_WITH_TERMINAL_ID = 4;
// These MUST have the same values as the relevant constants in format_utils.h.
// From version 4 on, we use version * 100 + revision as a version number. That allows
@@ -202,9 +182,6 @@ public final class FormatSpec {
// use it in the reading code.
static final int MAX_WORD_LENGTH = Constants.DICTIONARY_MAX_WORD_LENGTH;
- static final int PARENT_ADDRESS_SIZE = 3;
- static final int FORWARD_LINK_ADDRESS_SIZE = 3;
-
// These flags are used only in the static dictionary.
static final int MASK_CHILDREN_ADDRESS_TYPE = 0xC0;
static final int FLAG_CHILDREN_ADDRESS_TYPE_NOADDRESS = 0x00;
@@ -220,13 +197,6 @@ public final class FormatSpec {
static final int FLAG_IS_NOT_A_WORD = 0x02;
static final int FLAG_IS_BLACKLISTED = 0x01;
- // These flags are used only in the dynamic dictionary.
- static final int MASK_MOVE_AND_DELETE_FLAG = 0xC0;
- static final int FIXED_BIT_OF_DYNAMIC_UPDATE_MOVE = 0x40;
- static final int FLAG_IS_MOVED = 0x00 | FIXED_BIT_OF_DYNAMIC_UPDATE_MOVE;
- static final int FLAG_IS_NOT_MOVED = 0x80 | FIXED_BIT_OF_DYNAMIC_UPDATE_MOVE;
- static final int FLAG_IS_DELETED = 0x80;
-
static final int FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT = 0x80;
static final int FLAG_BIGRAM_ATTR_OFFSET_NEGATIVE = 0x40;
static final int MASK_BIGRAM_ATTR_ADDRESS_TYPE = 0x30;
@@ -240,52 +210,12 @@ public final class FormatSpec {
static final int PTNODE_TERMINATOR_SIZE = 1;
static final int PTNODE_FLAGS_SIZE = 1;
static final int PTNODE_FREQUENCY_SIZE = 1;
- static final int PTNODE_TERMINAL_ID_SIZE = 4;
static final int PTNODE_MAX_ADDRESS_SIZE = 3;
static final int PTNODE_ATTRIBUTE_FLAGS_SIZE = 1;
static final int PTNODE_ATTRIBUTE_MAX_ADDRESS_SIZE = 3;
static final int PTNODE_SHORTCUT_LIST_SIZE_SIZE = 2;
- // These values are used only by version 4 or later. They MUST match the definitions in
- // ver4_dict_constants.cpp.
- static final String TRIE_FILE_EXTENSION = ".trie";
- public static final String HEADER_FILE_EXTENSION = ".header";
- static final String FREQ_FILE_EXTENSION = ".freq";
- // tat = Terminal Address Table
- static final String TERMINAL_ADDRESS_TABLE_FILE_EXTENSION = ".tat";
- static final String BIGRAM_FILE_EXTENSION = ".bigram";
- static final String SHORTCUT_FILE_EXTENSION = ".shortcut";
- static final String LOOKUP_TABLE_FILE_SUFFIX = "_lookup";
- static final String CONTENT_TABLE_FILE_SUFFIX = "_index";
- static final int FLAGS_IN_FREQ_FILE_SIZE = 1;
- static final int FREQUENCY_AND_FLAGS_SIZE = 2;
- static final int TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE = 3;
- static final int UNIGRAM_TIMESTAMP_SIZE = 4;
- static final int UNIGRAM_COUNTER_SIZE = 1;
- static final int UNIGRAM_LEVEL_SIZE = 1;
-
- // With the English main dictionary as of October 2013, the size of bigram address table is
- // is 345KB with the block size being 16.
- // This is 54% of that of full address table.
- static final int BIGRAM_ADDRESS_TABLE_BLOCK_SIZE = 16;
- static final int BIGRAM_CONTENT_COUNT = 1;
- static final int BIGRAM_FREQ_CONTENT_INDEX = 0;
- static final String BIGRAM_FREQ_CONTENT_ID = "_freq";
- static final int BIGRAM_TIMESTAMP_SIZE = 4;
- static final int BIGRAM_COUNTER_SIZE = 1;
- static final int BIGRAM_LEVEL_SIZE = 1;
-
- static final int SHORTCUT_CONTENT_COUNT = 1;
- static final int SHORTCUT_CONTENT_INDEX = 0;
- // With the English main dictionary as of October 2013, the size of shortcut address table is
- // 26KB with the block size being 64.
- // This is only 4.4% of that of full address table.
- static final int SHORTCUT_ADDRESS_TABLE_BLOCK_SIZE = 64;
- static final String SHORTCUT_CONTENT_ID = "_shortcut";
-
static final int NO_CHILDREN_ADDRESS = Integer.MIN_VALUE;
- static final int NO_PARENT_ADDRESS = 0;
- static final int NO_FORWARD_LINK_ADDRESS = 0;
static final int INVALID_CHARACTER = -1;
static final int MAX_PTNODES_FOR_ONE_BYTE_PTNODE_COUNT = 0x7F; // 127
@@ -302,14 +232,11 @@ public final class FormatSpec {
// This option needs to be the same numeric value as the one in binary_format.h.
static final int NOT_VALID_WORD = -99;
- static final int SIGNED_CHILDREN_ADDRESS_SIZE = 3;
static final int UINT8_MAX = 0xFF;
static final int UINT16_MAX = 0xFFFF;
static final int UINT24_MAX = 0xFFFFFF;
- static final int SINT24_MAX = 0x7FFFFF;
static final int MSB8 = 0x80;
- static final int MSB24 = 0x800000;
/**
* Options about file format.
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
index 346aea34a..9d186d44d 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
@@ -125,9 +125,9 @@ public final class MoreSuggestions extends Keyboard {
}
private static final int[][] COLUMN_ORDER_TO_NUMBER = {
- { 0, },
- { 1, 0, },
- { 2, 0, 1},
+ { 0 }, // center
+ { 1, 0 }, // right-left
+ { 1, 0, 2 }, // center-left-right
};
public int getNumColumnInRow(final int index) {
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index 7307ca1ba..1e8df8986 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -45,11 +45,14 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.inputmethod.accessibility.AccessibilityUtils;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.PunctuationSuggestions;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.define.DebugFlags;
+import com.android.inputmethod.latin.settings.Settings;
+import com.android.inputmethod.latin.settings.SettingsValues;
import com.android.inputmethod.latin.utils.AutoCorrectionUtils;
import com.android.inputmethod.latin.utils.ResourceUtils;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
@@ -72,7 +75,7 @@ final class SuggestionStripLayoutHelper {
private int mMaxMoreSuggestionsRow;
public final float mMinMoreSuggestionsWidth;
public final int mMoreSuggestionsBottomGap;
- public boolean mMoreSuggestionsAvailable;
+ private boolean mMoreSuggestionsAvailable;
// The index of these {@link ArrayList} is the position in the suggestion strip. The indices
// increase towards the right for LTR scripts and the left for RTL scripts, starting with 0.
@@ -223,11 +226,59 @@ final class SuggestionStripLayoutHelper {
return spannedWord;
}
+ /**
+ * Convert an index of {@link SuggestedWords} to position in the suggestion strip.
+ * @param indexInSuggestedWords the index of {@link SuggestedWords}.
+ * @param suggestedWords the suggested words list
+ * @return Non-negative integer of the position in the suggestion strip.
+ * Negative integer if the word of the index shouldn't be shown on the suggestion strip.
+ */
private int getPositionInSuggestionStrip(final int indexInSuggestedWords,
final SuggestedWords suggestedWords) {
+ final SettingsValues settingsValues = Settings.getInstance().getCurrent();
+ final boolean shouldOmitTypedWord = shouldOmitTypedWord(suggestedWords.mInputStyle,
+ settingsValues.mGestureFloatingPreviewTextEnabled,
+ settingsValues.mShouldShowUiToAcceptTypedWord);
+ return getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords.mWillAutoCorrect,
+ settingsValues.mShouldShowUiToAcceptTypedWord && shouldOmitTypedWord,
+ mCenterPositionInStrip, mTypedWordPositionWhenAutocorrect);
+ }
+
+ @UsedForTesting
+ static boolean shouldOmitTypedWord(final int inputStyle,
+ final boolean gestureFloatingPreviewTextEnabled,
+ final boolean shouldShowUiToAcceptTypedWord) {
+ final boolean omitTypedWord = (inputStyle == SuggestedWords.INPUT_STYLE_TYPING)
+ || (inputStyle == SuggestedWords.INPUT_STYLE_TAIL_BATCH)
+ || (inputStyle == SuggestedWords.INPUT_STYLE_UPDATE_BATCH
+ && gestureFloatingPreviewTextEnabled);
+ return shouldShowUiToAcceptTypedWord && omitTypedWord;
+ }
+
+ @UsedForTesting
+ static int getPositionInSuggestionStrip(final int indexInSuggestedWords,
+ final boolean willAutoCorrect, final boolean omitTypedWord,
+ final int centerPositionInStrip, final int typedWordPositionWhenAutoCorrect) {
+ if (omitTypedWord) {
+ if (indexInSuggestedWords == SuggestedWords.INDEX_OF_TYPED_WORD) {
+ // Ignore.
+ return -1;
+ }
+ if (indexInSuggestedWords == SuggestedWords.INDEX_OF_AUTO_CORRECTION) {
+ // Center in the suggestion strip.
+ return centerPositionInStrip;
+ }
+ // If neither of those, the order in the suggestion strip is left of the center first
+ // then right of the center, to both edges of the suggestion strip.
+ // For example, center-1, center+1, center-2, center+2, and so on.
+ final int n = indexInSuggestedWords;
+ final int offsetFromCenter = (n % 2) == 0 ? -(n / 2) : (n / 2);
+ final int positionInSuggestionStrip = centerPositionInStrip + offsetFromCenter;
+ return positionInSuggestionStrip;
+ }
final int indexToDisplayMostImportantSuggestion;
final int indexToDisplaySecondMostImportantSuggestion;
- if (suggestedWords.mWillAutoCorrect) {
+ if (willAutoCorrect) {
indexToDisplayMostImportantSuggestion = SuggestedWords.INDEX_OF_AUTO_CORRECTION;
indexToDisplaySecondMostImportantSuggestion = SuggestedWords.INDEX_OF_TYPED_WORD;
} else {
@@ -235,25 +286,31 @@ final class SuggestionStripLayoutHelper {
indexToDisplaySecondMostImportantSuggestion = SuggestedWords.INDEX_OF_AUTO_CORRECTION;
}
if (indexInSuggestedWords == indexToDisplayMostImportantSuggestion) {
- return mCenterPositionInStrip;
+ // Center in the suggestion strip.
+ return centerPositionInStrip;
}
if (indexInSuggestedWords == indexToDisplaySecondMostImportantSuggestion) {
- return mTypedWordPositionWhenAutocorrect;
+ // Center-1.
+ return typedWordPositionWhenAutoCorrect;
}
- // If neither of those, the order in the suggestion strip is the same as in SuggestedWords.
- return indexInSuggestedWords;
+ // If neither of those, the order in the suggestion strip is right of the center first
+ // then left of the center, to both edges of the suggestion strip.
+ // For example, Center+1, center-2, center+2, center-3, and so on.
+ final int n = indexInSuggestedWords + 1;
+ final int offsetFromCenter = (n % 2) == 0 ? -(n / 2) : (n / 2);
+ final int positionInSuggestionStrip = centerPositionInStrip + offsetFromCenter;
+ return positionInSuggestionStrip;
}
private int getSuggestionTextColor(final SuggestedWords suggestedWords,
final int indexInSuggestedWords) {
- final int positionInStrip =
- getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords);
// Use identity for strings, not #equals : it's the typed word if it's the same object
final boolean isTypedWord = suggestedWords.getInfo(indexInSuggestedWords).isKindOf(
SuggestedWordInfo.KIND_TYPED);
final int color;
- if (positionInStrip == mCenterPositionInStrip && suggestedWords.mWillAutoCorrect) {
+ if (indexInSuggestedWords == SuggestedWords.INDEX_OF_AUTO_CORRECTION
+ && suggestedWords.mWillAutoCorrect) {
color = mColorAutoCorrect;
} else if (isTypedWord && suggestedWords.mTypedWordValid) {
color = mColorValidTypedWord;
@@ -265,7 +322,8 @@ final class SuggestionStripLayoutHelper {
if (DebugFlags.DEBUG_ENABLED && suggestedWords.size() > 1) {
// If we auto-correct, then the autocorrection is in slot 0 and the typed word
// is in slot 1.
- if (positionInStrip == mCenterPositionInStrip
+ if (indexInSuggestedWords == SuggestedWords.INDEX_OF_AUTO_CORRECTION
+ && suggestedWords.mWillAutoCorrect
&& AutoCorrectionUtils.shouldBlockAutoCorrectionBySafetyNet(
suggestedWords.getLabel(SuggestedWords.INDEX_OF_AUTO_CORRECTION),
suggestedWords.getLabel(SuggestedWords.INDEX_OF_TYPED_WORD))) {
@@ -292,31 +350,31 @@ final class SuggestionStripLayoutHelper {
}
/**
- * Layout suggestions to the suggestions strip. And returns the number of suggestions displayed
- * in the suggestions strip.
+ * Layout suggestions to the suggestions strip. And returns the start index of more
+ * suggestions.
*
* @param suggestedWords suggestions to be shown in the suggestions strip.
* @param stripView the suggestions strip view.
* @param placerView the view where the debug info will be placed.
- * @return the number of suggestions displayed in the suggestions strip
+ * @return the start index of more suggestions.
*/
- public int layoutAndReturnSuggestionCountInStrip(final SuggestedWords suggestedWords,
+ public int layoutAndReturnStartIndexOfMoreSuggestions(final SuggestedWords suggestedWords,
final ViewGroup stripView, final ViewGroup placerView) {
if (suggestedWords.isPunctuationSuggestions()) {
- return layoutPunctuationSuggestionsAndReturnSuggestionCountInStrip(
+ return layoutPunctuationsAndReturnStartIndexOfMoreSuggestions(
(PunctuationSuggestions)suggestedWords, stripView);
}
- setupWordViewsTextAndColor(suggestedWords, mSuggestionsCountInStrip);
+ final int startIndexOfMoreSuggestions = setupWordViewsAndReturnStartIndexOfMoreSuggestions(
+ suggestedWords, mSuggestionsCountInStrip);
final TextView centerWordView = mWordViews.get(mCenterPositionInStrip);
final int stripWidth = stripView.getWidth();
final int centerWidth = getSuggestionWidth(mCenterPositionInStrip, stripWidth);
- final int countInStrip;
if (suggestedWords.size() == 1 || getTextScaleX(centerWordView.getText(), centerWidth,
centerWordView.getPaint()) < MIN_TEXT_XSCALE) {
// Layout only the most relevant suggested word at the center of the suggestion strip
// by consolidating all slots in the strip.
- countInStrip = 1;
+ final int countInStrip = 1;
mMoreSuggestionsAvailable = (suggestedWords.size() > countInStrip);
layoutWord(mCenterPositionInStrip, stripWidth - mPadding);
stripView.addView(centerWordView);
@@ -324,31 +382,33 @@ final class SuggestionStripLayoutHelper {
if (SuggestionStripView.DBG) {
layoutDebugInfo(mCenterPositionInStrip, placerView, stripWidth);
}
- } else {
- countInStrip = mSuggestionsCountInStrip;
- mMoreSuggestionsAvailable = (suggestedWords.size() > countInStrip);
- int x = 0;
- for (int positionInStrip = 0; positionInStrip < countInStrip; positionInStrip++) {
- if (positionInStrip != 0) {
- final View divider = mDividerViews.get(positionInStrip);
- // Add divider if this isn't the left most suggestion in suggestions strip.
- addDivider(stripView, divider);
- x += divider.getMeasuredWidth();
- }
-
- final int width = getSuggestionWidth(positionInStrip, stripWidth);
- final TextView wordView = layoutWord(positionInStrip, width);
- stripView.addView(wordView);
- setLayoutWeight(wordView, getSuggestionWeight(positionInStrip),
- ViewGroup.LayoutParams.MATCH_PARENT);
- x += wordView.getMeasuredWidth();
-
- if (SuggestionStripView.DBG) {
- layoutDebugInfo(positionInStrip, placerView, x);
- }
+ final Integer lastIndex = (Integer)centerWordView.getTag();
+ return (lastIndex == null ? 0 : lastIndex) + 1;
+ }
+
+ final int countInStrip = mSuggestionsCountInStrip;
+ mMoreSuggestionsAvailable = (suggestedWords.size() > countInStrip);
+ int x = 0;
+ for (int positionInStrip = 0; positionInStrip < countInStrip; positionInStrip++) {
+ if (positionInStrip != 0) {
+ final View divider = mDividerViews.get(positionInStrip);
+ // Add divider if this isn't the left most suggestion in suggestions strip.
+ addDivider(stripView, divider);
+ x += divider.getMeasuredWidth();
+ }
+
+ final int width = getSuggestionWidth(positionInStrip, stripWidth);
+ final TextView wordView = layoutWord(positionInStrip, width);
+ stripView.addView(wordView);
+ setLayoutWeight(wordView, getSuggestionWeight(positionInStrip),
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ x += wordView.getMeasuredWidth();
+
+ if (SuggestionStripView.DBG) {
+ layoutDebugInfo(positionInStrip, placerView, x);
}
}
- return countInStrip;
+ return startIndexOfMoreSuggestions;
}
/**
@@ -426,10 +486,10 @@ final class SuggestionStripLayoutHelper {
return (1.0f - mCenterSuggestionWeight) / (mSuggestionsCountInStrip - 1);
}
- private void setupWordViewsTextAndColor(final SuggestedWords suggestedWords,
- final int countInStrip) {
+ private int setupWordViewsAndReturnStartIndexOfMoreSuggestions(
+ final SuggestedWords suggestedWords, final int maxSuggestionInStrip) {
// Clear all suggestions first
- for (int positionInStrip = 0; positionInStrip < countInStrip; ++positionInStrip) {
+ for (int positionInStrip = 0; positionInStrip < maxSuggestionInStrip; ++positionInStrip) {
final TextView wordView = mWordViews.get(positionInStrip);
wordView.setText(null);
wordView.setTag(null);
@@ -438,11 +498,15 @@ final class SuggestionStripLayoutHelper {
mDebugInfoViews.get(positionInStrip).setText(null);
}
}
- final int count = Math.min(suggestedWords.size(), countInStrip);
- for (int indexInSuggestedWords = 0; indexInSuggestedWords < count;
- indexInSuggestedWords++) {
+ int count = 0;
+ int indexInSuggestedWords;
+ for (indexInSuggestedWords = 0; indexInSuggestedWords < suggestedWords.size()
+ && count < maxSuggestionInStrip; indexInSuggestedWords++) {
final int positionInStrip =
getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords);
+ if (positionInStrip < 0) {
+ continue;
+ }
final TextView wordView = mWordViews.get(positionInStrip);
// {@link TextView#getTag()} is used to get the index in suggestedWords at
// {@link SuggestionStripView#onClick(View)}.
@@ -453,10 +517,12 @@ final class SuggestionStripLayoutHelper {
mDebugInfoViews.get(positionInStrip).setText(
suggestedWords.getDebugString(indexInSuggestedWords));
}
+ count++;
}
+ return indexInSuggestedWords;
}
- private int layoutPunctuationSuggestionsAndReturnSuggestionCountInStrip(
+ private int layoutPunctuationsAndReturnStartIndexOfMoreSuggestions(
final PunctuationSuggestions punctuationSuggestions, final ViewGroup stripView) {
final int countInStrip = Math.min(punctuationSuggestions.size(), PUNCTUATIONS_IN_STRIP);
for (int positionInStrip = 0; positionInStrip < countInStrip; positionInStrip++) {
@@ -483,8 +549,11 @@ final class SuggestionStripLayoutHelper {
}
public void layoutAddToDictionaryHint(final String word, final ViewGroup addToDictionaryStrip) {
+ final boolean shouldShowUiToAcceptTypedWord = Settings.getInstance().getCurrent()
+ .mShouldShowUiToAcceptTypedWord;
final int stripWidth = addToDictionaryStrip.getWidth();
- final int width = stripWidth - mDividerWidth - mPadding * 2;
+ final int width = shouldShowUiToAcceptTypedWord ? stripWidth
+ : stripWidth - mDividerWidth - mPadding * 2;
final TextView wordView = (TextView)addToDictionaryStrip.findViewById(R.id.word_to_save);
wordView.setTextColor(mColorTypedWord);
@@ -494,25 +563,38 @@ final class SuggestionStripLayoutHelper {
wordView.setText(wordToSave);
wordView.setTextScaleX(wordScaleX);
setLayoutWeight(wordView, mCenterSuggestionWeight, ViewGroup.LayoutParams.MATCH_PARENT);
+ final int wordVisibility = shouldShowUiToAcceptTypedWord ? View.GONE : View.VISIBLE;
+ wordView.setVisibility(wordVisibility);
+ addToDictionaryStrip.findViewById(R.id.word_to_save_divider).setVisibility(wordVisibility);
+ final Resources res = addToDictionaryStrip.getResources();
+ final CharSequence hintText;
+ final int hintWidth;
+ final float hintWeight;
final TextView hintView = (TextView)addToDictionaryStrip.findViewById(
R.id.hint_add_to_dictionary);
+ if (shouldShowUiToAcceptTypedWord) {
+ hintText = res.getText(R.string.hint_add_to_dictionary_without_word);
+ hintWidth = width;
+ hintWeight = 1.0f;
+ hintView.setGravity(Gravity.CENTER);
+ } else {
+ final boolean isRtlLanguage = (ViewCompat.getLayoutDirection(addToDictionaryStrip)
+ == ViewCompat.LAYOUT_DIRECTION_RTL);
+ final String arrow = isRtlLanguage ? RIGHTWARDS_ARROW : LEFTWARDS_ARROW;
+ final boolean isRtlSystem = SubtypeLocaleUtils.isRtlLanguage(
+ res.getConfiguration().locale);
+ final CharSequence hint = res.getText(R.string.hint_add_to_dictionary);
+ hintText = (isRtlLanguage == isRtlSystem) ? (arrow + hint) : (hint + arrow);
+ hintWidth = width - wordWidth;
+ hintWeight = 1.0f - mCenterSuggestionWeight;
+ hintView.setGravity(Gravity.CENTER_VERTICAL | Gravity.START);
+ }
hintView.setTextColor(mColorAutoCorrect);
- final boolean isRtlLanguage = (ViewCompat.getLayoutDirection(addToDictionaryStrip)
- == ViewCompat.LAYOUT_DIRECTION_RTL);
- final String arrow = isRtlLanguage ? RIGHTWARDS_ARROW : LEFTWARDS_ARROW;
- final Resources res = addToDictionaryStrip.getResources();
- final boolean isRtlSystem = SubtypeLocaleUtils.isRtlLanguage(res.getConfiguration().locale);
- final CharSequence hintText = res.getText(R.string.hint_add_to_dictionary);
- final String hintWithArrow = (isRtlLanguage == isRtlSystem)
- ? (arrow + hintText) : (hintText + arrow);
- final int hintWidth = width - wordWidth;
- hintView.setTextScaleX(1.0f); // Reset textScaleX.
- final float hintScaleX = getTextScaleX(hintWithArrow, hintWidth, hintView.getPaint());
- hintView.setText(hintWithArrow);
+ final float hintScaleX = getTextScaleX(hintText, hintWidth, hintView.getPaint());
+ hintView.setText(hintText);
hintView.setTextScaleX(hintScaleX);
- setLayoutWeight(
- hintView, 1.0f - mCenterSuggestionWeight, ViewGroup.LayoutParams.MATCH_PARENT);
+ setLayoutWeight(hintView, hintWeight, ViewGroup.LayoutParams.MATCH_PARENT);
}
public void layoutImportantNotice(final View importantNoticeStrip,
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index 9b8c38a2d..33745a846 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -83,7 +83,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
Listener mListener;
private SuggestedWords mSuggestedWords = SuggestedWords.EMPTY;
- private int mSuggestionsCountInStrip;
+ private int mStartIndexOfMoreSuggestions;
private final SuggestionStripLayoutHelper mLayoutHelper;
private final StripVisibilityGroup mStripVisibilityGroup;
@@ -214,7 +214,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
clear();
mStripVisibilityGroup.setLayoutDirection(isRtlLanguage);
mSuggestedWords = suggestedWords;
- mSuggestionsCountInStrip = mLayoutHelper.layoutAndReturnSuggestionCountInStrip(
+ mStartIndexOfMoreSuggestions = mLayoutHelper.layoutAndReturnStartIndexOfMoreSuggestions(
mSuggestedWords, mSuggestionsStrip, this);
mStripVisibilityGroup.showSuggestionsStrip();
}
@@ -337,7 +337,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
return false;
}
final SuggestionStripLayoutHelper layoutHelper = mLayoutHelper;
- if (!layoutHelper.mMoreSuggestionsAvailable) {
+ if (mSuggestedWords.size() <= mStartIndexOfMoreSuggestions) {
return false;
}
// Dismiss another {@link MoreKeysPanel} that may be being showed, for example
@@ -350,7 +350,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
final View container = mMoreSuggestionsContainer;
final int maxWidth = stripWidth - container.getPaddingLeft() - container.getPaddingRight();
final MoreSuggestions.Builder builder = mMoreSuggestionsBuilder;
- builder.layout(mSuggestedWords, mSuggestionsCountInStrip, maxWidth,
+ builder.layout(mSuggestedWords, mStartIndexOfMoreSuggestions, maxWidth,
(int)(maxWidth * layoutHelper.mMinMoreSuggestionsWidth),
layoutHelper.getMaxMoreSuggestionsRow(), parentKeyboard);
mMoreSuggestionsView.setKeyboard(builder.build());
@@ -363,7 +363,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
mMoreSuggestionsListener);
mOriginX = mLastX;
mOriginY = mLastY;
- for (int i = 0; i < mSuggestionsCountInStrip; i++) {
+ for (int i = 0; i < mStartIndexOfMoreSuggestions; i++) {
mWordViews.get(i).setPressed(false);
}
return true;
diff --git a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
index 351d01400..0db4106c5 100644
--- a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
@@ -30,6 +30,7 @@ import com.android.inputmethod.latin.R;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Locale;
public final class SubtypeLocaleUtils {
@@ -52,6 +53,8 @@ public final class SubtypeLocaleUtils {
private static final HashMap<String, String> sKeyboardLayoutToDisplayNameMap = new HashMap<>();
// Keyboard layout to subtype name resource id map.
private static final HashMap<String, Integer> sKeyboardLayoutToNameIdsMap = new HashMap<>();
+ // Exceptional locale whose name should be displayed in Locale.ROOT.
+ static final HashSet<String> sExceptionalLocaleDisplayedInRootLocale = new HashSet<>();
// Exceptional locale to subtype name resource id map.
private static final HashMap<String, Integer> sExceptionalLocaleToNameIdsMap = new HashMap<>();
// Exceptional locale to subtype name with layout resource id map.
@@ -106,6 +109,12 @@ public final class SubtypeLocaleUtils {
sKeyboardLayoutToNameIdsMap.put(key, noLanguageResId);
}
+ final String[] excetionalLocaleInRootLocale = res.getStringArray(
+ R.array.subtype_locale_displayed_in_root_locale);
+ for (int i = 0; i < excetionalLocaleInRootLocale.length; i++) {
+ sExceptionalLocaleDisplayedInRootLocale.add(excetionalLocaleInRootLocale[i]);
+ }
+
final String[] exceptionalLocales = res.getStringArray(
R.array.subtype_locale_exception_keys);
for (int i = 0; i < exceptionalLocales.length; i++) {
@@ -157,6 +166,9 @@ public final class SubtypeLocaleUtils {
if (NO_LANGUAGE.equals(localeString)) {
return sResources.getConfiguration().locale;
}
+ if (sExceptionalLocaleDisplayedInRootLocale.contains(localeString)) {
+ return Locale.ROOT;
+ }
return LocaleUtils.constructLocaleFromString(localeString);
}
@@ -171,9 +183,15 @@ public final class SubtypeLocaleUtils {
}
public static String getSubtypeLanguageDisplayName(final String localeString) {
- final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
final Locale displayLocale = getDisplayLocaleOfSubtypeLocale(localeString);
- return getSubtypeLocaleDisplayNameInternal(locale.getLanguage(), displayLocale);
+ final String languageString;
+ if (sExceptionalLocaleDisplayedInRootLocale.contains(localeString)) {
+ languageString = localeString;
+ } else {
+ final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
+ languageString = locale.getLanguage();
+ }
+ return getSubtypeLocaleDisplayNameInternal(languageString, displayLocale);
}
private static String getSubtypeLocaleDisplayNameInternal(final String localeString,