aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android')
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java8
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java2
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java2
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java6
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java69
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java9
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java2
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java6
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java2
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java5
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FormatSpec.java18
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java18
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java49
-rw-r--r--java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java55
14 files changed, 149 insertions, 102 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index afaf2cc57..816a94300 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -716,10 +716,14 @@ public class Key implements Comparable<Key> {
return (attrs != null) ? attrs.mAltCode : CODE_UNSPECIFIED;
}
+ public int getIconId() {
+ return mIconId;
+ }
+
public Drawable getIcon(final KeyboardIconsSet iconSet, final int alpha) {
final OptionalAttributes attrs = mOptionalAttributes;
final int disabledIconId = (attrs != null) ? attrs.mDisabledIconId : ICON_UNDEFINED;
- final int iconId = mEnabled ? mIconId : disabledIconId;
+ final int iconId = mEnabled ? getIconId() : disabledIconId;
final Drawable icon = iconSet.getIconDrawable(iconId);
if (icon != null) {
icon.setAlpha(alpha);
@@ -731,7 +735,7 @@ public class Key implements Comparable<Key> {
final OptionalAttributes attrs = mOptionalAttributes;
final int previewIconId = (attrs != null) ? attrs.mPreviewIconId : ICON_UNDEFINED;
return previewIconId != ICON_UNDEFINED
- ? iconSet.getIconDrawable(previewIconId) : iconSet.getIconDrawable(mIconId);
+ ? iconSet.getIconDrawable(previewIconId) : iconSet.getIconDrawable(getIconId());
}
public int getWidth() {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
index da8bf7d69..79d088f2e 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
@@ -102,7 +102,7 @@ public final class KeyboardIconsSet {
return isValidIconId(iconId) ? ICON_NAMES[iconId] : "unknown<" + iconId + ">";
}
- static int getIconId(final String name) {
+ public static int getIconId(final String name) {
Integer iconId = sNameToIdsMap.get(name);
if (iconId != null) {
return iconId;
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index a7008379f..acbd919cd 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -229,7 +229,7 @@ final public class BinaryDictionaryGetter {
private static boolean hackCanUseDictionaryFile(final Locale locale, final File f) {
try {
// Read the version of the file
- final DictDecoder dictDecoder = FormatSpec.getDictDecoder(f);
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(f, 0, f.length());
final DictionaryHeader header = dictDecoder.readHeader();
final String version = header.mDictionaryOptions.mAttributes.get(VERSION_KEY);
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
index e767e4be9..2dba7131e 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
@@ -28,6 +28,7 @@ import com.android.inputmethod.latin.personalization.PersonalizationHelper;
import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
import com.android.inputmethod.latin.settings.SettingsValues;
import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.ExecutorUtils;
import com.android.inputmethod.latin.utils.LanguageModelParam;
import java.io.File;
@@ -208,8 +209,7 @@ public class DictionaryFacilitatorForSuggest {
if (listener != null) {
listener.onUpdateMainDictionaryAvailability(hasMainDictionary());
}
- new Thread("InitializeBinaryDictionary") {
- @Override
+ ExecutorUtils.getExecutor("InitializeBinaryDictionary").execute(new Runnable() {
public void run() {
final DictionaryCollection newMainDict =
DictionaryFactory.createMainDictionaryFromManager(context, locale);
@@ -219,7 +219,7 @@ public class DictionaryFacilitatorForSuggest {
}
mLatchForWaitingLoadingMainDictionary.countDown();
}
- }.start();
+ });
}
// The main dictionary could have been loaded asynchronously. Don't cache the return value
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index f9ab9419b..c3e33c0c1 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -29,6 +29,7 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.utils.AsyncResultHolder;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.CombinedFormatUtils;
+import com.android.inputmethod.latin.utils.ExecutorUtils;
import com.android.inputmethod.latin.utils.FileUtils;
import com.android.inputmethod.latin.utils.LanguageModelParam;
import com.android.inputmethod.latin.utils.PrioritizedSerialExecutor;
@@ -80,9 +81,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
private static final ConcurrentHashMap<String, DictionaryUpdateController>
sDictNameDictionaryUpdateControllerMap = CollectionUtils.newConcurrentHashMap();
- private static final ConcurrentHashMap<String, PrioritizedSerialExecutor>
- sDictNameExecutorMap = CollectionUtils.newConcurrentHashMap();
-
/** The application context. */
protected final Context mContext;
@@ -163,33 +161,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
return recorder;
}
- /**
- * Gets the executor for the given dictionary name.
- */
- private static PrioritizedSerialExecutor getExecutor(final String dictName) {
- PrioritizedSerialExecutor executor = sDictNameExecutorMap.get(dictName);
- if (executor == null) {
- synchronized(sDictNameExecutorMap) {
- executor = new PrioritizedSerialExecutor();
- sDictNameExecutorMap.put(dictName, executor);
- }
- }
- return executor;
- }
-
- /**
- * Shutdowns all executors and removes all executors from the executor map for testing.
- */
- @UsedForTesting
- public static void shutdownAllExecutors() {
- synchronized(sDictNameExecutorMap) {
- for (final PrioritizedSerialExecutor executor : sDictNameExecutorMap.values()) {
- executor.shutdown();
- sDictNameExecutorMap.remove(executor);
- }
- }
- }
-
private static AbstractDictionaryWriter getDictionaryWriter(
final boolean isDynamicPersonalizationDictionary) {
if (isDynamicPersonalizationDictionary) {
@@ -243,10 +214,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
*/
@Override
public void close() {
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
- if (mBinaryDictionary!= null) {
+ if (mBinaryDictionary != null) {
mBinaryDictionary.close();
mBinaryDictionary = null;
}
@@ -256,7 +227,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
protected void closeBinaryDictionary() {
// Ensure that no other threads are accessing the local binary dictionary.
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
if (mBinaryDictionary != null) {
@@ -287,7 +258,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
protected void clear() {
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
if (mDictionaryWriter == null) {
@@ -331,7 +302,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
* Check whether GC is needed and run GC if required.
*/
protected void runGCIfRequired(final boolean mindsBlockByGC) {
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
runGCIfRequiredInternalLocked(mindsBlockByGC);
@@ -344,7 +315,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
if (mBinaryDictionary.needsToRunGC(mindsBlockByGC)) {
if (setProcessingLargeTaskIfNot()) {
// Run GC after currently existing time sensitive operations.
- getExecutor(mDictName).executePrioritized(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).executePrioritized(new Runnable() {
@Override
public void run() {
try {
@@ -368,7 +339,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
Log.w(TAG, "addWordDynamically is called for non-updatable dictionary: " + mDictName);
return;
}
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
runGCIfRequiredInternalLocked(true /* mindsBlockByGC */);
@@ -388,7 +359,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
+ mDictName);
return;
}
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
runGCIfRequiredInternalLocked(true /* mindsBlockByGC */);
@@ -406,7 +377,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
+ mDictName);
return;
}
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
runGCIfRequiredInternalLocked(true /* mindsBlockByGC */);
@@ -430,7 +401,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
"dictionary: " + mDictName);
return;
}
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
final boolean locked = setProcessingLargeTaskIfNot();
@@ -461,7 +432,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
final AsyncResultHolder<ArrayList<SuggestedWordInfo>> holder =
new AsyncResultHolder<ArrayList<SuggestedWordInfo>>();
- getExecutor(mDictName).executePrioritized(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).executePrioritized(new Runnable() {
@Override
public void run() {
if (mBinaryDictionary == null) {
@@ -500,7 +471,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
return false;
}
final AsyncResultHolder<Boolean> holder = new AsyncResultHolder<Boolean>();
- getExecutor(mDictName).executePrioritized(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).executePrioritized(new Runnable() {
@Override
public void run() {
holder.set(isValidWordLocked(word));
@@ -560,7 +531,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
// swapping in the new one.
// TODO: Ensure multi-thread assignment of mBinaryDictionary.
final BinaryDictionary oldBinaryDictionary = mBinaryDictionary;
- getExecutor(mDictName).executePrioritized(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).executePrioritized(new Runnable() {
@Override
public void run() {
mBinaryDictionary = newBinaryDictionary;
@@ -662,7 +633,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
private final void reloadDictionary() {
// Ensure that only one thread attempts to read or write to the shared binary dictionary
// file at the same time.
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
try {
@@ -696,7 +667,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
// If we just loaded the binary dictionary, then mBinaryDictionary is not
// up-to-date yet so it's useless to test it right away. Schedule the check
// for right after it's loaded instead.
- getExecutor(mDictName).executePrioritized(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).executePrioritized(new Runnable() {
@Override
public void run() {
if (mBinaryDictionary != null && !(isValidDictionary()
@@ -736,7 +707,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
};
final Runnable oldTask = mUnfinishedFlushingTask.getAndSet(newTask);
- getExecutor(mDictName).replaceAndExecute(oldTask, newTask);
+ ExecutorUtils.getExecutor(mDictName).replaceAndExecute(oldTask, newTask);
}
/**
@@ -757,7 +728,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@UsedForTesting
public boolean isInUnderlyingBinaryDictionaryForTests(final String word) {
final AsyncResultHolder<Boolean> holder = new AsyncResultHolder<Boolean>();
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
if (mDictType == Dictionary.TYPE_USER_HISTORY) {
@@ -771,7 +742,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@UsedForTesting
public void waitAllTasksForTests() {
final CountDownLatch countDownLatch = new CountDownLatch(1);
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
countDownLatch.countDown();
@@ -787,7 +758,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@UsedForTesting
public void dumpAllWordsForDebug() {
reloadDictionaryIfRequired();
- getExecutor(mDictName).execute(new Runnable() {
+ ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
@Override
public void run() {
Log.d(TAG, "Dump dictionary: " + mDictName);
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index abf831a28..5e144106f 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -147,6 +147,8 @@ public final class Suggest {
}
}
+ final boolean isPrediction = !wordComposer.isComposingWord();
+
// We allow auto-correction if we have a whitelisted word, or if the word is not a valid
// word of more than 1 char, except if the first suggestion is the same as the typed string
// because in this case if it's strong enough to auto-correct that will mistakenly designate
@@ -165,7 +167,7 @@ public final class Suggest {
// same time, it feels wrong that the SuggestedWord object includes information about
// the current settings. It may also be useful to know, when the setting is off, whether
// the word *would* have been auto-corrected.
- if (!isCorrectionEnabled || !allowsToBeAutoCorrected || !wordComposer.isComposingWord()
+ if (!isCorrectionEnabled || !allowsToBeAutoCorrected || isPrediction
|| suggestionsSet.isEmpty() || wordComposer.hasDigits()
|| wordComposer.isMostlyCaps() || wordComposer.isResumed()
|| !mDictionaryFacilitator.hasMainDictionary()
@@ -225,10 +227,9 @@ public final class Suggest {
// TODO: this first argument is lying. If this is a whitelisted word which is an
// actual word, it says typedWordValid = false, which looks wrong. We should either
// rename the attribute or change the value.
- !allowsToBeAutoCorrected /* typedWordValid */,
+ !isPrediction && !allowsToBeAutoCorrected /* typedWordValid */,
hasAutoCorrection, /* willAutoCorrect */
- false /* isObsoleteSuggestions */,
- !wordComposer.isComposingWord() /* isPrediction */, sequenceNumber));
+ false /* isObsoleteSuggestions */, isPrediction, sequenceNumber));
}
// Retrieves suggestions for the batch input
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 46df3e88c..06bc90c97 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -69,7 +69,7 @@ public class SuggestedWords {
final boolean isPrediction,
final int sequenceNumber) {
this(suggestedWordInfoList, rawSuggestions,
- suggestedWordInfoList.isEmpty() ? null
+ (suggestedWordInfoList.isEmpty() || isPrediction) ? null
: suggestedWordInfoList.get(INDEX_OF_TYPED_WORD).mWord,
typedWordValid, willAutoCorrect, isObsoleteSuggestions, isPrediction,
sequenceNumber);
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 045d06f0e..f2f9f1e68 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -1360,10 +1360,12 @@ public final class InputLogic {
}});
} else {
// We found suggestion spans in the word. We'll create the SuggestedWords out of
- // them, and make willAutoCorrect false.
+ // them, and make willAutoCorrect false. We make typedWordValid false, because the
+ // color of the word in the suggestion strip changes according to this parameter,
+ // and false gives the correct color.
final SuggestedWords suggestedWords = new SuggestedWords(suggestions,
null /* rawSuggestions */, typedWord,
- true /* typedWordValid */, false /* willAutoCorrect */,
+ false /* typedWordValid */, false /* willAutoCorrect */,
false /* isObsoleteSuggestions */, false /* isPrediction */,
SuggestedWords.NOT_A_SEQUENCE_NUMBER);
mIsAutoCorrectionIndicatorOn = false;
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
index b534ebeff..25e1bcd25 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
@@ -357,7 +357,7 @@ public final class BinaryDictDecoderUtils {
* @return true if it's a binary dictionary, false otherwise
*/
public static boolean isBinaryDictionary(final File file) {
- final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file);
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, 0, file.length());
if (dictDecoder == null) {
return false;
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 989ca4b2f..90e7400fb 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -237,7 +237,7 @@ public final class BinaryDictIOUtils {
final File file, final long offset, final long length)
throws FileNotFoundException, IOException, UnsupportedFormatException {
final byte[] buffer = new byte[HEADER_READING_BUFFER_SIZE];
- final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file,
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, offset, length,
new DictDecoder.DictionaryBufferFactory() {
@Override
public DictBuffer getDictionaryBuffer(File file)
@@ -251,8 +251,7 @@ public final class BinaryDictIOUtils {
inStream.close();
}
}
- }
- );
+ });
if (dictDecoder == null) {
return null;
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index c7635eff9..9abecbfec 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -326,30 +326,34 @@ public final class FormatSpec {
* Returns new dictionary decoder.
*
* @param dictFile the dictionary file.
+ * @param offset the offset in the file.
+ * @param length the length of the file, in bytes.
* @param bufferType The type of buffer, as one of USE_* in DictDecoder.
* @return new dictionary decoder if the dictionary file exists, otherwise null.
*/
- public static DictDecoder getDictDecoder(final File dictFile, final int bufferType) {
+ public static DictDecoder getDictDecoder(final File dictFile, final long offset,
+ final long length, final int bufferType) {
if (dictFile.isDirectory()) {
return new Ver4DictDecoder(dictFile, bufferType);
} else if (dictFile.isFile()) {
- return new Ver2DictDecoder(dictFile, bufferType);
+ return new Ver2DictDecoder(dictFile, offset, length, bufferType);
}
return null;
}
- public static DictDecoder getDictDecoder(final File dictFile,
- final DictionaryBufferFactory factory) {
+ public static DictDecoder getDictDecoder(final File dictFile, final long offset,
+ final long length, final DictionaryBufferFactory factory) {
if (dictFile.isDirectory()) {
return new Ver4DictDecoder(dictFile, factory);
} else if (dictFile.isFile()) {
- return new Ver2DictDecoder(dictFile, factory);
+ return new Ver2DictDecoder(dictFile, offset, length, factory);
}
return null;
}
- public static DictDecoder getDictDecoder(final File dictFile) {
- return getDictDecoder(dictFile, DictDecoder.USE_READONLY_BYTEBUFFER);
+ public static DictDecoder getDictDecoder(final File dictFile, final long offset,
+ final long length) {
+ return getDictDecoder(dictFile, offset, length, DictDecoder.USE_READONLY_BYTEBUFFER);
}
private FormatSpec() {
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
index bf776cfc5..ae1e443c5 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
@@ -116,13 +116,18 @@ public class Ver2DictDecoder extends AbstractDictDecoder {
}
protected final File mDictionaryBinaryFile;
+ protected final long mOffset;
+ protected final long mLength;
// TODO: Remove mBufferFactory and mDictBuffer from this class members because they are now
// used only for testing.
private final DictionaryBufferFactory mBufferFactory;
protected DictBuffer mDictBuffer;
- /* package */ Ver2DictDecoder(final File file, final int factoryFlag) {
+ /* package */ Ver2DictDecoder(final File file, final long offset, final long length,
+ final int factoryFlag) {
mDictionaryBinaryFile = file;
+ mOffset = offset;
+ mLength = length;
mDictBuffer = null;
if ((factoryFlag & MASK_DICTBUFFER) == USE_READONLY_BYTEBUFFER) {
mBufferFactory = new DictionaryBufferFromReadOnlyByteBufferFactory();
@@ -135,8 +140,11 @@ public class Ver2DictDecoder extends AbstractDictDecoder {
}
}
- /* package */ Ver2DictDecoder(final File file, final DictionaryBufferFactory factory) {
+ /* package */ Ver2DictDecoder(final File file, final long offset, final long length,
+ final DictionaryBufferFactory factory) {
mDictionaryBinaryFile = file;
+ mOffset = offset;
+ mLength = length;
mBufferFactory = factory;
}
@@ -164,9 +172,9 @@ public class Ver2DictDecoder extends AbstractDictDecoder {
public DictionaryHeader readHeader() throws IOException, UnsupportedFormatException {
// dictType is not being used in dicttool. Passing an empty string.
final BinaryDictionary binaryDictionary = new BinaryDictionary(
- mDictionaryBinaryFile.getAbsolutePath(), 0 /* offset */,
- mDictionaryBinaryFile.length() /* length */, true /* useFullEditDistance */,
- null /* locale */, "" /* dictType */, false /* isUpdatable */);
+ mDictionaryBinaryFile.getAbsolutePath(), mOffset, mLength,
+ true /* useFullEditDistance */, null /* locale */, "" /* dictType */,
+ false /* isUpdatable */);
final DictionaryHeader header = binaryDictionary.getHeader();
binaryDictionary.close();
if (header == null) {
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index 8ea712835..afa8fe3a8 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -95,9 +95,9 @@ final class SuggestionStripLayoutHelper {
private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD);
private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan();
- private final int mSuggestionStripOption;
+ private final int mSuggestionStripOptions;
// These constants are the flag values of
- // {@link R.styleable#SuggestionStripView_suggestionStripOption} attribute.
+ // {@link R.styleable#SuggestionStripView_suggestionStripOptions} attribute.
private static final int AUTO_CORRECT_BOLD = 0x01;
private static final int AUTO_CORRECT_UNDERLINE = 0x02;
private static final int VALID_TYPED_WORD_BOLD = 0x04;
@@ -122,8 +122,8 @@ final class SuggestionStripLayoutHelper {
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.SuggestionStripView, defStyle, R.style.SuggestionStripView);
- mSuggestionStripOption = a.getInt(
- R.styleable.SuggestionStripView_suggestionStripOption, 0);
+ mSuggestionStripOptions = a.getInt(
+ R.styleable.SuggestionStripView_suggestionStripOptions, 0);
mAlphaObsoleted = ResourceUtils.getFraction(a,
R.styleable.SuggestionStripView_alphaObsoleted, 1.0f);
mColorValidTypedWord = a.getColor(R.styleable.SuggestionStripView_colorValidTypedWord, 0);
@@ -200,22 +200,24 @@ final class SuggestionStripLayoutHelper {
return null;
}
final String word = suggestedWords.getLabel(indexInSuggestedWords);
- final boolean isAutoCorrect = indexInSuggestedWords == 1
- && suggestedWords.mWillAutoCorrect;
- final boolean isTypedWordValid = indexInSuggestedWords == 0
- && suggestedWords.mTypedWordValid;
- if (!isAutoCorrect && !isTypedWordValid) {
+ // TODO: don't use the index to decide whether this is the auto-correction/typed word, as
+ // this is brittle
+ final boolean isAutoCorrection = suggestedWords.mWillAutoCorrect
+ && indexInSuggestedWords == SuggestedWords.INDEX_OF_AUTO_CORRECTION;
+ final boolean isTypedWordValid = suggestedWords.mTypedWordValid
+ && indexInSuggestedWords == SuggestedWords.INDEX_OF_TYPED_WORD;
+ if (!isAutoCorrection && !isTypedWordValid) {
return word;
}
final int len = word.length();
final Spannable spannedWord = new SpannableString(word);
- final int option = mSuggestionStripOption;
- if ((isAutoCorrect && (option & AUTO_CORRECT_BOLD) != 0)
- || (isTypedWordValid && (option & VALID_TYPED_WORD_BOLD) != 0)) {
+ final int options = mSuggestionStripOptions;
+ if ((isAutoCorrection && (options & AUTO_CORRECT_BOLD) != 0)
+ || (isTypedWordValid && (options & VALID_TYPED_WORD_BOLD) != 0)) {
spannedWord.setSpan(BOLD_SPAN, 0, len, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
- if (isAutoCorrect && (option & AUTO_CORRECT_UNDERLINE) != 0) {
+ if (isAutoCorrection && (options & AUTO_CORRECT_UNDERLINE) != 0) {
spannedWord.setSpan(UNDERLINE_SPAN, 0, len, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
return spannedWord;
@@ -242,22 +244,23 @@ final class SuggestionStripLayoutHelper {
return indexInSuggestedWords;
}
- private int getSuggestionTextColor(final int indexInSuggestedWords,
- final SuggestedWords suggestedWords) {
+ private int getSuggestionTextColor(final SuggestedWords suggestedWords,
+ final int indexInSuggestedWords) {
final int positionInStrip =
getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords);
- // TODO: Need to revisit this logic with bigram suggestions
- final boolean isSuggested = (indexInSuggestedWords != SuggestedWords.INDEX_OF_TYPED_WORD);
+ // Use identity for strings, not #equals : it's the typed word if it's the same object
+ final boolean isTypedWord =
+ suggestedWords.getWord(indexInSuggestedWords) == suggestedWords.mTypedWord;
final int color;
if (positionInStrip == mCenterPositionInStrip && suggestedWords.mWillAutoCorrect) {
color = mColorAutoCorrect;
- } else if (positionInStrip == mCenterPositionInStrip && suggestedWords.mTypedWordValid) {
+ } else if (isTypedWord && suggestedWords.mTypedWordValid) {
color = mColorValidTypedWord;
- } else if (isSuggested) {
- color = mColorSuggested;
- } else {
+ } else if (isTypedWord) {
color = mColorTypedWord;
+ } else {
+ color = mColorSuggested;
}
if (LatinImeLogger.sDBG && suggestedWords.size() > 1) {
// If we auto-correct, then the autocorrection is in slot 0 and the typed word
@@ -270,7 +273,7 @@ final class SuggestionStripLayoutHelper {
}
}
- if (suggestedWords.mIsObsoleteSuggestions && isSuggested) {
+ if (suggestedWords.mIsObsoleteSuggestions && !isTypedWord) {
return applyAlpha(color, mAlphaObsoleted);
}
return color;
@@ -438,7 +441,7 @@ final class SuggestionStripLayoutHelper {
// {@link SuggestionStripView#onClick(View)}.
wordView.setTag(indexInSuggestedWords);
wordView.setText(getStyledSuggestedWord(suggestedWords, indexInSuggestedWords));
- wordView.setTextColor(getSuggestionTextColor(positionInStrip, suggestedWords));
+ wordView.setTextColor(getSuggestionTextColor(suggestedWords, indexInSuggestedWords));
if (SuggestionStripView.DBG) {
mDebugInfoViews.get(positionInStrip).setText(
suggestedWords.getDebugString(indexInSuggestedWords));
diff --git a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java
new file mode 100644
index 000000000..ee9718ad3
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java
@@ -0,0 +1,55 @@
+/*
+ * 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.utils;
+
+import com.android.inputmethod.annotations.UsedForTesting;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Utilities to manage executors.
+ */
+public class ExecutorUtils {
+ private static final ConcurrentHashMap<String, PrioritizedSerialExecutor>
+ sExecutorMap = CollectionUtils.newConcurrentHashMap();
+ /**
+ * Gets the executor for the given dictionary name.
+ */
+ public static PrioritizedSerialExecutor getExecutor(final String dictName) {
+ PrioritizedSerialExecutor executor = sExecutorMap.get(dictName);
+ if (executor == null) {
+ synchronized(sExecutorMap) {
+ executor = new PrioritizedSerialExecutor();
+ sExecutorMap.put(dictName, executor);
+ }
+ }
+ return executor;
+ }
+
+ /**
+ * Shutdowns all executors and removes all executors from the executor map for testing.
+ */
+ @UsedForTesting
+ public static void shutdownAllExecutors() {
+ synchronized(sExecutorMap) {
+ for (final PrioritizedSerialExecutor executor : sExecutorMap.values()) {
+ executor.shutdown();
+ sExecutorMap.remove(executor);
+ }
+ }
+ }
+}