diff --git a/app/build.gradle b/app/build.gradle index d4855caa8..1df406d0d 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -90,14 +90,22 @@ android { } dependencies { - implementation 'androidx.core:core-ktx:1.12.0' + // androidx + implementation 'androidx.core:core-ktx:1.13.1' implementation 'androidx.preference:preference:1.2.1' implementation 'androidx.recyclerview:recyclerview:1.3.2' - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3" - implementation 'com.github.martin-stone:hsv-alpha-color-picker-android:3.1.0' implementation 'androidx.autofill:autofill:1.1.0' + // kotlin + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3" + // when kotlin-serialization is enabled, Android Studio stops complaining about "Unresolved reference: serializer", but the build fails +// implementation "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" + + // color picker for user-defined colors + implementation 'com.github.martin-stone:hsv-alpha-color-picker-android:3.1.0' + + // test testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-core:5.11.0' testImplementation 'org.mockito:mockito-inline:5.2.0' diff --git a/app/src/main/java/helium314/keyboard/accessibility/AccessibilityUtils.kt b/app/src/main/java/helium314/keyboard/accessibility/AccessibilityUtils.kt index b5d7adb15..dafbfb2bf 100644 --- a/app/src/main/java/helium314/keyboard/accessibility/AccessibilityUtils.kt +++ b/app/src/main/java/helium314/keyboard/accessibility/AccessibilityUtils.kt @@ -7,7 +7,6 @@ package helium314.keyboard.accessibility import android.content.Context -import android.media.AudioDeviceInfo import android.media.AudioDeviceInfo.* import android.media.AudioManager import android.os.Build diff --git a/app/src/main/java/helium314/keyboard/accessibility/KeyboardAccessibilityDelegate.kt b/app/src/main/java/helium314/keyboard/accessibility/KeyboardAccessibilityDelegate.kt index 74c96e923..17edf65d1 100644 --- a/app/src/main/java/helium314/keyboard/accessibility/KeyboardAccessibilityDelegate.kt +++ b/app/src/main/java/helium314/keyboard/accessibility/KeyboardAccessibilityDelegate.kt @@ -47,10 +47,9 @@ open class KeyboardAccessibilityDelegate( /** * Called when the keyboard layout changes. * - * * **Note:** This method will be called even if accessibility is not * enabled. - * @param keyboard The keyboard that is being set to the wrapping view. + * [keyboard]: The keyboard that is being set to the wrapping view. */ open var keyboard: Keyboard? get() = mKeyboard diff --git a/app/src/main/java/helium314/keyboard/accessibility/MainKeyboardAccessibilityDelegate.kt b/app/src/main/java/helium314/keyboard/accessibility/MainKeyboardAccessibilityDelegate.kt index d81bd4ecf..0be99c7c0 100644 --- a/app/src/main/java/helium314/keyboard/accessibility/MainKeyboardAccessibilityDelegate.kt +++ b/app/src/main/java/helium314/keyboard/accessibility/MainKeyboardAccessibilityDelegate.kt @@ -116,8 +116,7 @@ class MainKeyboardAccessibilityDelegate( */ private fun announceKeyboardType(keyboard: Keyboard, lastKeyboard: Keyboard) { val lastElementId = lastKeyboard.mId.mElementId - val resId: Int - resId = when (keyboard.mId.mElementId) { + val resId = when (keyboard.mId.mElementId) { KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED, KeyboardId.ELEMENT_ALPHABET -> { if (lastElementId == KeyboardId.ELEMENT_ALPHABET || lastElementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) { diff --git a/app/src/main/java/helium314/keyboard/event/CombinerChain.kt b/app/src/main/java/helium314/keyboard/event/CombinerChain.kt index 7862f9ee2..4aa1a1fde 100644 --- a/app/src/main/java/helium314/keyboard/event/CombinerChain.kt +++ b/app/src/main/java/helium314/keyboard/event/CombinerChain.kt @@ -9,7 +9,6 @@ package helium314.keyboard.event import android.text.SpannableStringBuilder import android.text.TextUtils import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode -import helium314.keyboard.latin.common.Constants import java.util.* /** @@ -23,6 +22,12 @@ import java.util.* * finished combining part, will be shown normally as the composing string, while the second is * feedback on the composing state and will typically be shown with different styling such as * a colored background. + * + * The combiner chain takes events as inputs and outputs code points and combining state. + * For example, if the input language is Japanese, the combining chain will typically perform + * kana conversion. This takes a string for initial text, taken to be present before the + * cursor: we'll start after this. + * @param initialText The text that has already been combined so far. */ class CombinerChain(initialText: String) { // The already combined text, as described above @@ -45,16 +50,6 @@ class CombinerChain(initialText: String) { mCombiners.add(HangulCombiner()) } - /** - * Create an combiner chain. - * - * The combiner chain takes events as inputs and outputs code points and combining state. - * For example, if the input language is Japanese, the combining chain will typically perform - * kana conversion. This takes a string for initial text, taken to be present before the - * cursor: we'll start after this. - * - * @param initialText The text that has already been combined so far. - */ init { // The dead key combiner is always active, and always first mCombiners.add(DeadKeyCombiner()) diff --git a/app/src/main/java/helium314/keyboard/event/InputTransaction.kt b/app/src/main/java/helium314/keyboard/event/InputTransaction.kt index c753a739f..b7dbd26dc 100644 --- a/app/src/main/java/helium314/keyboard/event/InputTransaction.kt +++ b/app/src/main/java/helium314/keyboard/event/InputTransaction.kt @@ -28,7 +28,7 @@ class InputTransaction(// Initial conditions * @param updateType What type of shift update this requires. */ fun requireShiftUpdate(updateType: Int) { - requiredShiftUpdate = Math.max(requiredShiftUpdate, updateType) + requiredShiftUpdate = requiredShiftUpdate.coerceAtLeast(updateType) } /** diff --git a/app/src/main/java/helium314/keyboard/keyboard/Key.java b/app/src/main/java/helium314/keyboard/keyboard/Key.java index 231dd05ad..7368b27bc 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/Key.java +++ b/app/src/main/java/helium314/keyboard/keyboard/Key.java @@ -191,7 +191,7 @@ public class Key implements Comparable { /** * Constructor for a key on PopupKeyKeyboard and on MoreSuggestions. */ - public Key(@Nullable final String label, final String iconName, final int code, + public Key(@Nullable final String label, @NonNull final String iconName, final int code, @Nullable final String outputText, @Nullable final String hintLabel, final int labelFlags, final int backgroundType, final int x, final int y, final int width, final int height, final int horizontalGap, final int verticalGap) { @@ -404,7 +404,7 @@ public class Key implements Comparable { && o.mCode == mCode && TextUtils.equals(o.mLabel, mLabel) && TextUtils.equals(o.mHintLabel, mHintLabel) - && o.mIconName == mIconName + && o.mIconName.equals(mIconName) && o.mBackgroundType == mBackgroundType && Arrays.equals(o.mPopupKeys, mPopupKeys) && TextUtils.equals(o.getOutputText(), getOutputText()) @@ -429,6 +429,7 @@ public class Key implements Comparable { return o instanceof Key && equalsInternal((Key)o); } + @NonNull @Override public String toString() { return toShortString() + " " + getX() + "," + getY() + " " + getWidth() + "x" + getHeight(); @@ -654,7 +655,7 @@ public class Key implements Comparable { return (mLabelFlags & LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0; } - private final boolean isShiftedLetterActivated() { + private boolean isShiftedLetterActivated() { return (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) != 0 && !TextUtils.isEmpty(mHintLabel); } diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListener.java b/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListener.java index cd1763e11..0e3c6c5cb 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListener.java +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListener.java @@ -35,11 +35,11 @@ public interface KeyboardActionListener { * Send a key code to the listener. * * @param primaryCode this is the code of the key that was pressed - * @param x x-coordinate pixel of touched event. If {@link #onCodeInput} is not called by + * @param x x-coordinate pixel of touched event. If onCodeInput is not called by * {@link PointerTracker} or so, the value should be * {@link Constants#NOT_A_COORDINATE}. If it's called on insertion from the * suggestion strip, it should be {@link Constants#SUGGESTION_STRIP_COORDINATE}. - * @param y y-coordinate pixel of touched event. If {@link #onCodeInput} is not called by + * @param y y-coordinate pixel of touched event. If #onCodeInput is not called by * {@link PointerTracker} or so, the value should be * {@link Constants#NOT_A_COORDINATE}.If it's called on insertion from the * suggestion strip, it should be {@link Constants#SUGGESTION_STRIP_COORDINATE}. @@ -103,9 +103,9 @@ public interface KeyboardActionListener { KeyboardActionListener EMPTY_LISTENER = new Adapter(); - static int SWIPE_NO_ACTION = 0; - static int SWIPE_MOVE_CURSOR = 1; - static int SWIPE_SWITCH_LANGUAGE = 2; + int SWIPE_NO_ACTION = 0; + int SWIPE_MOVE_CURSOR = 1; + int SWIPE_SWITCH_LANGUAGE = 2; class Adapter implements KeyboardActionListener { @Override diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListenerImpl.kt b/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListenerImpl.kt index c878a26b0..30c047dbe 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListenerImpl.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListenerImpl.kt @@ -97,9 +97,9 @@ class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inp return true } - private fun onMoveCursorHorizontally(_steps: Int): Boolean { - if (_steps == 0) return false - var steps = _steps + private fun onMoveCursorHorizontally(rawSteps: Int): Boolean { + if (rawSteps == 0) return false + var steps = rawSteps // for RTL languages we want to invert pointer movement if (RichInputMethodManager.getInstance().currentSubtype.isRtlSubtype) steps = -steps val moveSteps: Int diff --git a/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt b/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt index 2f169242c..6624fb26d 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt @@ -32,6 +32,7 @@ import helium314.keyboard.latin.utils.getCodeForToolbarKey import helium314.keyboard.latin.utils.getCodeForToolbarKeyLongClick import helium314.keyboard.latin.utils.getEnabledClipboardToolbarKeys +@SuppressLint("CustomViewStyleable") class ClipboardHistoryView @JvmOverloads constructor( context: Context, attrs: AttributeSet?, @@ -160,7 +161,7 @@ class ClipboardHistoryView @JvmOverloads constructor( private fun setupToolbarKeys() { // set layout params - val toolbarKeyLayoutParams = LayoutParams(getResources().getDimensionPixelSize(R.dimen.config_suggestions_strip_edge_key_width), LayoutParams.MATCH_PARENT) + val toolbarKeyLayoutParams = LayoutParams(resources.getDimensionPixelSize(R.dimen.config_suggestions_strip_edge_key_width), LayoutParams.MATCH_PARENT) toolbarKeys.forEach { it.layoutParams = toolbarKeyLayoutParams } } diff --git a/app/src/main/java/helium314/keyboard/keyboard/emoji/DynamicGridKeyboard.java b/app/src/main/java/helium314/keyboard/keyboard/emoji/DynamicGridKeyboard.java index e51168b8f..39c3f0d65 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/emoji/DynamicGridKeyboard.java +++ b/app/src/main/java/helium314/keyboard/keyboard/emoji/DynamicGridKeyboard.java @@ -236,8 +236,7 @@ final class DynamicGridKeyboard extends Keyboard { if (o instanceof Integer) { final int code = (Integer)o; key = getKeyByCode(keyboards, code); - } else if (o instanceof String) { - final String outputText = (String)o; + } else if (o instanceof final String outputText) { key = getKeyByOutputText(keyboards, outputText); } else { Log.w(TAG, "Invalid object: " + o); @@ -267,18 +266,20 @@ final class DynamicGridKeyboard extends Keyboard { return row * mVerticalStep + mVerticalGap / 2; } + @NonNull @Override public List getSortedKeys() { synchronized (mLock) { if (mCachedGridKeys != null) { return mCachedGridKeys; } - final ArrayList cachedKeys = new ArrayList(mGridKeys); + final ArrayList cachedKeys = new ArrayList<>(mGridKeys); mCachedGridKeys = Collections.unmodifiableList(cachedKeys); return mCachedGridKeys; } } + @NonNull @Override public List getNearestKeys(final int x, final int y) { // TODO: Calculate the nearest key index in mGridKeys from x and y. @@ -312,13 +313,13 @@ final class DynamicGridKeyboard extends Keyboard { @Override public boolean equals(final Object o) { - if (!(o instanceof Key)) return false; - final Key key = (Key)o; + if (!(o instanceof final Key key)) return false; if (getCode() != key.getCode()) return false; if (!TextUtils.equals(getLabel(), key.getLabel())) return false; return TextUtils.equals(getOutputText(), key.getOutputText()); } + @NonNull @Override public String toString() { return "GridKey: " + super.toString(); diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/RawKeyboardParser.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/RawKeyboardParser.kt index 3053c488d..f108a5666 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/RawKeyboardParser.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/RawKeyboardParser.kt @@ -121,6 +121,7 @@ object RawKeyboardParser { else -> params.mId.mSubtype.keyboardLayoutSetName.substringBeforeLast("+") } + // todo (later, see also keyboardParser): use Settings.getInstance().current.mSingleFunctionalLayout private fun getFunctionalLayoutName(params: KeyboardParams) = when (params.mId.mElementId) { KeyboardId.ELEMENT_SYMBOLS_SHIFTED -> FUNCTIONAL_LAYOUT_SYMBOLS_SHIFTED KeyboardId.ELEMENT_SYMBOLS -> FUNCTIONAL_LAYOUT_SYMBOLS diff --git a/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java b/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java index 873d080f0..0fcb4f340 100644 --- a/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java +++ b/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java @@ -18,7 +18,7 @@ import helium314.keyboard.latin.settings.SettingsValues; /** * This class gathers audio feedback and haptic feedback functions. - * + *

* It offers a consistent and simple interface that allows LatinIME to forget about the * complexity of settings and the like. */ @@ -81,21 +81,12 @@ public final class AudioAndHapticFeedbackManager { if (!mSoundOn) { return; } - final int sound; - switch (code) { - case KeyCode.DELETE: - sound = AudioManager.FX_KEYPRESS_DELETE; - break; - case Constants.CODE_ENTER: - sound = AudioManager.FX_KEYPRESS_RETURN; - break; - case Constants.CODE_SPACE: - sound = AudioManager.FX_KEYPRESS_SPACEBAR; - break; - default: - sound = AudioManager.FX_KEYPRESS_STANDARD; - break; - } + final int sound = switch (code) { + case KeyCode.DELETE -> AudioManager.FX_KEYPRESS_DELETE; + case Constants.CODE_ENTER -> AudioManager.FX_KEYPRESS_RETURN; + case Constants.CODE_SPACE -> AudioManager.FX_KEYPRESS_SPACEBAR; + default -> AudioManager.FX_KEYPRESS_STANDARD; + }; mAudioManager.playSoundEffect(sound, mSettingsValues.mKeypressSoundVolume); } diff --git a/app/src/main/java/helium314/keyboard/latin/ContactsManager.java b/app/src/main/java/helium314/keyboard/latin/ContactsManager.java index 877bcdf50..bb171a2a1 100644 --- a/app/src/main/java/helium314/keyboard/latin/ContactsManager.java +++ b/app/src/main/java/helium314/keyboard/latin/ContactsManager.java @@ -25,7 +25,7 @@ import java.util.concurrent.atomic.AtomicInteger; /** * Manages all interactions with Contacts DB. - * + *

* The manager provides an API for listening to meaning full updates by keeping a * measure of the current state of the content provider. */ @@ -65,7 +65,7 @@ public class ContactsManager { * - How many times it has been contacted * - How long since the last contact. * - Whether the contact is in the visible group (i.e., Contacts list). - * + *

* Note: This affinity is limited by the fact that some apps currently do not update the * LAST_TIME_CONTACTED or TIMES_CONTACTED counters. As a result, a frequently messaged * contact may still have 0 affinity. @@ -101,13 +101,13 @@ public class ContactsManager { * The number of contacts observed in the most recent instance of * contacts content provider. */ - private AtomicInteger mContactCountAtLastRebuild = new AtomicInteger(0); + private final AtomicInteger mContactCountAtLastRebuild = new AtomicInteger(0); /** * The hash code of list of valid contacts names in the most recent dictionary * rebuild. */ - private AtomicInteger mHashCodeAtLastRebuild = new AtomicInteger(0); + private final AtomicInteger mHashCodeAtLastRebuild = new AtomicInteger(0); private final Context mContext; private final ContactsContentObserver mObserver; @@ -134,7 +134,7 @@ public class ContactsManager { * Returns all the valid names in the Contacts DB. Callers should also * call {@link #updateLocalState(ArrayList)} after they are done with result * so that the manager can cache local state for determining updates. - * + *

* These names are sorted by their affinity to the user, with favorite * contacts appearing first. */ @@ -183,22 +183,15 @@ public class ContactsManager { * Returns the number of contacts in contacts content provider. */ public int getContactCount() { - // TODO: consider switching to a rawQuery("select count(*)...") on the database if - // performance is a bottleneck. - Cursor cursor = null; - try { - cursor = mContext.getContentResolver().query(Contacts.CONTENT_URI, - ContactsDictionaryConstants.PROJECTION_ID_ONLY, null, null, null); - if (null == cursor) { + // TODO: consider switching to a rawQuery("select count(*)...") on the database if performance is a bottleneck. + try (Cursor cursor = mContext.getContentResolver().query(Contacts.CONTENT_URI, + ContactsDictionaryConstants.PROJECTION_ID_ONLY, null, null, null) + ) { + if (null == cursor) return 0; - } return cursor.getCount(); } catch (final SQLiteException e) { Log.e(TAG, "SQLiteException in the remote Contacts process.", e); - } finally { - if (null != cursor) { - cursor.close(); - } } return 0; } diff --git a/app/src/main/java/helium314/keyboard/latin/InputAttributes.java b/app/src/main/java/helium314/keyboard/latin/InputAttributes.java index c57fec006..92c75991b 100644 --- a/app/src/main/java/helium314/keyboard/latin/InputAttributes.java +++ b/app/src/main/java/helium314/keyboard/latin/InputAttributes.java @@ -20,6 +20,8 @@ import java.util.Arrays; import static helium314.keyboard.latin.common.Constants.ImeOption.NO_FLOATING_GESTURE_PREVIEW; import static helium314.keyboard.latin.common.Constants.ImeOption.NO_MICROPHONE; +import androidx.annotation.NonNull; + /** * Class to hold attributes of the input field. */ @@ -162,92 +164,60 @@ public final class InputAttributes { } private static String toInputClassString(final int inputClass) { - switch (inputClass) { - case InputType.TYPE_CLASS_TEXT: - return "TYPE_CLASS_TEXT"; - case InputType.TYPE_CLASS_PHONE: - return "TYPE_CLASS_PHONE"; - case InputType.TYPE_CLASS_NUMBER: - return "TYPE_CLASS_NUMBER"; - case InputType.TYPE_CLASS_DATETIME: - return "TYPE_CLASS_DATETIME"; - default: - return String.format("unknownInputClass<0x%08x>", inputClass); - } + return switch (inputClass) { + case InputType.TYPE_CLASS_TEXT -> "TYPE_CLASS_TEXT"; + case InputType.TYPE_CLASS_PHONE -> "TYPE_CLASS_PHONE"; + case InputType.TYPE_CLASS_NUMBER -> "TYPE_CLASS_NUMBER"; + case InputType.TYPE_CLASS_DATETIME -> "TYPE_CLASS_DATETIME"; + default -> String.format("unknownInputClass<0x%08x>", inputClass); + }; } private static String toVariationString(final int inputClass, final int variation) { - switch (inputClass) { - case InputType.TYPE_CLASS_TEXT: - return toTextVariationString(variation); - case InputType.TYPE_CLASS_NUMBER: - return toNumberVariationString(variation); - case InputType.TYPE_CLASS_DATETIME: - return toDatetimeVariationString(variation); - default: - return ""; - } + return switch (inputClass) { + case InputType.TYPE_CLASS_TEXT -> toTextVariationString(variation); + case InputType.TYPE_CLASS_NUMBER -> toNumberVariationString(variation); + case InputType.TYPE_CLASS_DATETIME -> toDatetimeVariationString(variation); + default -> ""; + }; } private static String toTextVariationString(final int variation) { - switch (variation) { - case InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS: - return " TYPE_TEXT_VARIATION_EMAIL_ADDRESS"; - case InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT: - return "TYPE_TEXT_VARIATION_EMAIL_SUBJECT"; - case InputType.TYPE_TEXT_VARIATION_FILTER: - return "TYPE_TEXT_VARIATION_FILTER"; - case InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE: - return "TYPE_TEXT_VARIATION_LONG_MESSAGE"; - case InputType.TYPE_TEXT_VARIATION_NORMAL: - return "TYPE_TEXT_VARIATION_NORMAL"; - case InputType.TYPE_TEXT_VARIATION_PASSWORD: - return "TYPE_TEXT_VARIATION_PASSWORD"; - case InputType.TYPE_TEXT_VARIATION_PERSON_NAME: - return "TYPE_TEXT_VARIATION_PERSON_NAME"; - case InputType.TYPE_TEXT_VARIATION_PHONETIC: - return "TYPE_TEXT_VARIATION_PHONETIC"; - case InputType.TYPE_TEXT_VARIATION_POSTAL_ADDRESS: - return "TYPE_TEXT_VARIATION_POSTAL_ADDRESS"; - case InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE: - return "TYPE_TEXT_VARIATION_SHORT_MESSAGE"; - case InputType.TYPE_TEXT_VARIATION_URI: - return "TYPE_TEXT_VARIATION_URI"; - case InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD: - return "TYPE_TEXT_VARIATION_VISIBLE_PASSWORD"; - case InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT: - return "TYPE_TEXT_VARIATION_WEB_EDIT_TEXT"; - case InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS: - return "TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS"; - case InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD: - return "TYPE_TEXT_VARIATION_WEB_PASSWORD"; - default: - return String.format("unknownVariation<0x%08x>", variation); - } + return switch (variation) { + case InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS -> " TYPE_TEXT_VARIATION_EMAIL_ADDRESS"; + case InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT -> "TYPE_TEXT_VARIATION_EMAIL_SUBJECT"; + case InputType.TYPE_TEXT_VARIATION_FILTER -> "TYPE_TEXT_VARIATION_FILTER"; + case InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE -> "TYPE_TEXT_VARIATION_LONG_MESSAGE"; + case InputType.TYPE_TEXT_VARIATION_NORMAL -> "TYPE_TEXT_VARIATION_NORMAL"; + case InputType.TYPE_TEXT_VARIATION_PASSWORD -> "TYPE_TEXT_VARIATION_PASSWORD"; + case InputType.TYPE_TEXT_VARIATION_PERSON_NAME -> "TYPE_TEXT_VARIATION_PERSON_NAME"; + case InputType.TYPE_TEXT_VARIATION_PHONETIC -> "TYPE_TEXT_VARIATION_PHONETIC"; + case InputType.TYPE_TEXT_VARIATION_POSTAL_ADDRESS -> "TYPE_TEXT_VARIATION_POSTAL_ADDRESS"; + case InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE -> "TYPE_TEXT_VARIATION_SHORT_MESSAGE"; + case InputType.TYPE_TEXT_VARIATION_URI -> "TYPE_TEXT_VARIATION_URI"; + case InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD -> "TYPE_TEXT_VARIATION_VISIBLE_PASSWORD"; + case InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT -> "TYPE_TEXT_VARIATION_WEB_EDIT_TEXT"; + case InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS -> "TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS"; + case InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD -> "TYPE_TEXT_VARIATION_WEB_PASSWORD"; + default -> String.format("unknownVariation<0x%08x>", variation); + }; } private static String toNumberVariationString(final int variation) { - switch (variation) { - case InputType.TYPE_NUMBER_VARIATION_NORMAL: - return "TYPE_NUMBER_VARIATION_NORMAL"; - case InputType.TYPE_NUMBER_VARIATION_PASSWORD: - return "TYPE_NUMBER_VARIATION_PASSWORD"; - default: - return String.format("unknownVariation<0x%08x>", variation); - } + return switch (variation) { + case InputType.TYPE_NUMBER_VARIATION_NORMAL -> "TYPE_NUMBER_VARIATION_NORMAL"; + case InputType.TYPE_NUMBER_VARIATION_PASSWORD -> "TYPE_NUMBER_VARIATION_PASSWORD"; + default -> String.format("unknownVariation<0x%08x>", variation); + }; } private static String toDatetimeVariationString(final int variation) { - switch (variation) { - case InputType.TYPE_DATETIME_VARIATION_NORMAL: - return "TYPE_DATETIME_VARIATION_NORMAL"; - case InputType.TYPE_DATETIME_VARIATION_DATE: - return "TYPE_DATETIME_VARIATION_DATE"; - case InputType.TYPE_DATETIME_VARIATION_TIME: - return "TYPE_DATETIME_VARIATION_TIME"; - default: - return String.format("unknownVariation<0x%08x>", variation); - } + return switch (variation) { + case InputType.TYPE_DATETIME_VARIATION_NORMAL -> "TYPE_DATETIME_VARIATION_NORMAL"; + case InputType.TYPE_DATETIME_VARIATION_DATE -> "TYPE_DATETIME_VARIATION_DATE"; + case InputType.TYPE_DATETIME_VARIATION_TIME -> "TYPE_DATETIME_VARIATION_TIME"; + default -> String.format("unknownVariation<0x%08x>", variation); + }; } private static String toFlagsString(final int flags) { @@ -272,6 +242,7 @@ public final class InputAttributes { } // Pretty print + @NonNull @Override public String toString() { return String.format( diff --git a/app/src/main/java/helium314/keyboard/latin/LatinIME.java b/app/src/main/java/helium314/keyboard/latin/LatinIME.java index 4a845a125..0e9bf6e26 100644 --- a/app/src/main/java/helium314/keyboard/latin/LatinIME.java +++ b/app/src/main/java/helium314/keyboard/latin/LatinIME.java @@ -6,6 +6,7 @@ package helium314.keyboard.latin; +import android.annotation.SuppressLint; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -783,6 +784,7 @@ public class LatinIME extends InputMethodService implements * Starts from {@link android.os.Build.VERSION_CODES#S_V2}, the returning context object has * became to IME context self since it ends up capable of updating its resources internally. */ + @SuppressWarnings("deprecation") private @NonNull Context getDisplayContext() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S_V2) { // IME context sources is now managed by WindowProviderService from Android 12L. @@ -1104,10 +1106,6 @@ public class LatinIME extends InputMethodService implements } } - public CharSequence getSelection() { - return mInputLogic.mConnection.getSelectedText(0); - } - /** * This is called when the user has clicked on the extracted text view, * when running in fullscreen mode. The default implementation hides @@ -1667,14 +1665,11 @@ public class LatinIME extends InputMethodService implements */ private void updateStateAfterInputTransaction(final InputTransaction inputTransaction) { switch (inputTransaction.getRequiredShiftUpdate()) { - case InputTransaction.SHIFT_UPDATE_LATER: - mHandler.postUpdateShiftState(); - break; - case InputTransaction.SHIFT_UPDATE_NOW: - mKeyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(), - getCurrentRecapitalizeState()); - break; - default: // SHIFT_NO_UPDATE + case InputTransaction.SHIFT_UPDATE_LATER -> mHandler.postUpdateShiftState(); + case InputTransaction.SHIFT_UPDATE_NOW -> mKeyboardSwitcher + .requestUpdatingShiftState(getCurrentAutoCapsState(), getCurrentRecapitalizeState()); + default -> { + } // SHIFT_NO_UPDATE } if (inputTransaction.requiresUpdateSuggestions()) { final int inputStyle; @@ -1897,6 +1892,7 @@ public class LatinIME extends InputMethodService implements } } + @SuppressLint("SwitchIntDef") @Override public void onTrimMemory(int level) { super.onTrimMemory(level); diff --git a/app/src/main/java/helium314/keyboard/latin/PunctuationSuggestions.java b/app/src/main/java/helium314/keyboard/latin/PunctuationSuggestions.java index 241af9a5e..6f6e75413 100644 --- a/app/src/main/java/helium314/keyboard/latin/PunctuationSuggestions.java +++ b/app/src/main/java/helium314/keyboard/latin/PunctuationSuggestions.java @@ -6,11 +6,11 @@ package helium314.keyboard.latin; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import helium314.keyboard.keyboard.internal.KeySpecParser; import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode; -import helium314.keyboard.latin.common.Constants; import helium314.keyboard.latin.common.StringUtils; import java.util.ArrayList; @@ -18,7 +18,7 @@ import java.util.Arrays; /** * The extended {@link SuggestedWords} class to represent punctuation suggestions. - * + *

* Each punctuation specification string is the key specification that can be parsed by * {@link KeySpecParser}. */ @@ -44,7 +44,7 @@ public final class PunctuationSuggestions extends SuggestedWords { public static PunctuationSuggestions newPunctuationSuggestions( @Nullable final String[] punctuationSpecs) { if (punctuationSpecs == null || punctuationSpecs.length == 0) { - return new PunctuationSuggestions(new ArrayList(0)); + return new PunctuationSuggestions(new ArrayList<>(0)); } final ArrayList punctuationList = new ArrayList<>(punctuationSpecs.length); @@ -99,7 +99,7 @@ public final class PunctuationSuggestions extends SuggestedWords { } @Override - public String toString() { + @NonNull public String toString() { return "PunctuationSuggestions: " + " words=" + Arrays.toString(mSuggestedWordInfoList.toArray()); } diff --git a/app/src/main/java/helium314/keyboard/latin/WordComposer.java b/app/src/main/java/helium314/keyboard/latin/WordComposer.java index 343dc6d8e..d67f50d7e 100644 --- a/app/src/main/java/helium314/keyboard/latin/WordComposer.java +++ b/app/src/main/java/helium314/keyboard/latin/WordComposer.java @@ -15,7 +15,6 @@ import helium314.keyboard.keyboard.KeyboardSwitcher; import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode; import helium314.keyboard.latin.SuggestedWords.SuggestedWordInfo; import helium314.keyboard.latin.common.ComposedData; -import helium314.keyboard.latin.common.Constants; import helium314.keyboard.latin.common.CoordinateUtils; import helium314.keyboard.latin.common.InputPointers; import helium314.keyboard.latin.common.StringUtils; @@ -167,7 +166,7 @@ public final class WordComposer { /** * Apply a processed input event. - * + *

* All input events should be supported, including software/hardware events, characters as well * as deletions, multiple inputs and gestures. * @@ -320,7 +319,7 @@ public final class WordComposer { /** * Whether this composer is composing or about to compose a word in which only the first letter * is a capital. - * + *

* If we do have a composing word, we just return whether the word has indeed only its first * character capitalized. If we don't, then we return a value based on the capitalized mode, * which tell us what is likely to happen for the next composing word. @@ -370,7 +369,7 @@ public final class WordComposer { /** * Saves the caps mode at the start of composing. - * + *

* WordComposer needs to know about the caps mode for several reasons. The first is, we need * to know after the fact what the reason was, to register the correct form into the user * history dictionary: if the word was automatically capitalized, we should insert it in @@ -385,7 +384,7 @@ public final class WordComposer { /** * Before fetching suggestions, we don't necessarily know about the capitalized mode yet. - * + *

* If we don't have a composing word yet, we take a note of this mode so that we can then * supply this information to the suggestion process. If we have a composing word, then * the previous mode has priority over this. diff --git a/app/src/main/java/helium314/keyboard/latin/common/LocaleUtils.kt b/app/src/main/java/helium314/keyboard/latin/common/LocaleUtils.kt index 766308182..fa2d81c78 100644 --- a/app/src/main/java/helium314/keyboard/latin/common/LocaleUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/common/LocaleUtils.kt @@ -58,7 +58,7 @@ object LocaleUtils { // The compared locales are fully identical. This is the best match level. private const val LOCALE_FULL_MATCH = 30 - const val LOCALE_GOOD_MATCH = LOCALE_LANGUAGE_MATCH_COUNTRY_DIFFER; + const val LOCALE_GOOD_MATCH = LOCALE_LANGUAGE_MATCH_COUNTRY_DIFFER /** * Return how well a tested locale matches a reference locale. diff --git a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogicHandler.java b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogicHandler.java index f75f01854..99b77fa3e 100644 --- a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogicHandler.java +++ b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogicHandler.java @@ -82,12 +82,8 @@ class InputLogicHandler implements Handler.Callback { // Called on the Non-UI handler thread by the Handler code. @Override public boolean handleMessage(final Message msg) { - switch (msg.what) { - case MSG_GET_SUGGESTED_WORDS: - mLatinIME.getSuggestedWords(msg.arg1 /* inputStyle */, - msg.arg2 /* sequenceNumber */, (OnGetSuggestedWordsCallback) msg.obj); - break; - } + if (msg.what == MSG_GET_SUGGESTED_WORDS) + mLatinIME.getSuggestedWords(msg.arg1, msg.arg2, (OnGetSuggestedWordsCallback) msg.obj); return true; } @@ -122,12 +118,7 @@ class InputLogicHandler implements Handler.Callback { return; } mInputLogic.mWordComposer.setBatchInputPointers(batchPointers); - final OnGetSuggestedWordsCallback callback = new OnGetSuggestedWordsCallback() { - @Override - public void onGetSuggestedWords(final SuggestedWords suggestedWords) { - showGestureSuggestionsWithPreviewVisuals(suggestedWords, isTailBatchInput); - } - }; + final OnGetSuggestedWordsCallback callback = suggestedWords -> showGestureSuggestionsWithPreviewVisuals(suggestedWords, isTailBatchInput); getSuggestedWords(isTailBatchInput ? SuggestedWords.INPUT_STYLE_TAIL_BATCH : SuggestedWords.INPUT_STYLE_UPDATE_BATCH, sequenceNumber, callback); } @@ -159,7 +150,7 @@ class InputLogicHandler implements Handler.Callback { /** * Update a batch input. - * + *

* This fetches suggestions and updates the suggestion strip and the floating text preview. * * @param batchPointers the updated batch pointers. @@ -168,12 +159,12 @@ class InputLogicHandler implements Handler.Callback { // Called on the UI thread by InputLogic. public void onUpdateBatchInput(final InputPointers batchPointers, final int sequenceNumber) { - updateBatchInput(batchPointers, sequenceNumber, false /* isTailBatchInput */); + updateBatchInput(batchPointers, sequenceNumber, false); } /** * Cancel a batch input. - * + *

* Note that as opposed to updateTailBatchInput, we do the UI side of this immediately on the * same thread, rather than get this to call a method in LatinIME. This is because * canceling a batch input does not necessitate the long operation of pulling suggestions. @@ -187,7 +178,7 @@ class InputLogicHandler implements Handler.Callback { /** * Trigger an update for a tail batch input. - * + *

* A tail batch input is the last update for a gesture, the one that is triggered after the * user lifts their finger. This method schedules fetching suggestions on the non-UI thread, * then when the suggestions are computed it comes back on the UI thread to update the @@ -199,7 +190,7 @@ class InputLogicHandler implements Handler.Callback { // Called on the UI thread by InputLogic. public void updateTailBatchInput(final InputPointers batchPointers, final int sequenceNumber) { - updateBatchInput(batchPointers, sequenceNumber, true /* isTailBatchInput */); + updateBatchInput(batchPointers, sequenceNumber, true); } public void getSuggestedWords(final int inputStyle, final int sequenceNumber, diff --git a/app/src/main/java/helium314/keyboard/latin/makedict/WordProperty.java b/app/src/main/java/helium314/keyboard/latin/makedict/WordProperty.java index 5910d74c0..2fcdfa617 100644 --- a/app/src/main/java/helium314/keyboard/latin/makedict/WordProperty.java +++ b/app/src/main/java/helium314/keyboard/latin/makedict/WordProperty.java @@ -6,6 +6,7 @@ package helium314.keyboard.latin.makedict; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.inputmethod.latin.BinaryDictionary; @@ -20,7 +21,7 @@ import java.util.Arrays; /** * Utility class for a word with a probability. - * + *

* This is chiefly used to iterate a dictionary. */ public final class WordProperty implements Comparable { @@ -150,7 +151,7 @@ public final class WordProperty implements Comparable { /** * Three-way comparison. - * + *

* A Word x is greater than a word y if x has a higher frequency. If they have the same * frequency, they are sorted in lexicographic order. */ @@ -163,15 +164,14 @@ public final class WordProperty implements Comparable { /** * Equality test. - * + *

* Words are equal if they have the same frequency, the same spellings, and the same * attributes. */ @Override public boolean equals(Object o) { if (o == this) return true; - if (!(o instanceof WordProperty)) return false; - WordProperty w = (WordProperty)o; + if (!(o instanceof WordProperty w)) return false; return mProbabilityInfo.equals(w.mProbabilityInfo) && mWord.equals(w.mWord) && mShortcutTargets.equals(w.mShortcutTargets) && equals(mNgrams, w.mNgrams) && mIsNotAWord == w.mIsNotAWord && mIsPossiblyOffensive == w.mIsPossiblyOffensive @@ -199,7 +199,7 @@ public final class WordProperty implements Comparable { } @Override - public String toString() { + @NonNull public String toString() { return CombinedFormatUtils.formatWordProperty(this); } } diff --git a/app/src/main/java/helium314/keyboard/latin/permissions/PermissionsActivity.java b/app/src/main/java/helium314/keyboard/latin/permissions/PermissionsActivity.java index a3c20ee10..1d190e9a5 100644 --- a/app/src/main/java/helium314/keyboard/latin/permissions/PermissionsActivity.java +++ b/app/src/main/java/helium314/keyboard/latin/permissions/PermissionsActivity.java @@ -57,7 +57,7 @@ public final class PermissionsActivity } @Override - protected void onSaveInstanceState(Bundle outState) { + protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putInt(EXTRA_PERMISSION_REQUEST_CODE, mPendingRequestCode); } @@ -68,8 +68,8 @@ public final class PermissionsActivity // Only do request when there is no pending request to avoid duplicated requests. if (mPendingRequestCode == INVALID_REQUEST_CODE) { final Bundle extras = getIntent().getExtras(); - final String[] permissionsToRequest = - extras.getStringArray(EXTRA_PERMISSION_REQUESTED_PERMISSIONS); + if (extras == null) return; + final String[] permissionsToRequest = extras.getStringArray(EXTRA_PERMISSION_REQUESTED_PERMISSIONS); mPendingRequestCode = extras.getInt(EXTRA_PERMISSION_REQUEST_CODE); // Assuming that all supplied permissions are not granted yet, so that we don't need to // check them again. diff --git a/app/src/main/java/helium314/keyboard/latin/settings/AdvancedSettingsFragment.kt b/app/src/main/java/helium314/keyboard/latin/settings/AdvancedSettingsFragment.kt index 740af6f4c..937441df1 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/AdvancedSettingsFragment.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/AdvancedSettingsFragment.kt @@ -73,6 +73,7 @@ import java.util.zip.ZipOutputStream * - Improve keyboard * - Debug settings */ +@Suppress("KotlinConstantConditions") // build type might be a constant, but depends on... build type! class AdvancedSettingsFragment : SubScreenFragment() { private val libfile by lazy { File(requireContext().filesDir.absolutePath + File.separator + JniUtils.JNI_LIB_IMPORT_FILE_NAME) } private val backupFilePatterns by lazy { listOf( @@ -436,8 +437,8 @@ class AdvancedSettingsFragment : SubScreenFragment() { } checkVersionUpgrade(requireContext()) Settings.getInstance().startListener() - val additionalSubtypes = Settings.readPrefAdditionalSubtypes(sharedPreferences, resources); - updateAdditionalSubtypes(AdditionalSubtypeUtils.createAdditionalSubtypesArray(additionalSubtypes)); + val additionalSubtypes = Settings.readPrefAdditionalSubtypes(sharedPreferences, resources) + updateAdditionalSubtypes(AdditionalSubtypeUtils.createAdditionalSubtypesArray(additionalSubtypes)) reloadEnabledSubtypes(requireContext()) val newDictBroadcast = Intent(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION) activity?.sendBroadcast(newDictBroadcast) diff --git a/app/src/main/java/helium314/keyboard/latin/setup/SetupStartIndicatorView.java b/app/src/main/java/helium314/keyboard/latin/setup/SetupStartIndicatorView.java index 004fbdd02..bab9415d8 100644 --- a/app/src/main/java/helium314/keyboard/latin/setup/SetupStartIndicatorView.java +++ b/app/src/main/java/helium314/keyboard/latin/setup/SetupStartIndicatorView.java @@ -21,7 +21,6 @@ import helium314.keyboard.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 { public SetupStartIndicatorView(final Context context, final AttributeSet attrs) { @@ -72,13 +71,13 @@ public final class SetupStartIndicatorView extends LinearLayout { @Override protected void onDraw(@NonNull final Canvas canvas) { super.onDraw(canvas); - final int layoutDirection = ViewCompat.getLayoutDirection(this); + final int layoutDirection = getLayoutDirection(); final int width = getWidth(); final int height = getHeight(); final float halfHeight = height / 2.0f; final Path path = mIndicatorPath; path.rewind(); - if (layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL) { + if (layoutDirection == View.LAYOUT_DIRECTION_RTL) { // Left arrow path.moveTo(width, 0.0f); path.lineTo(0.0f, halfHeight); diff --git a/app/src/main/java/helium314/keyboard/latin/setup/SetupStepIndicatorView.java b/app/src/main/java/helium314/keyboard/latin/setup/SetupStepIndicatorView.java index bee8069f8..320c0fe48 100644 --- a/app/src/main/java/helium314/keyboard/latin/setup/SetupStepIndicatorView.java +++ b/app/src/main/java/helium314/keyboard/latin/setup/SetupStepIndicatorView.java @@ -13,9 +13,9 @@ import android.graphics.Path; import android.util.AttributeSet; import android.view.View; -import helium314.keyboard.latin.R; +import androidx.annotation.NonNull; -import androidx.core.view.ViewCompat; +import helium314.keyboard.latin.R; public final class SetupStepIndicatorView extends View { private final Path mIndicatorPath = new Path(); @@ -29,17 +29,17 @@ public final class SetupStepIndicatorView extends View { } public void setIndicatorPosition(final int stepPos, final int totalStepNum) { - final int layoutDirection = ViewCompat.getLayoutDirection(this); + final int layoutDirection = getLayoutDirection(); // The indicator position is the center of the partition that is equally divided into // the total step number. final float partionWidth = 1.0f / totalStepNum; final float pos = stepPos * partionWidth + partionWidth / 2.0f; - mXRatio = (layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL) ? 1.0f - pos : pos; + mXRatio = (layoutDirection == View.LAYOUT_DIRECTION_RTL) ? 1.0f - pos : pos; invalidate(); } @Override - protected void onDraw(final Canvas canvas) { + protected void onDraw(@NonNull final Canvas canvas) { super.onDraw(canvas); final int xPos = (int)(getWidth() * mXRatio); final int height = getHeight(); diff --git a/app/src/main/java/helium314/keyboard/latin/suggestions/MoreSuggestions.java b/app/src/main/java/helium314/keyboard/latin/suggestions/MoreSuggestions.java index 93030def7..8ef29dd40 100644 --- a/app/src/main/java/helium314/keyboard/latin/suggestions/MoreSuggestions.java +++ b/app/src/main/java/helium314/keyboard/latin/suggestions/MoreSuggestions.java @@ -7,10 +7,12 @@ package helium314.keyboard.latin.suggestions; import android.content.Context; -import android.content.res.Resources; import android.graphics.Paint; import android.graphics.drawable.Drawable; +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + import helium314.keyboard.keyboard.Key; import helium314.keyboard.keyboard.Keyboard; import helium314.keyboard.keyboard.internal.KeyboardBuilder; @@ -45,12 +47,11 @@ public final class MoreSuggestions extends Keyboard { public int layout(final SuggestedWords suggestedWords, final int fromIndex, final int maxWidth, final int minWidth, final int maxRow, final Paint paint, - final Resources res) { + final Context context) { clearKeys(); - mDivider = res.getDrawable(R.drawable.more_suggestions_divider); - mDividerWidth = mDivider.getIntrinsicWidth(); - final float padding = res.getDimension( - R.dimen.config_more_suggestions_key_horizontal_padding); + mDivider = ContextCompat.getDrawable(context, R.drawable.more_suggestions_divider); + mDividerWidth = mDivider == null ? 0 : mDivider.getIntrinsicWidth(); + final float padding = context.getResources().getDimension(R.dimen.config_more_suggestions_key_horizontal_padding); int row = 0; int index = fromIndex; @@ -186,7 +187,7 @@ public final class MoreSuggestions extends Keyboard { mParams.mVerticalGap = mParams.mTopPadding = parentKeyboard.mVerticalGap / 2; mPaneView.updateKeyboardGeometry(mParams.mDefaultAbsoluteRowHeight); final int count = mParams.layout(suggestedWords, fromIndex, maxWidth, minWidth, maxRow, - mPaneView.newLabelPaint(null /* key */), mResources); + mPaneView.newLabelPaint(null /* key */), getMContext()); mFromIndex = fromIndex; mToIndex = fromIndex + count; mSuggestedWords = suggestedWords; @@ -194,7 +195,7 @@ public final class MoreSuggestions extends Keyboard { } @Override - public MoreSuggestions build() { + @NonNull public MoreSuggestions build() { final MoreSuggestionsParam params = mParams; for (int index = mFromIndex; index < mToIndex; index++) { final int x = params.getX(index); diff --git a/app/src/main/java/helium314/keyboard/latin/suggestions/SuggestionStripView.java b/app/src/main/java/helium314/keyboard/latin/suggestions/SuggestionStripView.java index a8b4ffc2b..aea803001 100644 --- a/app/src/main/java/helium314/keyboard/latin/suggestions/SuggestionStripView.java +++ b/app/src/main/java/helium314/keyboard/latin/suggestions/SuggestionStripView.java @@ -67,8 +67,8 @@ import java.util.ArrayList; import java.util.concurrent.atomic.AtomicBoolean; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.widget.PopupMenu; -import androidx.core.view.ViewCompat; public final class SuggestionStripView extends RelativeLayout implements OnClickListener, OnLongClickListener { @@ -76,7 +76,6 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick void pickSuggestionManually(SuggestedWordInfo word); void onCodeInput(int primaryCode, int x, int y, boolean isKeyRepeat); void removeSuggestion(final String word); - CharSequence getSelection(); } public static boolean DEBUG_SUGGESTIONS; @@ -124,8 +123,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick } public void setLayoutDirection(final int layoutDirection) { - ViewCompat.setLayoutDirection(mSuggestionStripView, layoutDirection); - ViewCompat.setLayoutDirection(mSuggestionsStrip, layoutDirection); + mSuggestionStripView.setLayoutDirection(layoutDirection); + mSuggestionsStrip.setLayoutDirection(layoutDirection); } public void showSuggestionsStrip() { @@ -141,6 +140,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick this(context, attrs, R.attr.suggestionStripViewStyle); } + @SuppressLint("InflateParams") // does not seem suitable here public SuggestionStripView(final Context context, final AttributeSet attrs, final int defStyle) { super(context, attrs, defStyle); final Colors colors = Settings.getInstance().getCurrent().mColors; @@ -183,6 +183,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick R.dimen.config_more_suggestions_modal_tolerance); mMoreSuggestionsSlidingDetector = new GestureDetector(context, mMoreSuggestionsSlidingListener); + @SuppressLint("CustomViewStyleable") final TypedArray keyboardAttr = context.obtainStyledAttributes(attrs, R.styleable.Keyboard, defStyle, R.style.SuggestionStripView); mIncognitoIcon = keyboardAttr.getDrawable(R.styleable.Keyboard_iconIncognitoKey); mToolbarArrowIcon = keyboardAttr.getDrawable(R.styleable.Keyboard_iconToolbarKey); @@ -262,9 +263,9 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick public void setRtl(final boolean isRtlLanguage) { final int layoutDirection; if (!Settings.getInstance().getCurrent().mVarToolbarDirection) - layoutDirection = ViewCompat.LAYOUT_DIRECTION_LOCALE; + layoutDirection = View.LAYOUT_DIRECTION_LOCALE; else{ - layoutDirection = isRtlLanguage ? ViewCompat.LAYOUT_DIRECTION_RTL : ViewCompat.LAYOUT_DIRECTION_LTR; + layoutDirection = isRtlLanguage ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR; mRtl = isRtlLanguage ? -1 : 1; } mStripVisibilityGroup.setLayoutDirection(layoutDirection); @@ -528,7 +529,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick private final GestureDetector.OnGestureListener mMoreSuggestionsSlidingListener = new GestureDetector.SimpleOnGestureListener() { @Override - public boolean onScroll(MotionEvent down, MotionEvent me, float deltaX, float deltaY) { + public boolean onScroll(@Nullable MotionEvent down, @NonNull MotionEvent me, float deltaX, float deltaY) { + if (down == null) return false; final float dy = me.getY() - down.getY(); if (mToolbarContainer.getVisibility() != VISIBLE && deltaY > 0 && dy < 0) { return showMoreSuggestions(); @@ -637,7 +639,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback(KeyCode.NOT_SPECIFIED, this); final Object tag = view.getTag(); if (tag instanceof ToolbarKey) { - final Integer code = getCodeForToolbarKey((ToolbarKey) tag); + final int code = getCodeForToolbarKey((ToolbarKey) tag); if (code != KeyCode.UNSPECIFIED) { Log.d(TAG, "click toolbar key "+tag); mListener.onCodeInput(code, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false); diff --git a/app/src/main/java/helium314/keyboard/latin/utils/CustomLayoutUtils.kt b/app/src/main/java/helium314/keyboard/latin/utils/CustomLayoutUtils.kt index 05283a1f0..3fa3d2e64 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/CustomLayoutUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/CustomLayoutUtils.kt @@ -18,7 +18,6 @@ import helium314.keyboard.keyboard.internal.keyboard_parser.RawKeyboardParser import helium314.keyboard.keyboard.internal.keyboard_parser.addLocaleKeyTextsToParams import helium314.keyboard.latin.R import helium314.keyboard.latin.common.FileUtils -import helium314.keyboard.latin.settings.Settings import java.io.File import java.io.IOException import java.math.BigInteger @@ -80,13 +79,13 @@ private fun checkLayout(layoutContent: String, context: Context): Boolean? { params.mPopupKeyTypes.add(POPUP_KEYS_LAYOUT) addLocaleKeyTextsToParams(context, params, POPUP_KEYS_NORMAL) try { - val keys = RawKeyboardParser.parseJsonString(layoutContent).map { it.mapNotNull { it.compute(params)?.toKeyParams(params) } } + val keys = RawKeyboardParser.parseJsonString(layoutContent).map { row -> row.mapNotNull { it.compute(params)?.toKeyParams(params) } } if (!checkKeys(keys)) return null return true } catch (e: Exception) { Log.w(TAG, "error parsing custom json layout", e) } try { - val keys = RawKeyboardParser.parseSimpleString(layoutContent).map { it.map { it.toKeyParams(params) } } + val keys = RawKeyboardParser.parseSimpleString(layoutContent).map { row -> row.map { it.toKeyParams(params) } } if (!checkKeys(keys)) return null return false @@ -94,7 +93,7 @@ private fun checkLayout(layoutContent: String, context: Context): Boolean? { if (layoutContent.startsWith("[")) { // layout can't be loaded, assume it's json -> load json layout again because the error message shown to the user is from the most recent error try { - RawKeyboardParser.parseJsonString(layoutContent).map { it.mapNotNull { it.compute(params)?.toKeyParams(params) } } + RawKeyboardParser.parseJsonString(layoutContent).map { row -> row.mapNotNull { it.compute(params)?.toKeyParams(params) } } } catch (e: Exception) { Log.w(TAG, "error parsing custom json layout", e) } } return null @@ -109,19 +108,19 @@ private fun checkKeys(keys: List>): Boolean { Log.w(TAG, "too many rows") return false } - if (keys.any { it.size > 20 }) { + if (keys.any { row -> row.size > 20 }) { Log.w(TAG, "too many keys in one row") return false } - if (keys.any { it.any { ((it.mLabel?.length ?: 0) > 6) } }) { + if (keys.any { row -> row.any { ((it.mLabel?.length ?: 0) > 6) } }) { Log.w(TAG, "too long text on key") return false } - if (keys.any { it.any { (it.mPopupKeys?.size ?: 0) > 20 } }) { + if (keys.any { row -> row.any { (it.mPopupKeys?.size ?: 0) > 20 } }) { Log.w(TAG, "too many popup keys on a key") return false } - if (keys.any { it.any { it.mPopupKeys?.any { (it.mLabel?.length ?: 0) > 10 } == true } }) { + if (keys.any { row -> row.any { it.mPopupKeys?.any { popupKey -> (popupKey.mLabel?.length ?: 0) > 10 } == true } }) { Log.w(TAG, "too long text on popup key") return false } diff --git a/app/src/main/java/helium314/keyboard/latin/utils/RecapitalizeStatus.java b/app/src/main/java/helium314/keyboard/latin/utils/RecapitalizeStatus.java index 0b0f129f9..1616017fd 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/RecapitalizeStatus.java +++ b/app/src/main/java/helium314/keyboard/latin/utils/RecapitalizeStatus.java @@ -29,7 +29,7 @@ public class RecapitalizeStatus { CAPS_MODE_ALL_UPPER }; - private static final int getStringMode(final String string, final int[] sortedSeparators) { + private static int getStringMode(final String string, final int[] sortedSeparators) { if (StringUtils.isIdenticalAfterUpcase(string)) { return CAPS_MODE_ALL_UPPER; } else if (StringUtils.isIdenticalAfterDowncase(string)) { @@ -42,14 +42,14 @@ public class RecapitalizeStatus { } public static String modeToString(final int recapitalizeMode) { - switch (recapitalizeMode) { - case NOT_A_RECAPITALIZE_MODE: return "undefined"; - case CAPS_MODE_ORIGINAL_MIXED_CASE: return "mixedCase"; - case CAPS_MODE_ALL_LOWER: return "allLower"; - case CAPS_MODE_FIRST_WORD_UPPER: return "firstWordUpper"; - case CAPS_MODE_ALL_UPPER: return "allUpper"; - default: return "unknown<" + recapitalizeMode + ">"; - } + return switch (recapitalizeMode) { + case NOT_A_RECAPITALIZE_MODE -> "undefined"; + case CAPS_MODE_ORIGINAL_MIXED_CASE -> "mixedCase"; + case CAPS_MODE_ALL_LOWER -> "allLower"; + case CAPS_MODE_FIRST_WORD_UPPER -> "firstWordUpper"; + case CAPS_MODE_ALL_UPPER -> "allUpper"; + default -> "unknown<" + recapitalizeMode + ">"; + }; } /** @@ -145,21 +145,10 @@ public class RecapitalizeStatus { } ++count; switch (ROTATION_STYLE[mRotationStyleCurrentIndex]) { - case CAPS_MODE_ORIGINAL_MIXED_CASE: - mStringAfter = mStringBefore; - break; - case CAPS_MODE_ALL_LOWER: - mStringAfter = mStringBefore.toLowerCase(mLocale); - break; - case CAPS_MODE_FIRST_WORD_UPPER: - mStringAfter = StringUtils.capitalizeEachWord(mStringBefore, mSortedSeparators, - mLocale); - break; - case CAPS_MODE_ALL_UPPER: - mStringAfter = mStringBefore.toUpperCase(mLocale); - break; - default: - mStringAfter = mStringBefore; + case CAPS_MODE_ALL_LOWER -> mStringAfter = mStringBefore.toLowerCase(mLocale); + case CAPS_MODE_FIRST_WORD_UPPER -> mStringAfter = StringUtils.capitalizeEachWord(mStringBefore, mSortedSeparators, mLocale); + case CAPS_MODE_ALL_UPPER -> mStringAfter = mStringBefore.toUpperCase(mLocale); + default -> mStringAfter = mStringBefore; } } while (mStringAfter.equals(oldResult) && count < ROTATION_STYLE.length + 1); mCursorEndAfter = mCursorStartAfter + mStringAfter.length(); diff --git a/app/src/test/java/helium314/keyboard/KeySpecParserTest.kt b/app/src/test/java/helium314/keyboard/KeySpecParserTest.kt index 1c0fc1ba1..5212984e7 100644 --- a/app/src/test/java/helium314/keyboard/KeySpecParserTest.kt +++ b/app/src/test/java/helium314/keyboard/KeySpecParserTest.kt @@ -2,7 +2,6 @@ package helium314.keyboard import helium314.keyboard.keyboard.internal.KeySpecParser import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode -import helium314.keyboard.latin.common.Constants import org.junit.Assert.assertEquals import org.junit.Test diff --git a/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt b/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt index 68d36b977..f5d398085 100644 --- a/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt +++ b/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt @@ -867,7 +867,7 @@ private val ic = object : InputConnection { // update selection selectionStart -= beforeLength selectionEnd -= beforeLength - return true; + return true } override fun sendKeyEvent(p0: KeyEvent): Boolean { if (p0.action != KeyEvent.ACTION_DOWN) return true // only change the text on key down, like RichInputConnection does @@ -908,7 +908,7 @@ private val ic = object : InputConnection { override fun clearMetaKeyStates(p0: Int): Boolean = TODO("Not yet implemented") override fun reportFullscreenMode(p0: Boolean): Boolean = TODO("Not yet implemented") override fun performPrivateCommand(p0: String?, p1: Bundle?): Boolean = TODO("Not yet implemented") - override fun getHandler(): Handler? = TODO("Not yet implemented") + override fun getHandler(): Handler = TODO("Not yet implemented") override fun closeConnection() = TODO("Not yet implemented") override fun commitContent(p0: InputContentInfo, p1: Int, p2: Bundle?): Boolean = TODO("Not yet implemented") } diff --git a/app/src/test/java/helium314/keyboard/latin/SuggestTest.kt b/app/src/test/java/helium314/keyboard/latin/SuggestTest.kt index 7e92f48f7..fe07e5c5f 100644 --- a/app/src/test/java/helium314/keyboard/latin/SuggestTest.kt +++ b/app/src/test/java/helium314/keyboard/latin/SuggestTest.kt @@ -25,6 +25,7 @@ import org.robolectric.annotation.Implements import org.robolectric.shadows.ShadowLog import java.util.* +@Suppress("NonAsciiCharacters") @RunWith(RobolectricTestRunner::class) @Config(shadows = [ ShadowLocaleManagerCompat::class, diff --git a/build.gradle b/build.gradle index 0f10f1bfc..83e31cf34 100755 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.9.23' + ext.kotlin_version = '1.9.24' repositories { mavenCentral() google() @@ -17,7 +17,7 @@ buildscript { } plugins { - id 'org.jetbrains.kotlin.plugin.serialization' version '1.9.23' apply false + id 'org.jetbrains.kotlin.plugin.serialization' version "$kotlin_version" } allprojects {