remove unused stuff, solve warnings

This commit is contained in:
Helium314 2024-01-01 17:42:26 +01:00
parent cc3a406e51
commit 091222d16d
18 changed files with 59 additions and 263 deletions

View file

@ -12,6 +12,8 @@ import org.dslul.openboard.inputmethod.latin.common.Constants;
import org.dslul.openboard.inputmethod.latin.common.InputPointers;
import org.dslul.openboard.inputmethod.latin.common.ResizableIntArray;
import java.util.Locale;
/**
* This class holds event points to recognize a gesture stroke.
* TODO: Should be package private class.
@ -83,7 +85,7 @@ public final class GestureStrokeRecognitionPoints {
mGestureRecognitionSpeedThreshold = (int)(
keyWidth * mRecognitionParams.mRecognitionSpeedThreshold);
if (DEBUG) {
Log.d(TAG, String.format(
Log.d(TAG, String.format(Locale.US,
"[%d] setKeyboardGeometry: keyWidth=%3d tT=%3d >> %3d tD=%3d >> %3d",
mPointerId, keyWidth,
mRecognitionParams.mDynamicTimeThresholdFrom,
@ -106,7 +108,7 @@ public final class GestureStrokeRecognitionPoints {
mAfterFastTyping = true;
}
if (DEBUG) {
Log.d(TAG, String.format("[%d] onDownEvent: dT=%3d%s", mPointerId,
Log.d(TAG, String.format(Locale.US, "[%d] onDownEvent: dT=%3d%s", mPointerId,
elapsedTimeSinceLastTyping, mAfterFastTyping ? " afterFastTyping" : ""));
}
// Call {@link #addEventPoint(int,int,int,boolean)} to record this down event point as a
@ -157,7 +159,7 @@ public final class GestureStrokeRecognitionPoints {
final boolean isStartOfAGesture = deltaTime >= timeThreshold
&& deltaDistance >= distanceThreshold;
if (DEBUG) {
Log.d(TAG, String.format("[%d] isStartOfAGesture: dT=%3d tT=%3d dD=%3d tD=%3d%s%s",
Log.d(TAG, String.format(Locale.US, "[%d] isStartOfAGesture: dT=%3d tT=%3d dD=%3d tD=%3d%s%s",
mPointerId, deltaTime, timeThreshold,
deltaDistance, distanceThreshold,
mAfterFastTyping ? " afterFastTyping" : "",
@ -173,7 +175,7 @@ public final class GestureStrokeRecognitionPoints {
final int x = mXCoordinates.get(lastIndex);
final int y = mYCoordinates.get(lastIndex);
if (DEBUG) {
Log.d(TAG, String.format("[%d] duplicateLastPointWith: %d,%d|%d", mPointerId,
Log.d(TAG, String.format(Locale.US, "[%d] duplicateLastPointWith: %d,%d|%d", mPointerId,
x, y, time));
}
// TODO: Have appendMajorPoint()
@ -199,7 +201,7 @@ public final class GestureStrokeRecognitionPoints {
// time than the next {@link MotionEvent}. To maintain the monotonicity of the event time,
// drop the successive point here.
if (lastIndex >= 0 && mEventTimes.get(lastIndex) > time) {
Log.w(TAG, String.format("[%d] drop stale event: %d,%d|%d last: %d,%d|%d", mPointerId,
Log.w(TAG, String.format(Locale.US, "[%d] drop stale event: %d,%d|%d last: %d,%d|%d", mPointerId,
x, y, time, mXCoordinates.get(lastIndex), mYCoordinates.get(lastIndex),
mEventTimes.get(lastIndex)));
return;
@ -231,13 +233,13 @@ public final class GestureStrokeRecognitionPoints {
final int pixelsPerSec = pixels * MSEC_PER_SEC;
if (DEBUG_SPEED) {
final float speed = (float)pixelsPerSec / msecs / mKeyWidth;
Log.d(TAG, String.format("[%d] detectFastMove: speed=%5.2f", mPointerId, speed));
Log.d(TAG, String.format(Locale.US, "[%d] detectFastMove: speed=%5.2f", mPointerId, speed));
}
// Equivalent to (pixels / msecs < mStartSpeedThreshold / MSEC_PER_SEC)
if (!hasDetectedFastMove() && pixelsPerSec > mDetectFastMoveSpeedThreshold * msecs) {
if (DEBUG) {
final float speed = (float)pixelsPerSec / msecs / mKeyWidth;
Log.d(TAG, String.format(
Log.d(TAG, String.format(Locale.US,
"[%d] detectFastMove: speed=%5.2f T=%3d points=%3d fastMove",
mPointerId, speed, time, size));
}

View file

@ -470,10 +470,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
label ?: getPeriodLabel(),
params,
width,
Key.LABEL_FLAGS_HAS_POPUP_HINT
// todo (later): check what LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT does, maybe remove the flag here
or if (params.mId.isAlphabetKeyboard) Key.LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT else 0
or defaultLabelFlags,
Key.LABEL_FLAGS_HAS_POPUP_HINT or defaultLabelFlags,
if (label?.first()?.isLetter() == true) Key.BACKGROUND_TYPE_NORMAL
else Key.BACKGROUND_TYPE_FUNCTIONAL,
SimplePopups(moreKeys?.let { getPunctuationMoreKeys() + it } ?: getPunctuationMoreKeys())
@ -512,7 +509,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
params,
width,
Key.LABEL_FLAGS_PRESERVE_CASE or if (!params.mId.isAlphabetKeyboard) Key.LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR else 0,
// todo (later): possibly the whole stickOn/Off stuff can be removed, currently it should only have a very slight effect in holo
// todo (later): possibly the whole stickyOn/Off stuff can be removed, currently it should only have a very slight effect in holo
if (params.mId.mElementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED || params.mId.mElementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED)
Key.BACKGROUND_TYPE_STICKY_ON
else Key.BACKGROUND_TYPE_STICKY_OFF,
@ -781,7 +778,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
private fun isTablet() = context.resources.getInteger(R.integer.config_screen_metrics) >= 3
companion object {
private val TAG = KeyboardParser::class.simpleName
private const val TAG = "KeyboardParser"
fun parseCustom(params: KeyboardParams, context: Context): ArrayList<ArrayList<KeyParams>> {
val layoutName = params.mId.mSubtype.keyboardLayoutSetName

View file

@ -187,13 +187,6 @@ class LocaleKeyTexts(dataStream: InputStream?, locale: Locale) {
}
fun getNumberLabel(numberIndex: Int?): String? = numberIndex?.let { numberKeys.getOrNull(it) }
// get moreKeys with the number itself (as used on alphabet keyboards)
// todo: use it or remove it
/* fun getNumberMoreKeys(numberIndex: Int?): List<String> {
if (numberIndex == null) return emptyList()
return listOf(numberKeys[numberIndex]) + numbersMoreKeys[numberIndex]
}*/
}
private fun mergeMoreKeys(original: Array<String>, added: List<String>): Array<String> {

View file

@ -6,7 +6,6 @@ import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.floris.KeyData
import org.dslul.openboard.inputmethod.keyboard.internal.keyboard_parser.floris.toTextKey
import org.dslul.openboard.inputmethod.latin.common.splitOnWhitespace
import org.dslul.openboard.inputmethod.latin.utils.SubtypeLocaleUtils
/**
* Parser for simple layouts, defined only as rows of (normal) keys with moreKeys.

View file

@ -9,33 +9,8 @@ import android.icu.lang.UCharacter
import android.icu.lang.UCharacterCategory
import android.os.Build
// taken from FlorisBoard, small modifications
// isNonSpacingMark has a fallback for api < 24
/**
* Character codes and comments source:
* https://www.w3.org/International/questions/qa-bidi-unicode-controls#basedirection
*/
@Suppress("unused")
object UnicodeCtrlChar {
/** Sets base direction to LTR and isolates the embedded content from the surrounding text */
const val LeftToRightIsolate = "\u2066"
/** Sets base direction to RTL and isolates the embedded content from the surrounding text */
const val RightToLeftIsolate = "\u2067"
/** Isolates the content and sets the direction according to the first strongly typed directional character */
const val FirstStrongIsolate = "\u2068"
/** Closes a previously opened isolated text block */
const val PopDirectionalIsolate = "\u2069"
val Matcher = """[$LeftToRightIsolate$RightToLeftIsolate$FirstStrongIsolate$PopDirectionalIsolate]""".toRegex()
}
fun String.stripUnicodeCtrlChars(): String {
return this.replace(UnicodeCtrlChar.Matcher, "")
}
// taken from FlorisBoard
// unused parts removed, added fallback for api < 24
object Unicode {
fun isNonSpacingMark(code: Int): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

View file

@ -13,9 +13,6 @@ import android.provider.ContactsContract.Contacts;
* Constants related to Contacts Content Provider.
*/
public class ContactsDictionaryConstants {
/**
* Projections for {@link Contacts.CONTENT_URI}
*/
public static final String[] PROJECTION = { BaseColumns._ID, Contacts.DISPLAY_NAME,
Contacts.TIMES_CONTACTED, Contacts.LAST_TIME_CONTACTED, Contacts.IN_VISIBLE_GROUP };
public static final String[] PROJECTION_ID_ONLY = { BaseColumns._ID };

View file

@ -12,18 +12,13 @@ import android.util.LruCache;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.dslul.openboard.inputmethod.annotations.UsedForTesting;
import org.dslul.openboard.inputmethod.keyboard.Keyboard;
import org.dslul.openboard.inputmethod.latin.common.ComposedData;
import org.dslul.openboard.inputmethod.latin.settings.SettingsValuesForSuggestion;
import org.dslul.openboard.inputmethod.latin.utils.SuggestionResults;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
@ -47,13 +42,11 @@ public interface DictionaryFacilitator {
/**
* The facilitator will put words into the cache whenever it decodes them.
* @param cache
*/
void setValidSpellingWordReadCache(final LruCache<String, Boolean> cache);
/**
* The facilitator will get words from the cache whenever it needs to check their spelling.
* @param cache
*/
void setValidSpellingWordWriteCache(final LruCache<String, Boolean> cache);
@ -77,8 +70,7 @@ public interface DictionaryFacilitator {
/**
* Called every time {@link LatinIME} starts on a new text field.
* Dot not affect {@link AndroidSpellCheckerService}.
*
* <p>
* WARNING: The service methods that call start/finish are very spammy.
*/
void onStartInput();
@ -87,8 +79,7 @@ public interface DictionaryFacilitator {
* Called every time the {@link LatinIME} finishes with the current text field.
* May be followed by {@link #onStartInput} again in another text field,
* or it may be done for a while.
* Dot not affect {@link AndroidSpellCheckerService}.
*
* <p>
* WARNING: The service methods that call start/finish are very spammy.
*/
void onFinishInput(Context context);
@ -118,20 +109,8 @@ public interface DictionaryFacilitator {
void removeWord(String word);
@UsedForTesting
void resetDictionariesForTesting(
final Context context,
final Locale locale,
final ArrayList<String> dictionaryTypes,
final HashMap<String, File> dictionaryFiles,
final Map<String, Map<String, String>> additionalDictAttributes,
@Nullable final String account);
void closeDictionaries();
@UsedForTesting
ExpandableBinaryDictionary getSubDictForTesting(final String dictName);
// The main dictionaries are loaded asynchronously. Don't cache the return value
// of these methods.
boolean hasAtLeastOneInitializedMainDictionary();
@ -141,10 +120,6 @@ public interface DictionaryFacilitator {
void waitForLoadingMainDictionaries(final long timeout, final TimeUnit unit)
throws InterruptedException;
@UsedForTesting
void waitForLoadingDictionariesForTesting(final long timeout, final TimeUnit unit)
throws InterruptedException;
void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized,
@NonNull final NgramContext ngramContext, final long timeStampInSeconds,
final boolean blockPotentiallyOffensive);

View file

@ -16,7 +16,6 @@ import android.util.LruCache;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.dslul.openboard.inputmethod.annotations.UsedForTesting;
import org.dslul.openboard.inputmethod.keyboard.Keyboard;
import org.dslul.openboard.inputmethod.latin.NgramContext.WordInfo;
import org.dslul.openboard.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
@ -53,7 +52,7 @@ import java.util.concurrent.TimeUnit;
* Facilitates interaction with different kinds of dictionaries. Provides APIs
* to instantiate and select the correct dictionaries (based on language or account),
* update entries and fetch suggestions.
*
* <p>
* Currently AndroidSpellCheckerService and LatinIME both use DictionaryFacilitator as
* a client for interacting with dictionaries.
*/
@ -451,10 +450,8 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
// Clean up old dictionaries.
for (final Locale localeToCleanUp : existingDictionariesToCleanup.keySet()) {
final ArrayList<String> dictTypesToCleanUp =
existingDictionariesToCleanup.get(localeToCleanUp);
final DictionaryGroup dictionarySetToCleanup =
findDictionaryGroupWithLocale(oldDictionaryGroups, localeToCleanUp);
final ArrayList<String> dictTypesToCleanUp = existingDictionariesToCleanup.get(localeToCleanUp);
final DictionaryGroup dictionarySetToCleanup = findDictionaryGroupWithLocale(oldDictionaryGroups, localeToCleanUp);
for (final String dictType : dictTypesToCleanUp) {
dictionarySetToCleanup.closeDict(dictType);
}
@ -517,36 +514,6 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
latchForWaitingLoadingMainDictionary.countDown();
}
@UsedForTesting
public void resetDictionariesForTesting(final Context context, final Locale locale,
final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles,
final Map<String, Map<String, String>> additionalDictAttributes,
@Nullable final String account) {
Dictionary mainDictionary = null;
final Map<String, ExpandableBinaryDictionary> subDicts = new HashMap<>();
for (final String dictType : dictionaryTypes) {
if (dictType.equals(Dictionary.TYPE_MAIN)) {
mainDictionary = DictionaryFactory.createMainDictionaryFromManager(context, locale);
} else {
final File dictFile = dictionaryFiles.get(dictType);
final ExpandableBinaryDictionary dict = getSubDict(
dictType, context, locale, dictFile, "", account);
if (dict == null) {
throw new RuntimeException("Unknown dictionary type: " + dictType);
}
if (additionalDictAttributes.containsKey(dictType)) {
dict.clearAndFlushDictionaryWithAdditionalAttributes(additionalDictAttributes.get(dictType));
}
dict.reloadDictionaryIfRequired();
dict.waitAllTasksForTests();
subDicts.put(dictType, dict);
}
}
mDictionaryGroups.clear();
mDictionaryGroups.add(new DictionaryGroup(locale, mainDictionary, account, subDicts));
}
public void closeDictionaries() {
final ArrayList<DictionaryGroup> dictionaryGroupsToClose;
synchronized (mLock) {
@ -561,11 +528,6 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
}
}
@UsedForTesting
public ExpandableBinaryDictionary getSubDictForTesting(final String dictName) {
return mDictionaryGroups.get(0).getSubDict(dictName);
}
// The main dictionaries are loaded asynchronously. Don't cache the return value
// of these methods.
public boolean hasAtLeastOneInitializedMainDictionary() {
@ -589,15 +551,6 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
mLatchForWaitingLoadingMainDictionaries.await(timeout, unit);
}
@UsedForTesting
public void waitForLoadingDictionariesForTesting(final long timeout, final TimeUnit unit)
throws InterruptedException {
waitForLoadingMainDictionaries(timeout, unit);
for (final ExpandableBinaryDictionary dict : mDictionaryGroups.get(0).mSubDictMap.values()) {
dict.waitAllTasksForTests();
}
}
public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized,
@NonNull final NgramContext ngramContext, final long timeStampInSeconds,
final boolean blockPotentiallyOffensive) {

View file

@ -26,7 +26,7 @@ import androidx.annotation.Nullable;
/**
* Enrichment class for InputMethodSubtype to enable concurrent multi-lingual input.
*
* <p>
* Right now, this returns the extra value of its primary subtype.
*/
// non final for easy mocking.
@ -208,7 +208,6 @@ public class RichInputMethodSubtype {
.setSubtypeId(SUBTYPE_ID_OF_DUMMY_EMOJI_SUBTYPE)
.build());
private static RichInputMethodSubtype sNoLanguageSubtype;
private static RichInputMethodSubtype sEmojiSubtype;
@NonNull
public static RichInputMethodSubtype getNoLanguageSubtype() {
@ -231,20 +230,6 @@ public class RichInputMethodSubtype {
@NonNull
public static RichInputMethodSubtype getEmojiSubtype() {
RichInputMethodSubtype emojiSubtype = sEmojiSubtype;
if (emojiSubtype == null) {
final InputMethodSubtype rawEmojiSubtype = RichInputMethodManager.getInstance()
.findSubtypeByLocaleAndKeyboardLayoutSet(SubtypeLocaleUtils.NO_LANGUAGE, SubtypeLocaleUtils.EMOJI);
if (rawEmojiSubtype != null) {
emojiSubtype = new RichInputMethodSubtype(rawEmojiSubtype);
}
}
if (emojiSubtype != null) {
sEmojiSubtype = emojiSubtype;
return emojiSubtype;
}
Log.w(TAG, "Can't find emoji subtype");
Log.w(TAG, "No input method subtype found; returning dummy subtype: " + DUMMY_EMOJI_SUBTYPE);
return DUMMY_EMOJI_SUBTYPE;
}
}

View file

@ -25,7 +25,6 @@ import org.dslul.openboard.inputmethod.latin.BuildConfig
import org.dslul.openboard.inputmethod.latin.R
import org.dslul.openboard.inputmethod.latin.SystemBroadcastReceiver
import org.dslul.openboard.inputmethod.latin.common.FileUtils
import org.dslul.openboard.inputmethod.latin.define.DebugFlags
import org.dslul.openboard.inputmethod.latin.define.JniLibName
import org.dslul.openboard.inputmethod.latin.settings.SeekBarDialogPreference.ValueProxy
import java.io.File
@ -49,7 +48,6 @@ import java.util.zip.ZipOutputStream
* - Debug settings
*/
class AdvancedSettingsFragment : SubScreenFragment() {
private val TAG = this::class.simpleName
private var libfile: File? = null
private val backupFilePatterns by lazy { listOf(
"blacklists/.*\\.txt".toRegex(),
@ -107,7 +105,7 @@ class AdvancedSettingsFragment : SubScreenFragment() {
val abi = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Build.SUPPORTED_ABIS[0]
} else {
Build.CPU_ABI
@Suppress("Deprecation") Build.CPU_ABI
}
// show delete / add dialog
val builder = AlertDialog.Builder(requireContext())
@ -305,3 +303,4 @@ class AdvancedSettingsFragment : SubScreenFragment() {
}
private const val PREFS_FILE_NAME = "preferences.json"
private const val TAG = "AdvancedSettingsFragment"

View file

@ -8,11 +8,6 @@ package org.dslul.openboard.inputmethod.latin.settings;
/**
* Debug settings for the application.
*
* Note: Even though these settings are stored in the default shared preferences file,
* they shouldn't be restored across devices.
* If a new key is added here, it should also be blacklisted for restore in
* {@link LocalSettingsConstants}.
*/
public final class DebugSettings {
public static final String PREF_DEBUG_MODE = "debug_mode";

View file

@ -606,7 +606,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
}
public static Context getDayNightContext(final Context context, final boolean wantNight) {
final boolean isNight = (context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
final boolean isNight = ResourceUtils.isNight(context.getResources());
if (isNight == wantNight)
return context;
final Configuration config = new Configuration(context.getResources().getConfiguration());

View file

@ -274,11 +274,13 @@ private fun removeEnabledSubtype(prefs: SharedPreferences, subtypeString: String
prefs.edit { putString(Settings.PREF_ENABLED_INPUT_STYLES, newString) }
if (subtypeString == prefs.getString(Settings.PREF_SELECTED_INPUT_STYLE, "")) {
// switch subtype if the currently used one has been disabled
val nextSubtype = RichInputMethodManager.getInstance().getNextSubtypeInThisIme(true)
if (subtypeString == nextSubtype?.prefString())
KeyboardSwitcher.getInstance().switchToSubtype(getDefaultEnabledSubtypes().first())
else
KeyboardSwitcher.getInstance().switchToSubtype(nextSubtype)
try {
val nextSubtype = RichInputMethodManager.getInstance().getNextSubtypeInThisIme(true)
if (subtypeString == nextSubtype?.prefString())
KeyboardSwitcher.getInstance().switchToSubtype(getDefaultEnabledSubtypes().first())
else
KeyboardSwitcher.getInstance().switchToSubtype(nextSubtype)
} catch (_: Exception) { } // do nothing if RichInputMethodManager isn't initialized
}
}

View file

@ -15,10 +15,12 @@ import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.dslul.openboard.inputmethod.latin.R;
import androidx.annotation.NonNull;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.core.view.ViewCompat;
public final class SetupStartIndicatorView extends LinearLayout {
@ -31,7 +33,7 @@ public final class SetupStartIndicatorView extends LinearLayout {
labelView.setIndicatorView(findViewById(R.id.setup_start_indicator));
}
public static final class LabelView extends TextView {
public static final class LabelView extends AppCompatTextView {
private View mIndicatorView;
public LabelView(final Context context, final AttributeSet attrs) {
@ -42,28 +44,12 @@ public final class SetupStartIndicatorView extends LinearLayout {
mIndicatorView = indicatorView;
}
// TODO: Once we stop supporting ICS, uncomment {@link #setPressed(boolean)} method and
// remove this method.
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
for (final int state : getDrawableState()) {
if (state == android.R.attr.state_pressed) {
updateIndicatorView(true /* pressed */);
return;
}
}
updateIndicatorView(false /* pressed */);
public void setPressed(final boolean pressed) {
super.setPressed(pressed);
updateIndicatorView(pressed);
}
// TODO: Once we stop supporting ICS, uncomment this method and remove
// {@link #drawableStateChanged()} method.
// @Override
// public void setPressed(final boolean pressed) {
// super.setPressed(pressed);
// updateIndicatorView(pressed);
// }
private void updateIndicatorView(final boolean pressed) {
if (mIndicatorView != null) {
mIndicatorView.setPressed(pressed);
@ -79,13 +65,12 @@ public final class SetupStartIndicatorView extends LinearLayout {
public IndicatorView(final Context context, final AttributeSet attrs) {
super(context, attrs);
mIndicatorColor = getResources().getColorStateList(
R.color.setup_step_action_background);
mIndicatorColor = AppCompatResources.getColorStateList(context, R.color.setup_step_action_background);
mIndicatorPaint.setStyle(Paint.Style.FILL);
}
@Override
protected void onDraw(final Canvas canvas) {
protected void onDraw(@NonNull final Canvas canvas) {
super.onDraw(canvas);
final int layoutDirection = ViewCompat.getLayoutDirection(this);
final int width = getWidth();

View file

@ -6,12 +6,10 @@
package org.dslul.openboard.inputmethod.latin.utils;
import android.content.ContentValues;
import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.text.TextUtils;
import org.dslul.openboard.inputmethod.latin.utils.Log;
import android.view.inputmethod.InputMethodSubtype;
import androidx.annotation.NonNull;
@ -36,7 +34,6 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
/**
* This class encapsulates the logic for the Latin-IME side of dictionary information management.
@ -86,7 +83,7 @@ public class DictionaryInfoUtils {
/**
* Returns whether we may want to use this character as part of a file name.
*
* <p>
* This basically only accepts ascii letters and numbers, and rejects everything else.
*/
private static boolean isFileNameCharacter(int codePoint) {
@ -98,7 +95,7 @@ public class DictionaryInfoUtils {
/**
* Escapes a string for any characters that may be suspicious for a file or directory name.
*
* <p>
* Concretely this does a sort of URL-encoding except it will encode everything that's not
* alphanumeric or underscore. (true URL-encoding leaves alone characters like '*', which
* we cannot allow here)
@ -114,8 +111,7 @@ public class DictionaryInfoUtils {
if (DictionaryInfoUtils.isFileNameCharacter(codePoint)) {
sb.appendCodePoint(codePoint);
} else {
sb.append(String.format((Locale)null, "%%%1$0" + MAX_HEX_DIGITS_FOR_CODEPOINT + "x",
codePoint));
sb.append(String.format(Locale.US, "%%%1$0" + MAX_HEX_DIGITS_FOR_CODEPOINT + "x", codePoint));
}
}
return sb.toString();
@ -155,8 +151,8 @@ public class DictionaryInfoUtils {
sb.appendCodePoint(codePoint);
} else {
// + 1 to pass the % sign
final int encodedCodePoint = Integer.parseInt(
fname.substring(i + 1, i + 1 + MAX_HEX_DIGITS_FOR_CODEPOINT), 16);
final int encodedCodePoint =
Integer.parseInt(fname.substring(i + 1, i + 1 + MAX_HEX_DIGITS_FOR_CODEPOINT), 16);
i += MAX_HEX_DIGITS_FOR_CODEPOINT;
sb.appendCodePoint(encodedCodePoint);
}
@ -177,7 +173,7 @@ public class DictionaryInfoUtils {
/**
* Returns the category for a given file name.
*
* <p>
* This parses the file name, extracts the category, and returns it. See
* {@link #getMainDictId(Locale)} and {@link #isMainWordListId(String)}.
* @return The category as a string or null if it can't be found in the file name.
@ -201,8 +197,7 @@ public class DictionaryInfoUtils {
*/
public static String getCacheDirectoryForLocale(final String locale, final Context context) {
final String relativeDirectoryName = replaceFileNameDangerousCharacters(locale).toLowerCase(Locale.ENGLISH);
final String absoluteDirectoryName = getWordListCacheDirectory(context) + File.separator
+ relativeDirectoryName;
final String absoluteDirectoryName = getWordListCacheDirectory(context) + File.separator + relativeDirectoryName;
final File directory = new File(absoluteDirectoryName);
if (!directory.exists()) {
if (!directory.mkdirs()) {
@ -248,8 +243,7 @@ public class DictionaryInfoUtils {
if (!locale.getCountry().isEmpty()) {
final String dictLanguageCountry = MAIN_DICT_PREFIX
+ locale.toString().toLowerCase(Locale.ROOT) + DECODER_DICT_SUFFIX;
if ((resId = res.getIdentifier(
dictLanguageCountry, "raw", RESOURCE_PACKAGE_NAME)) != 0) {
if ((resId = res.getIdentifier(dictLanguageCountry, "raw", RESOURCE_PACKAGE_NAME)) != 0) {
return resId;
}
}
@ -281,7 +275,7 @@ public class DictionaryInfoUtils {
/**
* Returns the id associated with the main word list for a specified locale.
*
* <p>
* Word lists stored in Android Keyboard's resources are referred to as the "main"
* word lists. Since they can be updated like any other list, we need to assign a
* unique ID to them. This ID is just the name of the language (locale-wise) they
@ -308,12 +302,8 @@ public class DictionaryInfoUtils {
public static DictionaryHeader getDictionaryFileHeaderOrNull(final File file,
final long offset, final long length) {
try {
final DictionaryHeader header =
BinaryDictionaryUtils.getHeaderWithOffsetAndLength(file, offset, length);
return header;
} catch (UnsupportedFormatException e) {
return null;
} catch (IOException e) {
return BinaryDictionaryUtils.getHeaderWithOffsetAndLength(file, offset, length);
} catch (UnsupportedFormatException | IOException e) {
return null;
}
}
@ -392,8 +382,7 @@ public class DictionaryInfoUtils {
dictList.add(newElement);
}
public static ArrayList<DictionaryInfo> getCurrentDictionaryFileNameAndVersionInfo(
final Context context) {
public static ArrayList<DictionaryInfo> getCurrentDictionaryFileNameAndVersionInfo(final Context context) {
final ArrayList<DictionaryInfo> dictList = new ArrayList<>();
// Retrieve downloaded dictionaries from cached directories
@ -410,8 +399,7 @@ public class DictionaryInfoUtils {
}
final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
final AssetFileAddress fileAddress = AssetFileAddress.makeFromFile(dict);
final DictionaryInfo dictionaryInfo =
createDictionaryInfoFromFileAddress(fileAddress, locale);
final DictionaryInfo dictionaryInfo = createDictionaryInfoFromFileAddress(fileAddress, locale);
// Protect against cases of a less-specific dictionary being found, like an
// en dictionary being used for an en_US locale. In this case, the en dictionary
// should be used for en_US but discounted for listing purposes.
@ -429,15 +417,12 @@ public class DictionaryInfoUtils {
for (final String localeString : assets.getLocales()) {
final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
final int resourceId =
DictionaryInfoUtils.getMainDictionaryResourceIdIfAvailableForLocale(
context.getResources(), locale);
DictionaryInfoUtils.getMainDictionaryResourceIdIfAvailableForLocale(context.getResources(), locale);
if (0 == resourceId) {
continue;
}
final AssetFileAddress fileAddress =
BinaryDictionaryGetter.loadFallbackResource(context, resourceId);
final DictionaryInfo dictionaryInfo = createDictionaryInfoFromFileAddress(fileAddress,
locale);
final AssetFileAddress fileAddress = BinaryDictionaryGetter.loadFallbackResource(context, resourceId);
final DictionaryInfo dictionaryInfo = createDictionaryInfoFromFileAddress(fileAddress, locale);
// Protect against cases of a less-specific dictionary being found, like an
// en dictionary being used for an en_US locale. In this case, the en dictionary
// should be used for en_US but discounted for listing purposes.

View file

@ -112,9 +112,9 @@ fun reorderMoreKeysDialog(context: Context, key: String, defaultSetting: String,
override fun areItemsTheSame(p0: Pair<String, Boolean>, p1: Pair<String, Boolean>) = p0 == p1
override fun areContentsTheSame(p0: Pair<String, Boolean>, p1: Pair<String, Boolean>) = p0 == p1
}
val bgColor = if (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_NO)
ContextCompat.getColor(context, androidx.appcompat.R.color.background_floating_material_light)
else ContextCompat.getColor(context, androidx.appcompat.R.color.background_floating_material_dark)
val bgColor = if (ResourceUtils.isNight(context.resources))
ContextCompat.getColor(context, androidx.appcompat.R.color.background_floating_material_dark)
else ContextCompat.getColor(context, androidx.appcompat.R.color.background_floating_material_light)
val adapter = object : ListAdapter<Pair<String, Boolean>, RecyclerView.ViewHolder>(callback) {
override fun onCreateViewHolder(p0: ViewGroup, p1: Int): RecyclerView.ViewHolder {
val b = LayoutInflater.from(context).inflate(R.layout.morekeys_list_item, rv, false)

View file

@ -12,7 +12,6 @@ import android.content.res.TypedArray;
import android.os.Build;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import org.dslul.openboard.inputmethod.latin.utils.Log;
import android.util.TypedValue;
import org.dslul.openboard.inputmethod.annotations.UsedForTesting;
@ -82,7 +81,6 @@ public final class ResourceUtils {
return defaultValue;
}
@SuppressWarnings("serial")
static class DeviceOverridePatternSyntaxError extends Exception {
public DeviceOverridePatternSyntaxError(final String message, final String expression) {
this(message, expression, null);
@ -100,7 +98,7 @@ public final class ResourceUtils {
* "pattern1[:pattern2...] (or an empty string for the default). A pattern is
* "key=regexp_value" string. The condition matches only if all patterns of the condition
* are true for the specified key value pairs.
*
* <p>
* For example, "condition,constant" has the following format.
* - HARDWARE=mako,constantForNexus4
* - MODEL=Nexus 4:MANUFACTURER=LGE,constantForNexus4
@ -110,7 +108,6 @@ public final class ResourceUtils {
* @param conditionConstantArray an array of "condition,constant" elements to be searched.
* @return the constant part of the matched "condition,constant" element. Returns null if no
* condition matches.
* @see org.dslul.openboard.inputmethod.latin.utils.ResourceUtilsTests#testFindConstantForKeyValuePairsRegexp()
*/
@UsedForTesting
static String findConstantForKeyValuePairs(final HashMap<String, String> keyValuePairs,
@ -219,15 +216,6 @@ public final class ResourceUtils {
return dimension > 0;
}
// {@link Resources#getDimensionPixelOffset(int)} may return zero pixel offset.
public static boolean isValidDimensionPixelOffset(final int dimension) {
return dimension >= 0;
}
public static float getFloatFromFraction(final Resources res, final int fractionResId) {
return res.getFraction(fractionResId, 1, 1);
}
public static float getFraction(final TypedArray a, final int index, final float defValue) {
final TypedValue value = a.peekValue(index);
if (value == null || !isFractionValue(value)) {
@ -262,17 +250,6 @@ public final class ResourceUtils {
return defValue;
}
public static int getEnumValue(final TypedArray a, final int index, final int defValue) {
final TypedValue value = a.peekValue(index);
if (value == null) {
return defValue;
}
if (isIntegerValue(value)) {
return a.getInt(index, defValue);
}
return defValue;
}
public static boolean isFractionValue(final TypedValue v) {
return v.type == TypedValue.TYPE_FRACTION;
}
@ -281,16 +258,7 @@ public final class ResourceUtils {
return v.type == TypedValue.TYPE_DIMENSION;
}
public static boolean isIntegerValue(final TypedValue v) {
return v.type >= TypedValue.TYPE_FIRST_INT && v.type <= TypedValue.TYPE_LAST_INT;
}
public static boolean isStringValue(final TypedValue v) {
return v.type == TypedValue.TYPE_STRING;
}
public static boolean isNight(final Resources res) {
// todo: night mode can be unspecified -> maybe need to adjust for correct behavior on some devices?
return (res.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
}
}