address some more warnings

This commit is contained in:
Helium314 2023-09-10 12:39:01 +02:00
parent 6c0f1361d9
commit ac1cc0a690
9 changed files with 184 additions and 252 deletions

View file

@ -51,7 +51,6 @@ import java.util.Locale;
*/ */
public final class BinaryDictionaryFileDumper { public final class BinaryDictionaryFileDumper {
private static final String TAG = BinaryDictionaryFileDumper.class.getSimpleName(); private static final String TAG = BinaryDictionaryFileDumper.class.getSimpleName();
private static final boolean DEBUG = false;
/** /**
* The size of the temporary buffer to copy files. * The size of the temporary buffer to copy files.
@ -63,10 +62,8 @@ public final class BinaryDictionaryFileDumper {
private static final byte[] MAGIC_NUMBER_VERSION_2 = private static final byte[] MAGIC_NUMBER_VERSION_2 =
new byte[] { (byte)0x9B, (byte)0xC1, (byte)0x3A, (byte)0xFE }; new byte[] { (byte)0x9B, (byte)0xC1, (byte)0x3A, (byte)0xFE };
private static final boolean SHOULD_VERIFY_MAGIC_NUMBER = private static final boolean SHOULD_VERIFY_MAGIC_NUMBER = DecoderSpecificConstants.SHOULD_VERIFY_MAGIC_NUMBER;
DecoderSpecificConstants.SHOULD_VERIFY_MAGIC_NUMBER; private static final boolean SHOULD_VERIFY_CHECKSUM = DecoderSpecificConstants.SHOULD_VERIFY_CHECKSUM;
private static final boolean SHOULD_VERIFY_CHECKSUM =
DecoderSpecificConstants.SHOULD_VERIFY_CHECKSUM;
private static final String[] DICTIONARY_PROJECTION = {"id"}; private static final String[] DICTIONARY_PROJECTION = {"id"};

View file

@ -69,7 +69,7 @@ final public class BinaryDictionaryGetter {
public static final String ASSETS_DICTIONARY_FOLDER = "dicts"; public static final String ASSETS_DICTIONARY_FOLDER = "dicts";
// The key considered to read the version attribute in a dictionary file. // The key considered to read the version attribute in a dictionary file.
private static String VERSION_KEY = "version"; private static final String VERSION_KEY = "version";
// Prevents this from being instantiated // Prevents this from being instantiated
private BinaryDictionaryGetter() {} private BinaryDictionaryGetter() {}
@ -225,15 +225,7 @@ final public class BinaryDictionaryGetter {
// Version 18 is the first one to include the whitelist // Version 18 is the first one to include the whitelist
// Obviously this is a big ## HACK ## // Obviously this is a big ## HACK ##
return Integer.parseInt(version) >= 18; return Integer.parseInt(version) >= 18;
} catch (java.io.FileNotFoundException e) { } catch (IOException | NumberFormatException | BufferUnderflowException | UnsupportedFormatException e) {
return false;
} catch (java.io.IOException e) {
return false;
} catch (NumberFormatException e) {
return false;
} catch (BufferUnderflowException e) {
return false;
} catch (UnsupportedFormatException e) {
return false; return false;
} }
} }
@ -276,8 +268,7 @@ final public class BinaryDictionaryGetter {
final AssetFileAddress afa = AssetFileAddress.makeFromFileName(f.getPath()); final AssetFileAddress afa = AssetFileAddress.makeFromFileName(f.getPath());
if (null != afa) fileList.add(afa); if (null != afa) fileList.add(afa);
} else { } else {
Log.e(TAG, "Found a cached dictionary file for " + locale.toString() Log.e(TAG, "Found a cached dictionary file for " + locale + " but cannot read or use it");
+ " but cannot read or use it");
} }
} }

View file

@ -27,7 +27,7 @@ import java.util.concurrent.TimeUnit;
* This class automatically creates and releases up to 3 facilitator instances using LRU policy. * This class automatically creates and releases up to 3 facilitator instances using LRU policy.
*/ */
public class DictionaryFacilitatorLruCache { public class DictionaryFacilitatorLruCache {
private static final String TAG = "DictionaryFacilitatorLruCache"; private static final String TAG = "DictFacilitatorLruCache";
private static final int WAIT_FOR_LOADING_MAIN_DICT_IN_MILLISECONDS = 1000; private static final int WAIT_FOR_LOADING_MAIN_DICT_IN_MILLISECONDS = 1000;
private static final int MAX_RETRY_COUNT_FOR_WAITING_FOR_LOADING_DICT = 5; private static final int MAX_RETRY_COUNT_FOR_WAITING_FOR_LOADING_DICT = 5;

View file

@ -34,10 +34,10 @@ import java.util.List;
* A class for detecting Emoji-Alt physical key. * A class for detecting Emoji-Alt physical key.
*/ */
final class EmojiAltPhysicalKeyDetector { final class EmojiAltPhysicalKeyDetector {
private static final String TAG = "EmojiAltPhysicalKeyDetector"; private static final String TAG = "EmojiAltPhysKeyDetector";
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
private List<EmojiHotKeys> mHotKeysList; private final List<EmojiHotKeys> mHotKeysList;
private static class HotKeySet extends HashSet<Pair<Integer, Integer>> { } private static class HotKeySet extends HashSet<Pair<Integer, Integer>> { }
@ -120,7 +120,7 @@ final class EmojiAltPhysicalKeyDetector {
} }
public EmojiAltPhysicalKeyDetector(@NonNull final Resources resources) { public EmojiAltPhysicalKeyDetector(@NonNull final Resources resources) {
mHotKeysList = new ArrayList<EmojiHotKeys>(); mHotKeysList = new ArrayList<>();
final HotKeySet emojiSwitchSet = parseHotKeys( final HotKeySet emojiSwitchSet = parseHotKeys(
resources, R.array.keyboard_switcher_emoji); resources, R.array.keyboard_switcher_emoji);
@ -192,8 +192,8 @@ final class EmojiAltPhysicalKeyDetector {
Log.w(TAG, "Expected 2 integers in " + name + "[" + i + "] : " + values[i]); Log.w(TAG, "Expected 2 integers in " + name + "[" + i + "] : " + values[i]);
} }
try { try {
final Integer keyCode = Integer.parseInt(valuePair[0]); final int keyCode = Integer.parseInt(valuePair[0]);
final Integer metaState = Integer.parseInt(valuePair[1]); final int metaState = Integer.parseInt(valuePair[1]);
final Pair<Integer, Integer> key = Pair.create( final Pair<Integer, Integer> key = Pair.create(
keyCode, KeyEvent.normalizeMetaState(metaState)); keyCode, KeyEvent.normalizeMetaState(metaState));
keySet.add(key); keySet.add(key);

View file

@ -169,16 +169,13 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
} }
private static void asyncExecuteTaskWithLock(final Lock lock, final Runnable task) { private static void asyncExecuteTaskWithLock(final Lock lock, final Runnable task) {
ExecutorUtils.getBackgroundExecutor(ExecutorUtils.KEYBOARD).execute(new Runnable() { ExecutorUtils.getBackgroundExecutor(ExecutorUtils.KEYBOARD).execute(() -> {
@Override
public void run() {
lock.lock(); lock.lock();
try { try {
task.run(); task.run();
} finally { } finally {
lock.unlock(); lock.unlock();
} }
}
}); });
} }
@ -199,12 +196,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
*/ */
@Override @Override
public void close() { public void close() {
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(this::closeBinaryDictionary);
@Override
public void run() {
closeBinaryDictionary();
}
});
} }
protected Map<String, String> getHeaderAttributeMap() { protected Map<String, String> getHeaderAttributeMap() {
@ -220,12 +212,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
} }
private void removeBinaryDictionary() { private void removeBinaryDictionary() {
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(this::removeBinaryDictionaryLocked);
@Override
public void run() {
removeBinaryDictionaryLocked();
}
});
} }
void removeBinaryDictionaryLocked() { void removeBinaryDictionaryLocked() {
@ -248,12 +235,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
} }
public void clear() { public void clear() {
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(() -> {
@Override
public void run() {
removeBinaryDictionaryLocked(); removeBinaryDictionaryLocked();
createOnMemoryBinaryDictionaryLocked(); createOnMemoryBinaryDictionaryLocked();
}
}); });
} }
@ -261,14 +245,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
* Check whether GC is needed and run GC if required. * Check whether GC is needed and run GC if required.
*/ */
public void runGCIfRequired(final boolean mindsBlockByGC) { public void runGCIfRequired(final boolean mindsBlockByGC) {
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(() -> {
@Override
public void run() {
if (getBinaryDictionary() == null) { if (getBinaryDictionary() == null) {
return; return;
} }
runGCIfRequiredLocked(mindsBlockByGC); runGCIfRequiredLocked(mindsBlockByGC);
}
}); });
} }
@ -280,17 +261,13 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
private void updateDictionaryWithWriteLock(@NonNull final Runnable updateTask) { private void updateDictionaryWithWriteLock(@NonNull final Runnable updateTask) {
reloadDictionaryIfRequired(); reloadDictionaryIfRequired();
final Runnable task = new Runnable() { asyncExecuteTaskWithWriteLock(() -> {
@Override
public void run() {
if (getBinaryDictionary() == null) { if (getBinaryDictionary() == null) {
return; return;
} }
runGCIfRequiredLocked(true /* mindsBlockByGC */); runGCIfRequiredLocked(true /* mindsBlockByGC */);
updateTask.run(); updateTask.run();
} });
};
asyncExecuteTaskWithWriteLock(task);
} }
/** /**
@ -299,13 +276,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
public void addUnigramEntry(final String word, final int frequency, public void addUnigramEntry(final String word, final int frequency,
final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord, final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord,
final boolean isPossiblyOffensive, final int timestamp) { final boolean isPossiblyOffensive, final int timestamp) {
updateDictionaryWithWriteLock(new Runnable() { updateDictionaryWithWriteLock(() -> addUnigramLocked(word, frequency, shortcutTarget,
@Override shortcutFreq, isNotAWord, isPossiblyOffensive, timestamp));
public void run() {
addUnigramLocked(word, frequency, shortcutTarget, shortcutFreq,
isNotAWord, isPossiblyOffensive, timestamp);
}
});
} }
protected void addUnigramLocked(final String word, final int frequency, protected void addUnigramLocked(final String word, final int frequency,
@ -322,9 +294,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
*/ */
public void removeUnigramEntryDynamically(final String word) { public void removeUnigramEntryDynamically(final String word) {
reloadDictionaryIfRequired(); reloadDictionaryIfRequired();
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(() -> {
@Override
public void run() {
final BinaryDictionary binaryDictionary = getBinaryDictionary(); final BinaryDictionary binaryDictionary = getBinaryDictionary();
if (binaryDictionary == null) { if (binaryDictionary == null) {
return; return;
@ -335,7 +305,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
Log.i(TAG, "Cannot remove unigram entry: " + word); Log.i(TAG, "Cannot remove unigram entry: " + word);
} }
} }
}
}); });
} }
@ -345,15 +314,12 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
public void addNgramEntry(@NonNull final NgramContext ngramContext, final String word, public void addNgramEntry(@NonNull final NgramContext ngramContext, final String word,
final int frequency, final int timestamp) { final int frequency, final int timestamp) {
reloadDictionaryIfRequired(); reloadDictionaryIfRequired();
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(() -> {
@Override
public void run() {
if (getBinaryDictionary() == null) { if (getBinaryDictionary() == null) {
return; return;
} }
runGCIfRequiredLocked(true /* mindsBlockByGC */); runGCIfRequiredLocked(true /* mindsBlockByGC */);
addNgramEntryLocked(ngramContext, word, frequency, timestamp); addNgramEntryLocked(ngramContext, word, frequency, timestamp);
}
}); });
} }
@ -372,9 +338,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
*/ */
public void updateEntriesForWord(@NonNull final NgramContext ngramContext, public void updateEntriesForWord(@NonNull final NgramContext ngramContext,
final String word, final boolean isValidWord, final int count, final int timestamp) { final String word, final boolean isValidWord, final int count, final int timestamp) {
updateDictionaryWithWriteLock(new Runnable() { updateDictionaryWithWriteLock(() -> {
@Override
public void run() {
final BinaryDictionary binaryDictionary = getBinaryDictionary(); final BinaryDictionary binaryDictionary = getBinaryDictionary();
if (binaryDictionary == null) { if (binaryDictionary == null) {
return; return;
@ -383,8 +347,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
isValidWord, count, timestamp)) { isValidWord, count, timestamp)) {
if (DEBUG) { if (DEBUG) {
Log.e(TAG, "Cannot update counter. word: " + word Log.e(TAG, "Cannot update counter. word: " + word
+ " context: " + ngramContext.toString()); + " context: " + ngramContext);
}
} }
} }
}); });
@ -410,23 +373,18 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@NonNull final ArrayList<WordInputEventForPersonalization> inputEvents, @NonNull final ArrayList<WordInputEventForPersonalization> inputEvents,
final UpdateEntriesForInputEventsCallback callback) { final UpdateEntriesForInputEventsCallback callback) {
reloadDictionaryIfRequired(); reloadDictionaryIfRequired();
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(() -> {
@Override
public void run() {
try { try {
final BinaryDictionary binaryDictionary = getBinaryDictionary(); final BinaryDictionary binaryDictionary = getBinaryDictionary();
if (binaryDictionary == null) { if (binaryDictionary == null) {
return; return;
} }
binaryDictionary.updateEntriesForInputEvents( binaryDictionary.updateEntriesForInputEvents(inputEvents.toArray(new WordInputEventForPersonalization[0]));
inputEvents.toArray(
new WordInputEventForPersonalization[inputEvents.size()]));
} finally { } finally {
if (callback != null) { if (callback != null) {
callback.onFinished(); callback.onFinished();
} }
} }
}
}); });
} }
@ -601,9 +559,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
return; return;
} }
final File dictFile = mDictFile; final File dictFile = mDictFile;
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(() -> {
@Override
public void run() {
try { try {
if (!dictFile.exists() || isNeededToRecreate()) { if (!dictFile.exists() || isNeededToRecreate()) {
// If the dictionary file does not exist or contents have been updated, // If the dictionary file does not exist or contents have been updated,
@ -615,8 +571,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
final BinaryDictionary binaryDictionary = getBinaryDictionary(); final BinaryDictionary binaryDictionary = getBinaryDictionary();
if (binaryDictionary != null && !(isValidDictionaryLocked() if (binaryDictionary != null && !(isValidDictionaryLocked()
// TODO: remove the check below // TODO: remove the check below
&& matchesExpectedBinaryDictFormatVersionForThisType( && matchesExpectedBinaryDictFormatVersionForThisType(binaryDictionary.getFormatVersion()))) {
binaryDictionary.getFormatVersion()))) {
// Binary dictionary or its format version is not valid. Regenerate // Binary dictionary or its format version is not valid. Regenerate
// the dictionary file. createNewDictionaryLocked will remove the // the dictionary file. createNewDictionaryLocked will remove the
// existing files if appropriate. // existing files if appropriate.
@ -627,7 +582,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
} finally { } finally {
isReloading.set(false); isReloading.set(false);
} }
}
}); });
} }
@ -636,9 +590,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
*/ */
@Override @Override
public void onFinishInput() { public void onFinishInput() {
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(() -> {
@Override
public void run() {
final BinaryDictionary binaryDictionary = getBinaryDictionary(); final BinaryDictionary binaryDictionary = getBinaryDictionary();
if (binaryDictionary == null) { if (binaryDictionary == null) {
return; return;
@ -648,7 +600,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
} else { } else {
binaryDictionary.flush(); binaryDictionary.flush();
} }
}
}); });
} }
@ -670,12 +621,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@UsedForTesting @UsedForTesting
public void waitAllTasksForTests() { public void waitAllTasksForTests() {
final CountDownLatch countDownLatch = new CountDownLatch(1); final CountDownLatch countDownLatch = new CountDownLatch(1);
asyncExecuteTaskWithWriteLock(new Runnable() { asyncExecuteTaskWithWriteLock(countDownLatch::countDown);
@Override
public void run() {
countDownLatch.countDown();
}
});
try { try {
countDownLatch.await(); countDownLatch.await();
} catch (InterruptedException e) { } catch (InterruptedException e) {
@ -694,9 +640,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
reloadDictionaryIfRequired(); reloadDictionaryIfRequired();
final String tag = TAG; final String tag = TAG;
final String dictName = mDictName; final String dictName = mDictName;
asyncExecuteTaskWithLock(mLock.readLock(), new Runnable() { asyncExecuteTaskWithLock(mLock.readLock(), () -> {
@Override
public void run() {
Log.d(tag, "Dump dictionary: " + dictName + " for " + mLocale); Log.d(tag, "Dump dictionary: " + dictName + " for " + mLocale);
final BinaryDictionary binaryDictionary = getBinaryDictionary(); final BinaryDictionary binaryDictionary = getBinaryDictionary();
if (binaryDictionary == null) { if (binaryDictionary == null) {
@ -705,8 +649,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
try { try {
final DictionaryHeader header = binaryDictionary.getHeader(); final DictionaryHeader header = binaryDictionary.getHeader();
Log.d(tag, "Format version: " + binaryDictionary.getFormatVersion()); Log.d(tag, "Format version: " + binaryDictionary.getFormatVersion());
Log.d(tag, CombinedFormatUtils.formatAttributeMap( Log.d(tag, CombinedFormatUtils.formatAttributeMap(header.mDictionaryOptions.mAttributes));
header.mDictionaryOptions.mAttributes));
} catch (final UnsupportedFormatException e) { } catch (final UnsupportedFormatException e) {
Log.d(tag, "Cannot fetch header information.", e); Log.d(tag, "Cannot fetch header information.", e);
} }
@ -722,7 +665,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
Log.d(tag, wordProperty.toString()); Log.d(tag, wordProperty.toString());
token = result.mNextToken; token = result.mNextToken;
} while (token != 0); } while (token != 0);
}
}); });
} }
@ -733,9 +675,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
reloadDictionaryIfRequired(); reloadDictionaryIfRequired();
final AsyncResultHolder<WordProperty[]> result = final AsyncResultHolder<WordProperty[]> result =
new AsyncResultHolder<>("WordPropertiesForSync"); new AsyncResultHolder<>("WordPropertiesForSync");
asyncExecuteTaskWithLock(mLock.readLock(), new Runnable() { asyncExecuteTaskWithLock(mLock.readLock(), () -> {
@Override
public void run() {
final ArrayList<WordProperty> wordPropertyList = new ArrayList<>(); final ArrayList<WordProperty> wordPropertyList = new ArrayList<>();
final BinaryDictionary binaryDictionary = getBinaryDictionary(); final BinaryDictionary binaryDictionary = getBinaryDictionary();
if (binaryDictionary == null) { if (binaryDictionary == null) {
@ -753,11 +693,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
wordPropertyList.add(wordProperty); wordPropertyList.add(wordProperty);
token = nextWordPropertyResult.mNextToken; token = nextWordPropertyResult.mNextToken;
} while (token != 0); } while (token != 0);
result.set(wordPropertyList.toArray(new WordProperty[wordPropertyList.size()])); result.set(wordPropertyList.toArray(new WordProperty[0]));
}
}); });
// TODO: Figure out the best timeout duration for this API. // TODO: Figure out the best timeout duration for this API.
return result.get(DEFAULT_WORD_PROPERTIES_FOR_SYNC, return result.get(DEFAULT_WORD_PROPERTIES_FOR_SYNC, TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS);
TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS);
} }
} }

View file

@ -16,12 +16,11 @@
package org.dslul.openboard.inputmethod.latin; package org.dslul.openboard.inputmethod.latin;
import android.os.Build;
import android.text.InputType; import android.text.InputType;
import android.util.Log; import android.util.Log;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import androidx.core.view.inputmethod.EditorInfoCompat;
import org.dslul.openboard.inputmethod.latin.common.StringUtils; import org.dslul.openboard.inputmethod.latin.common.StringUtils;
import org.dslul.openboard.inputmethod.latin.utils.InputTypeUtils; import org.dslul.openboard.inputmethod.latin.utils.InputTypeUtils;
@ -94,14 +93,10 @@ public final class InputAttributes {
} }
// inputClass == InputType.TYPE_CLASS_TEXT // inputClass == InputType.TYPE_CLASS_TEXT
final int variation = inputType & InputType.TYPE_MASK_VARIATION; final int variation = inputType & InputType.TYPE_MASK_VARIATION;
final boolean flagNoSuggestions = final boolean flagNoSuggestions = 0 != (inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
0 != (inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); final boolean flagMultiLine = 0 != (inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE);
final boolean flagMultiLine = final boolean flagAutoCorrect = 0 != (inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT);
0 != (inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE); final boolean flagAutoComplete = 0 != (inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE);
final boolean flagAutoCorrect =
0 != (inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT);
final boolean flagAutoComplete =
0 != (inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE);
// TODO: Have a helper method in InputTypeUtils // TODO: Have a helper method in InputTypeUtils
// Make sure that passwords are not displayed in {@link SuggestionStripView}. // Make sure that passwords are not displayed in {@link SuggestionStripView}.
@ -140,7 +135,10 @@ public final class InputAttributes {
&& InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD != variation; && InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD != variation;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
mNoLearning = flagNoSuggestions || (editorInfo.imeOptions & EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING) != 0; mNoLearning = flagNoSuggestions || (editorInfo.imeOptions & EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING) != 0;
else
mNoLearning = flagNoSuggestions;
} }
public boolean isTypeNull() { public boolean isTypeNull() {

View file

@ -43,7 +43,7 @@ public class RichInputMethodSubtype {
private static final String TAG = RichInputMethodSubtype.class.getSimpleName(); private static final String TAG = RichInputMethodSubtype.class.getSimpleName();
private static final HashMap<Locale, Locale> sLocaleMap = initializeLocaleMap(); private static final HashMap<Locale, Locale> sLocaleMap = initializeLocaleMap();
private static final HashMap<Locale, Locale> initializeLocaleMap() { private static HashMap<Locale, Locale> initializeLocaleMap() {
final HashMap<Locale, Locale> map = new HashMap<>(); final HashMap<Locale, Locale> map = new HashMap<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// Locale#forLanguageTag is available on API Level 21+. // Locale#forLanguageTag is available on API Level 21+.
@ -182,12 +182,18 @@ public class RichInputMethodSubtype {
+ "," + Constants.Subtype.ExtraValue.EMOJI_CAPABLE; + "," + Constants.Subtype.ExtraValue.EMOJI_CAPABLE;
@NonNull @NonNull
private static final RichInputMethodSubtype DUMMY_NO_LANGUAGE_SUBTYPE = private static final RichInputMethodSubtype DUMMY_NO_LANGUAGE_SUBTYPE =
new RichInputMethodSubtype(new InputMethodSubtype( new RichInputMethodSubtype(new InputMethodSubtype.InputMethodSubtypeBuilder()
R.string.subtype_no_language_qwerty, R.drawable.ic_ime_switcher_dark, .setSubtypeNameResId(R.string.subtype_no_language_qwerty)
SubtypeLocaleUtils.NO_LANGUAGE, KEYBOARD_MODE, .setSubtypeIconResId(R.drawable.ic_ime_switcher_dark)
EXTRA_VALUE_OF_DUMMY_NO_LANGUAGE_SUBTYPE, .setSubtypeLocale(SubtypeLocaleUtils.NO_LANGUAGE)
false /* isAuxiliary */, false /* overridesImplicitlyEnabledSubtype */, .setSubtypeMode(KEYBOARD_MODE)
SUBTYPE_ID_OF_DUMMY_NO_LANGUAGE_SUBTYPE)); .setSubtypeExtraValue(EXTRA_VALUE_OF_DUMMY_NO_LANGUAGE_SUBTYPE)
.setIsAuxiliary(false)
.setOverridesImplicitlyEnabledSubtype(false)
.setSubtypeId(SUBTYPE_ID_OF_DUMMY_NO_LANGUAGE_SUBTYPE)
.setIsAsciiCapable(true)
.build());
// Caveat: We probably should remove this when we add an Emoji subtype in {@link R.xml.method}. // Caveat: We probably should remove this when we add an Emoji subtype in {@link R.xml.method}.
// Dummy Emoji subtype. See {@link R.xml.method}. // Dummy Emoji subtype. See {@link R.xml.method}.
private static final int SUBTYPE_ID_OF_DUMMY_EMOJI_SUBTYPE = 0xd78b2ed0; private static final int SUBTYPE_ID_OF_DUMMY_EMOJI_SUBTYPE = 0xd78b2ed0;
@ -195,13 +201,17 @@ public class RichInputMethodSubtype {
"KeyboardLayoutSet=" + SubtypeLocaleUtils.EMOJI "KeyboardLayoutSet=" + SubtypeLocaleUtils.EMOJI
+ "," + Constants.Subtype.ExtraValue.EMOJI_CAPABLE; + "," + Constants.Subtype.ExtraValue.EMOJI_CAPABLE;
@NonNull @NonNull
private static final RichInputMethodSubtype DUMMY_EMOJI_SUBTYPE = new RichInputMethodSubtype( private static final RichInputMethodSubtype DUMMY_EMOJI_SUBTYPE =
new InputMethodSubtype( new RichInputMethodSubtype(new InputMethodSubtype.InputMethodSubtypeBuilder()
R.string.subtype_emoji, R.drawable.ic_ime_switcher_dark, .setSubtypeNameResId(R.string.subtype_emoji)
SubtypeLocaleUtils.NO_LANGUAGE, KEYBOARD_MODE, .setSubtypeIconResId(R.drawable.ic_ime_switcher_dark)
EXTRA_VALUE_OF_DUMMY_EMOJI_SUBTYPE, .setSubtypeLocale(SubtypeLocaleUtils.NO_LANGUAGE)
false /* isAuxiliary */, false /* overridesImplicitlyEnabledSubtype */, .setSubtypeMode(KEYBOARD_MODE)
SUBTYPE_ID_OF_DUMMY_EMOJI_SUBTYPE)); .setSubtypeExtraValue(EXTRA_VALUE_OF_DUMMY_EMOJI_SUBTYPE)
.setIsAuxiliary(false)
.setOverridesImplicitlyEnabledSubtype(false)
.setSubtypeId(SUBTYPE_ID_OF_DUMMY_EMOJI_SUBTYPE)
.build());
private static RichInputMethodSubtype sNoLanguageSubtype; private static RichInputMethodSubtype sNoLanguageSubtype;
private static RichInputMethodSubtype sEmojiSubtype; private static RichInputMethodSubtype sEmojiSubtype;
@ -210,8 +220,7 @@ public class RichInputMethodSubtype {
RichInputMethodSubtype noLanguageSubtype = sNoLanguageSubtype; RichInputMethodSubtype noLanguageSubtype = sNoLanguageSubtype;
if (noLanguageSubtype == null) { if (noLanguageSubtype == null) {
final InputMethodSubtype rawNoLanguageSubtype = RichInputMethodManager.getInstance() final InputMethodSubtype rawNoLanguageSubtype = RichInputMethodManager.getInstance()
.findSubtypeByLocaleAndKeyboardLayoutSet( .findSubtypeByLocaleAndKeyboardLayoutSet(SubtypeLocaleUtils.NO_LANGUAGE, SubtypeLocaleUtils.QWERTY);
SubtypeLocaleUtils.NO_LANGUAGE, SubtypeLocaleUtils.QWERTY);
if (rawNoLanguageSubtype != null) { if (rawNoLanguageSubtype != null) {
noLanguageSubtype = new RichInputMethodSubtype(rawNoLanguageSubtype); noLanguageSubtype = new RichInputMethodSubtype(rawNoLanguageSubtype);
} }
@ -221,8 +230,7 @@ public class RichInputMethodSubtype {
return noLanguageSubtype; return noLanguageSubtype;
} }
Log.w(TAG, "Can't find any language with QWERTY subtype"); Log.w(TAG, "Can't find any language with QWERTY subtype");
Log.w(TAG, "No input method subtype found; returning dummy subtype: " Log.w(TAG, "No input method subtype found; returning dummy subtype: " + DUMMY_NO_LANGUAGE_SUBTYPE);
+ DUMMY_NO_LANGUAGE_SUBTYPE);
return DUMMY_NO_LANGUAGE_SUBTYPE; return DUMMY_NO_LANGUAGE_SUBTYPE;
} }
@ -231,8 +239,7 @@ public class RichInputMethodSubtype {
RichInputMethodSubtype emojiSubtype = sEmojiSubtype; RichInputMethodSubtype emojiSubtype = sEmojiSubtype;
if (emojiSubtype == null) { if (emojiSubtype == null) {
final InputMethodSubtype rawEmojiSubtype = RichInputMethodManager.getInstance() final InputMethodSubtype rawEmojiSubtype = RichInputMethodManager.getInstance()
.findSubtypeByLocaleAndKeyboardLayoutSet( .findSubtypeByLocaleAndKeyboardLayoutSet(SubtypeLocaleUtils.NO_LANGUAGE, SubtypeLocaleUtils.EMOJI);
SubtypeLocaleUtils.NO_LANGUAGE, SubtypeLocaleUtils.EMOJI);
if (rawEmojiSubtype != null) { if (rawEmojiSubtype != null) {
emojiSubtype = new RichInputMethodSubtype(rawEmojiSubtype); emojiSubtype = new RichInputMethodSubtype(rawEmojiSubtype);
} }
@ -242,8 +249,7 @@ public class RichInputMethodSubtype {
return emojiSubtype; return emojiSubtype;
} }
Log.w(TAG, "Can't find emoji subtype"); Log.w(TAG, "Can't find emoji subtype");
Log.w(TAG, "No input method subtype found; returning dummy subtype: " Log.w(TAG, "No input method subtype found; returning dummy subtype: " + DUMMY_EMOJI_SUBTYPE);
+ DUMMY_EMOJI_SUBTYPE);
return DUMMY_EMOJI_SUBTYPE; return DUMMY_EMOJI_SUBTYPE;
} }
} }

View file

@ -203,7 +203,7 @@ public class SuggestedWords {
} }
@NonNull @NonNull
public static final SuggestedWords getEmptyInstance() { public static SuggestedWords getEmptyInstance() {
return SuggestedWords.EMPTY; return SuggestedWords.EMPTY;
} }
@ -347,7 +347,7 @@ public class SuggestedWords {
return (mKindAndFlags & KIND_FLAG_EXACT_MATCH_WITH_INTENTIONAL_OMISSION) != 0; return (mKindAndFlags & KIND_FLAG_EXACT_MATCH_WITH_INTENTIONAL_OMISSION) != 0;
} }
public boolean isAprapreateForAutoCorrection() { public boolean isAppropriateForAutoCorrection() {
return (mKindAndFlags & KIND_FLAG_APPROPRIATE_FOR_AUTO_CORRECTION) != 0; return (mKindAndFlags & KIND_FLAG_APPROPRIATE_FOR_AUTO_CORRECTION) != 0;
} }

View file

@ -18,6 +18,7 @@ package org.dslul.openboard.inputmethod.latin.utils;
import static android.view.KeyEvent.KEYCODE_SPACE; import static android.view.KeyEvent.KEYCODE_SPACE;
import android.annotation.SuppressLint;
import android.os.Build; import android.os.Build;
import android.util.Log; import android.util.Log;
@ -37,6 +38,7 @@ public final class AutoCorrectionUtils {
// Purely static class: can't instantiate. // Purely static class: can't instantiate.
} }
@SuppressLint("ObsoleteSdkInt") // SDK_INT is 0 in unit tests
public static boolean suggestionExceedsThreshold(final SuggestedWordInfo suggestion, public static boolean suggestionExceedsThreshold(final SuggestedWordInfo suggestion,
final String consideredWord, final float threshold) { final String consideredWord, final float threshold) {
if (null != suggestion) { if (null != suggestion) {
@ -44,15 +46,15 @@ public final class AutoCorrectionUtils {
if (suggestion.isKindOf(SuggestedWordInfo.KIND_WHITELIST)) { if (suggestion.isKindOf(SuggestedWordInfo.KIND_WHITELIST)) {
return true; return true;
} }
// TODO: return suggestion.isAprapreateForAutoCorrection(); // TODO: return suggestion.isAppropriateForAutoCorrection();
if (!suggestion.isAprapreateForAutoCorrection()) { if (!suggestion.isAppropriateForAutoCorrection()) {
return false; return false;
} }
final int autoCorrectionSuggestionScore = suggestion.mScore; final int autoCorrectionSuggestionScore = suggestion.mScore;
// TODO: when the normalized score of the first suggestion is nearly equals to // TODO: when the normalized score of the first suggestion is nearly equals to
// the normalized score of the second suggestion, behave less aggressive. // the normalized score of the second suggestion, behave less aggressive.
final float normalizedScore; final float normalizedScore;
if (BuildConfig.DEBUG && Build.VERSION.SDK_INT == 0) // SDK_INT is 0 in unit tests if (BuildConfig.DEBUG && Build.VERSION.SDK_INT == 0)
normalizedScore = calcNormalizedScore(StringUtils.toCodePointArray(consideredWord), StringUtils.toCodePointArray(suggestion.mWord), autoCorrectionSuggestionScore, editDistance(consideredWord, suggestion.mWord)); normalizedScore = calcNormalizedScore(StringUtils.toCodePointArray(consideredWord), StringUtils.toCodePointArray(suggestion.mWord), autoCorrectionSuggestionScore, editDistance(consideredWord, suggestion.mWord));
else else
normalizedScore = BinaryDictionaryUtils.calcNormalizedScore( normalizedScore = BinaryDictionaryUtils.calcNormalizedScore(