From b5461fa069684ca4bf80f2a3713c80d389d4cbc5 Mon Sep 17 00:00:00 2001 From: "Arthur K." Date: Tue, 9 Dec 2025 20:25:04 +0300 Subject: [PATCH 1/4] feat: configurable vibration amplitude on api >= 26 --- .../latin/AudioAndHapticFeedbackManager.java | 27 +++++----- .../keyboard/latin/settings/Defaults.kt | 5 +- .../keyboard/latin/settings/Settings.java | 25 +++++++-- .../latin/settings/SettingsValues.java | 12 +++-- .../settings/screens/PreferencesScreen.kt | 52 ++++++++++++++++--- app/src/main/res/values/strings.xml | 5 ++ 6 files changed, 98 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java b/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java index 9c1f6aa724..7c2cdecd77 100644 --- a/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java +++ b/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java @@ -8,7 +8,10 @@ import android.content.Context; import android.media.AudioManager; +import android.os.Build; +import android.os.VibrationEffect; import android.os.Vibrator; +import android.util.Log; import android.view.HapticFeedbackConstants; import android.view.View; @@ -64,11 +67,14 @@ public boolean hasVibrator() { return mVibrator != null && mVibrator.hasVibrator(); } - public void vibrate(final long milliseconds) { - if (mVibrator == null || milliseconds <= 0) { + public void vibrate(final long milliseconds, final int amplitude) { + if (mVibrator == null || milliseconds <= 0 || amplitude <= 0) { return; } - mVibrator.vibrate(milliseconds); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + mVibrator.vibrate(VibrationEffect.createOneShot(milliseconds, amplitude)); + } else + mVibrator.vibrate(milliseconds); } private boolean reevaluateIfSoundIsOn() { @@ -99,22 +105,19 @@ public void performAudioFeedback(final int code, final HapticEvent hapticEvent) } public void performHapticFeedback(final View viewToPerformHapticFeedbackOn, final HapticEvent hapticEvent) { - if (!mSettingsValues.mVibrateOn || (mDoNotDisturb && !mSettingsValues.mVibrateInDndMode)) { + if (mDoNotDisturb && !mSettingsValues.mVibrateInDndMode) { return; } if (hapticEvent == HapticEvent.NO_HAPTICS) { // Avoid surprises with the handling of HapticFeedbackConstants.NO_HAPTICS return; } - if (hapticEvent.allowCustomDuration && mSettingsValues.mKeypressVibrationDuration >= 0) { - vibrate(mSettingsValues.mKeypressVibrationDuration); - return; - } - // Go ahead with the system default - if (viewToPerformHapticFeedbackOn != null) { + if (mSettingsValues.mVibrationType.equals("custom") && hapticEvent.allowCustomDuration) { + vibrate(mSettingsValues.mKeypressVibrationDuration, mSettingsValues.mKeypressVibrationAmplitude); + } else if (!mSettingsValues.mVibrationType.equals("off") && viewToPerformHapticFeedbackOn != null) { viewToPerformHapticFeedbackOn.performHapticFeedback( - hapticEvent.feedbackConstant, - HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); + hapticEvent.feedbackConstant, + HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); } } diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt index e036231c07..99a2a9b562 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt @@ -51,7 +51,7 @@ object Defaults { const val PREF_CUSTOM_ICON_NAMES = "" const val PREF_TOOLBAR_CUSTOM_KEY_CODES = "" const val PREF_AUTO_CAP = true - const val PREF_VIBRATE_ON = false + const val PREF_VIBRATION_TYPE = "off" const val PREF_VIBRATE_IN_DND_MODE = false const val PREF_SOUND_ON = false const val PREF_SUGGEST_EMOJIS = true @@ -105,7 +105,8 @@ object Defaults { const val PREF_SUGGEST_PUNCTUATION = false const val PREF_SUGGEST_CLIPBOARD_CONTENT = true const val PREF_GESTURE_INPUT = true - const val PREF_VIBRATION_DURATION_SETTINGS = -1 + const val PREF_VIBRATION_DURATION_SETTINGS = 10 + const val PREF_VIBRATION_AMPLITUDE_SETTINGS = 255 const val PREF_KEYPRESS_SOUND_VOLUME = -0.01f const val PREF_KEY_LONGPRESS_TIMEOUT = 300 const val PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY = true diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java index ee8f57cf3b..d9c75fc9df 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java @@ -69,6 +69,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_AUTO_CAP = "auto_cap"; public static final String PREF_VIBRATE_ON = "vibrate_on"; + public static final String PREF_VIBRATION_TYPE = "vibration_type"; public static final String PREF_VIBRATE_IN_DND_MODE = "vibrate_in_dnd_mode"; public static final String PREF_SOUND_ON = "sound_on"; public static final String PREF_SUGGEST_EMOJIS = "suggest_emojis"; @@ -116,6 +117,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_SUGGEST_CLIPBOARD_CONTENT = "suggest_clipboard_content"; public static final String PREF_GESTURE_INPUT = "gesture_input"; public static final String PREF_VIBRATION_DURATION_SETTINGS = "vibration_duration_settings"; + public static final String PREF_VIBRATION_AMPLITUDE_SETTINGS = "vibration_amplitude_settings"; public static final String PREF_KEYPRESS_SOUND_VOLUME = "keypress_sound_volume"; public static final String PREF_KEY_LONGPRESS_TIMEOUT = "key_longpress_timeout"; public static final String PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY = "enable_emoji_alt_physical_key"; @@ -232,6 +234,22 @@ private void onCreate(final Context context) { mContext = context; mPrefs = KtxKt.prefs(context); mPrefs.registerOnSharedPreferenceChangeListener(this); + migrateLegacyPreferences(); + } + + private void migrateLegacyPreferences() { + final var prefsEditor = mPrefs.edit(); + if (mPrefs.contains(Settings.PREF_VIBRATE_ON)) { + if (mPrefs.getBoolean(Settings.PREF_VIBRATE_ON, false)) + prefsEditor.putString(PREF_VIBRATION_TYPE, + mPrefs.getInt(Settings.PREF_VIBRATION_DURATION_SETTINGS, Defaults.PREF_VIBRATION_DURATION_SETTINGS) == -1 + ? "system" + : "custom"); + else + prefsEditor.putString(PREF_VIBRATION_TYPE, "off"); + prefsEditor.remove(Settings.PREF_VIBRATE_ON); + } + prefsEditor.apply(); } public void onDestroy() { @@ -300,9 +318,10 @@ public static int readScreenMetrics(final Resources res) { return res.getInteger(R.integer.config_screen_metrics); } - public static boolean readVibrationEnabled(final SharedPreferences prefs) { - return prefs.getBoolean(PREF_VIBRATE_ON, Defaults.PREF_VIBRATE_ON) - && AudioAndHapticFeedbackManager.getInstance().hasVibrator(); + public static String readVibrationType(final SharedPreferences prefs) { + return AudioAndHapticFeedbackManager.getInstance().hasVibrator() + ? prefs.getString(PREF_VIBRATION_TYPE, Defaults.PREF_VIBRATION_TYPE) + : "off"; } public void toggleAutoCorrect() { diff --git a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java index 6dcb79689f..261ede9dae 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java @@ -51,7 +51,7 @@ public class SettingsValues { public final int mDisplayOrientation; // From preferences public final boolean mAutoCap; - public final boolean mVibrateOn; + public final String mVibrationType; public final boolean mVibrateInDndMode; public final boolean mSoundOn; public final boolean mSuggestEmojis; @@ -141,6 +141,7 @@ public class SettingsValues { public final boolean mSuggestionStripHiddenPerUserSettings; public final boolean mSecondaryStripVisible; public final int mKeypressVibrationDuration; + public final int mKeypressVibrationAmplitude; public final float mKeypressSoundVolume; public final boolean mAutoCorrectionEnabledPerUserSettings; public final boolean mAutoCorrectEnabled; @@ -172,7 +173,7 @@ public SettingsValues(final Context context, final SharedPreferences prefs, fina mToolbarMode = Settings.readToolbarMode(prefs); mToolbarHidingGlobal = prefs.getBoolean(Settings.PREF_TOOLBAR_HIDING_GLOBAL, Defaults.PREF_TOOLBAR_HIDING_GLOBAL); mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, Defaults.PREF_AUTO_CAP) && ScriptUtils.scriptSupportsUppercase(mLocale); - mVibrateOn = Settings.readVibrationEnabled(prefs); + mVibrationType = Settings.readVibrationType(prefs); mVibrateInDndMode = prefs.getBoolean(Settings.PREF_VIBRATE_IN_DND_MODE, Defaults.PREF_VIBRATE_IN_DND_MODE); mSoundOn = prefs.getBoolean(Settings.PREF_SOUND_ON, Defaults.PREF_SOUND_ON); mSuggestEmojis = prefs.getBoolean(Settings.PREF_SUGGEST_EMOJIS, Defaults.PREF_SUGGEST_EMOJIS); @@ -231,6 +232,7 @@ public SettingsValues(final Context context, final SharedPreferences prefs, fina // Compute other readable settings mKeyLongpressTimeout = prefs.getInt(Settings.PREF_KEY_LONGPRESS_TIMEOUT, Defaults.PREF_KEY_LONGPRESS_TIMEOUT); mKeypressVibrationDuration = prefs.getInt(Settings.PREF_VIBRATION_DURATION_SETTINGS, Defaults.PREF_VIBRATION_DURATION_SETTINGS); + mKeypressVibrationAmplitude = prefs.getInt(Settings.PREF_VIBRATION_AMPLITUDE_SETTINGS, Defaults.PREF_VIBRATION_AMPLITUDE_SETTINGS); mKeypressSoundVolume = prefs.getFloat(Settings.PREF_KEYPRESS_SOUND_VOLUME, Defaults.PREF_KEYPRESS_SOUND_VOLUME); mEnableEmojiAltPhysicalKey = prefs.getBoolean(Settings.PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY, Defaults.PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY); mGestureInputEnabled = JniUtils.sHaveGestureLib && prefs.getBoolean(Settings.PREF_GESTURE_INPUT, Defaults.PREF_GESTURE_INPUT); @@ -384,8 +386,8 @@ public String dump() { sb.append("" + mSpacingAndPunctuations.dump()); sb.append("\n mAutoCap = "); sb.append("" + mAutoCap); - sb.append("\n mVibrateOn = "); - sb.append("" + mVibrateOn); + sb.append("\n mVibrationType = "); + sb.append("" + mVibrationType); sb.append("\n mSoundOn = "); sb.append("" + mSoundOn); sb.append("\n mKeyPreviewPopupOn = "); @@ -420,6 +422,8 @@ public String dump() { sb.append("" + mInputAttributes); sb.append("\n mKeypressVibrationDuration = "); sb.append("" + mKeypressVibrationDuration); + sb.append("\n mKeypressVibrationAmplitude = "); + sb.append("" + mKeypressVibrationAmplitude); sb.append("\n mKeypressSoundVolume = "); sb.append("" + mKeypressSoundVolume); sb.append("\n mAutoCorrectEnabled = "); diff --git a/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt index 544c32ef31..f296bd0418 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt @@ -3,6 +3,7 @@ package helium314.keyboard.settings.screens import android.content.Context import android.media.AudioManager +import android.os.Build import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState @@ -52,10 +53,13 @@ fun PreferencesScreen( Settings.PREF_SHOW_TLD_POPUP_KEYS, Settings.PREF_POPUP_ON, if (AudioAndHapticFeedbackManager.getInstance().hasVibrator()) - Settings.PREF_VIBRATE_ON else null, - if (prefs.getBoolean(Settings.PREF_VIBRATE_ON, Defaults.PREF_VIBRATE_ON)) + Settings.PREF_VIBRATION_TYPE else null, + if (prefs.getString(Settings.PREF_VIBRATION_TYPE, Defaults.PREF_VIBRATION_TYPE) == "custom") Settings.PREF_VIBRATION_DURATION_SETTINGS else null, - if (prefs.getBoolean(Settings.PREF_VIBRATE_ON, Defaults.PREF_VIBRATE_ON)) + if (prefs.getString(Settings.PREF_VIBRATION_TYPE, Defaults.PREF_VIBRATION_TYPE) == "custom" && + Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) + Settings.PREF_VIBRATION_AMPLITUDE_SETTINGS else null, + if (prefs.getString(Settings.PREF_VIBRATION_TYPE, Defaults.PREF_VIBRATION_TYPE) != "off") Settings.PREF_VIBRATE_IN_DND_MODE else null, Settings.PREF_SOUND_ON, if (prefs.getBoolean(Settings.PREF_SOUND_ON, Defaults.PREF_SOUND_ON)) @@ -112,8 +116,16 @@ fun createPreferencesSettings(context: Context) = listOf( Setting(context, Settings.PREF_POPUP_ON, R.string.popup_on_keypress) { SwitchPreference(it, Defaults.PREF_POPUP_ON) { KeyboardSwitcher.getInstance().reloadKeyboard() } }, - Setting(context, Settings.PREF_VIBRATE_ON, R.string.vibrate_on_keypress) { - SwitchPreference(it, Defaults.PREF_VIBRATE_ON) + Setting(context, Settings.PREF_VIBRATION_TYPE, R.string.vibrate_on_keypress) { + ListPreference( + it, + listOf( + stringResource(R.string.prefs_keypress_vibration_mode_off) to "off", + stringResource(R.string.prefs_keypress_vibration_mode_system) to "system", + stringResource(R.string.prefs_keypress_vibration_mode_custom) to "custom" + ), + Defaults.PREF_VIBRATION_TYPE + ) }, Setting(context, Settings.PREF_VIBRATE_IN_DND_MODE, R.string.vibrate_in_dnd_mode) { SwitchPreference(it, Defaults.PREF_VIBRATE_IN_DND_MODE) @@ -192,8 +204,34 @@ fun createPreferencesSettings(context: Context) = listOf( if (it < 0) stringResource(R.string.settings_system_default) else stringResource(R.string.abbreviation_unit_milliseconds, it.toString()) }, - range = -1f..100f, - onValueChanged = { it?.let { AudioAndHapticFeedbackManager.getInstance().vibrate(it.toLong()) } } + range = 0f..100f, + onValueChanged = { + it?.let { + AudioAndHapticFeedbackManager.getInstance().vibrate( + it.toLong(), + Settings.getInstance().current.mKeypressVibrationAmplitude + ) + } + } + ) + }, + Setting(context, Settings.PREF_VIBRATION_AMPLITUDE_SETTINGS, R.string.prefs_keypress_vibration_amplitude_settings) { setting -> + SliderPreference( + name = setting.title, + key = setting.key, + default = Defaults.PREF_VIBRATION_AMPLITUDE_SETTINGS, + description = { + if (it == 255) stringResource(R.string.settings_system_default) + else it.toString() + }, + range = 0f..255f, + onValueChanged = { + it?.let { + AudioAndHapticFeedbackManager.getInstance().vibrate( + Settings.getInstance().current.mKeypressVibrationDuration.toLong(), it.toInt() + ) + } + } ) }, Setting(context, Settings.PREF_KEYPRESS_SOUND_VOLUME, R.string.prefs_keypress_sound_volume_settings) { setting -> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6918a79aa3..c13da06254 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -546,8 +546,13 @@ language, hence "No language". --> Day Night + Off + System + Custom Keypress vibration duration + + Keypress vibration amplitude Keypress sound volume From e666bccea8172cf822b066936611c44fd1c96d0a Mon Sep 17 00:00:00 2001 From: "Arthur K." Date: Wed, 10 Dec 2025 13:17:54 +0300 Subject: [PATCH 2/4] chore: minor refinements --- .../helium314/keyboard/latin/AppUpgrade.kt | 14 ++++++++++ .../latin/AudioAndHapticFeedbackManager.java | 28 +++++++++++++++++-- .../keyboard/latin/settings/Defaults.kt | 8 ++++-- .../keyboard/latin/settings/Settings.java | 22 ++------------- .../latin/settings/SettingsValues.java | 3 +- .../settings/screens/PreferencesScreen.kt | 13 +++++---- app/src/main/res/values/strings.xml | 4 +-- 7 files changed, 59 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/AppUpgrade.kt b/app/src/main/java/helium314/keyboard/latin/AppUpgrade.kt index 1310c7baff..d55ffca842 100644 --- a/app/src/main/java/helium314/keyboard/latin/AppUpgrade.kt +++ b/app/src/main/java/helium314/keyboard/latin/AppUpgrade.kt @@ -2,6 +2,7 @@ package helium314.keyboard.latin import android.annotation.SuppressLint import android.content.Context +import android.content.SharedPreferences import androidx.core.content.edit import helium314.keyboard.compat.isDeviceLocked import helium314.keyboard.compat.isUserLocked @@ -598,6 +599,19 @@ object AppUpgrade { !prefs.getBoolean(Settings.PREF_BIGRAM_PREDICTIONS, Defaults.PREF_BIGRAM_PREDICTIONS)) } } + if (prefs.contains(Settings.PREF_VIBRATE_ON)) { + prefs.edit { + if (prefs.getBoolean(Settings.PREF_VIBRATE_ON, false)) + if (prefs.getInt(Settings.PREF_VIBRATION_DURATION_SETTINGS, Defaults.PREF_VIBRATION_DURATION_SETTINGS) == -1) { + putString(Settings.PREF_VIBRATION_TYPE, AudioAndHapticFeedbackManager.VibrationType.SYSTEM.value) + putInt(Settings.PREF_VIBRATION_DURATION_SETTINGS, Defaults.PREF_VIBRATION_DURATION_SETTINGS) + } + else + putString(Settings.PREF_VIBRATION_TYPE, AudioAndHapticFeedbackManager.VibrationType.CUSTOM.value) + else putString(Settings.PREF_VIBRATION_TYPE, AudioAndHapticFeedbackManager.VibrationType.OFF.value) + remove(Settings.PREF_VIBRATE_ON) + } + } upgradeToolbarPrefs(prefs) LayoutUtilsCustom.onLayoutFileChanged() // just to be sure prefs.edit { putInt(Settings.PREF_VERSION_CODE, BuildConfig.VERSION_CODE) } diff --git a/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java b/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java index 7c2cdecd77..a34473a46b 100644 --- a/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java +++ b/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java @@ -41,6 +41,30 @@ public static AudioAndHapticFeedbackManager getInstance() { return sInstance; } + public enum VibrationType { + OFF("off"), + SYSTEM("system"), + CUSTOM("custom"); + + private final String value; + + VibrationType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public static VibrationType fromString(String value) { + try { + return VibrationType.valueOf(value.toUpperCase()); + } catch (IllegalArgumentException e) { + return VibrationType.OFF; + } + } + }; + private AudioAndHapticFeedbackManager() { // Intentional empty constructor for singleton. } @@ -112,9 +136,9 @@ public void performHapticFeedback(final View viewToPerformHapticFeedbackOn, fina // Avoid surprises with the handling of HapticFeedbackConstants.NO_HAPTICS return; } - if (mSettingsValues.mVibrationType.equals("custom") && hapticEvent.allowCustomDuration) { + if (mSettingsValues.mVibrationType == VibrationType.CUSTOM && hapticEvent.allowCustomDuration) { vibrate(mSettingsValues.mKeypressVibrationDuration, mSettingsValues.mKeypressVibrationAmplitude); - } else if (!mSettingsValues.mVibrationType.equals("off") && viewToPerformHapticFeedbackOn != null) { + } else if (mSettingsValues.mVibrationType != VibrationType.OFF && viewToPerformHapticFeedbackOn != null) { viewToPerformHapticFeedbackOn.performHapticFeedback( hapticEvent.feedbackConstant, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt index 99a2a9b562..684880dad8 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt @@ -6,6 +6,7 @@ import android.os.Build import android.util.TypedValue import android.view.Gravity import helium314.keyboard.keyboard.KeyboardTheme +import helium314.keyboard.latin.AudioAndHapticFeedbackManager import helium314.keyboard.latin.BuildConfig import helium314.keyboard.latin.common.Constants.Separators import helium314.keyboard.latin.common.Constants.Subtype.ExtraValue @@ -51,7 +52,8 @@ object Defaults { const val PREF_CUSTOM_ICON_NAMES = "" const val PREF_TOOLBAR_CUSTOM_KEY_CODES = "" const val PREF_AUTO_CAP = true - const val PREF_VIBRATION_TYPE = "off" + @JvmField + val PREF_VIBRATION_TYPE: String = AudioAndHapticFeedbackManager.VibrationType.OFF.value const val PREF_VIBRATE_IN_DND_MODE = false const val PREF_SOUND_ON = false const val PREF_SUGGEST_EMOJIS = true @@ -105,8 +107,8 @@ object Defaults { const val PREF_SUGGEST_PUNCTUATION = false const val PREF_SUGGEST_CLIPBOARD_CONTENT = true const val PREF_GESTURE_INPUT = true - const val PREF_VIBRATION_DURATION_SETTINGS = 10 - const val PREF_VIBRATION_AMPLITUDE_SETTINGS = 255 + const val PREF_VIBRATION_DURATION_SETTINGS = 1 + const val PREF_VIBRATION_AMPLITUDE_SETTINGS = 128 const val PREF_KEYPRESS_SOUND_VOLUME = -0.01f const val PREF_KEY_LONGPRESS_TIMEOUT = 300 const val PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY = true diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java index d9c75fc9df..ece469e6a3 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java @@ -234,22 +234,6 @@ private void onCreate(final Context context) { mContext = context; mPrefs = KtxKt.prefs(context); mPrefs.registerOnSharedPreferenceChangeListener(this); - migrateLegacyPreferences(); - } - - private void migrateLegacyPreferences() { - final var prefsEditor = mPrefs.edit(); - if (mPrefs.contains(Settings.PREF_VIBRATE_ON)) { - if (mPrefs.getBoolean(Settings.PREF_VIBRATE_ON, false)) - prefsEditor.putString(PREF_VIBRATION_TYPE, - mPrefs.getInt(Settings.PREF_VIBRATION_DURATION_SETTINGS, Defaults.PREF_VIBRATION_DURATION_SETTINGS) == -1 - ? "system" - : "custom"); - else - prefsEditor.putString(PREF_VIBRATION_TYPE, "off"); - prefsEditor.remove(Settings.PREF_VIBRATE_ON); - } - prefsEditor.apply(); } public void onDestroy() { @@ -318,10 +302,10 @@ public static int readScreenMetrics(final Resources res) { return res.getInteger(R.integer.config_screen_metrics); } - public static String readVibrationType(final SharedPreferences prefs) { + public static AudioAndHapticFeedbackManager.VibrationType readVibrationType(final SharedPreferences prefs) { return AudioAndHapticFeedbackManager.getInstance().hasVibrator() - ? prefs.getString(PREF_VIBRATION_TYPE, Defaults.PREF_VIBRATION_TYPE) - : "off"; + ? AudioAndHapticFeedbackManager.VibrationType.fromString(prefs.getString(PREF_VIBRATION_TYPE, Defaults.PREF_VIBRATION_TYPE)) + : AudioAndHapticFeedbackManager.VibrationType.OFF; } public void toggleAutoCorrect() { diff --git a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java index 261ede9dae..096e71ea84 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java @@ -21,6 +21,7 @@ import helium314.keyboard.compat.ConfigurationCompatKt; import helium314.keyboard.keyboard.KeyboardTheme; import helium314.keyboard.keyboard.internal.keyboard_parser.LocaleKeyboardInfosKt; +import helium314.keyboard.latin.AudioAndHapticFeedbackManager; import helium314.keyboard.latin.InputAttributes; import helium314.keyboard.latin.R; import helium314.keyboard.latin.RichInputMethodManager; @@ -51,7 +52,7 @@ public class SettingsValues { public final int mDisplayOrientation; // From preferences public final boolean mAutoCap; - public final String mVibrationType; + public final AudioAndHapticFeedbackManager.VibrationType mVibrationType; public final boolean mVibrateInDndMode; public final boolean mSoundOn; public final boolean mSuggestEmojis; diff --git a/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt index f296bd0418..b9f48d4653 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt @@ -43,6 +43,7 @@ fun PreferencesScreen( if ((b?.value ?: 0) < 0) Log.v("irrelevant", "stupid way to trigger recomposition on preference change") val clipboardHistoryEnabled = prefs.getBoolean(Settings.PREF_ENABLE_CLIPBOARD_HISTORY, Defaults.PREF_ENABLE_CLIPBOARD_HISTORY) + val vibrationType = Settings.readVibrationType(prefs); val items = listOf( R.string.settings_category_input, Settings.PREF_SHOW_HINTS, @@ -54,12 +55,12 @@ fun PreferencesScreen( Settings.PREF_POPUP_ON, if (AudioAndHapticFeedbackManager.getInstance().hasVibrator()) Settings.PREF_VIBRATION_TYPE else null, - if (prefs.getString(Settings.PREF_VIBRATION_TYPE, Defaults.PREF_VIBRATION_TYPE) == "custom") + if (vibrationType == AudioAndHapticFeedbackManager.VibrationType.CUSTOM) Settings.PREF_VIBRATION_DURATION_SETTINGS else null, - if (prefs.getString(Settings.PREF_VIBRATION_TYPE, Defaults.PREF_VIBRATION_TYPE) == "custom" && + if (vibrationType == AudioAndHapticFeedbackManager.VibrationType.CUSTOM && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) Settings.PREF_VIBRATION_AMPLITUDE_SETTINGS else null, - if (prefs.getString(Settings.PREF_VIBRATION_TYPE, Defaults.PREF_VIBRATION_TYPE) != "off") + if (vibrationType != AudioAndHapticFeedbackManager.VibrationType.OFF) Settings.PREF_VIBRATE_IN_DND_MODE else null, Settings.PREF_SOUND_ON, if (prefs.getBoolean(Settings.PREF_SOUND_ON, Defaults.PREF_SOUND_ON)) @@ -120,9 +121,9 @@ fun createPreferencesSettings(context: Context) = listOf( ListPreference( it, listOf( - stringResource(R.string.prefs_keypress_vibration_mode_off) to "off", - stringResource(R.string.prefs_keypress_vibration_mode_system) to "system", - stringResource(R.string.prefs_keypress_vibration_mode_custom) to "custom" + stringResource(R.string.prefs_keypress_vibration_mode_off) to AudioAndHapticFeedbackManager.VibrationType.OFF.value, + stringResource(R.string.prefs_keypress_vibration_mode_system) to AudioAndHapticFeedbackManager.VibrationType.SYSTEM.value, + stringResource(R.string.prefs_keypress_vibration_mode_custom) to AudioAndHapticFeedbackManager.VibrationType.CUSTOM.value, ), Defaults.PREF_VIBRATION_TYPE ) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c13da06254..02e036f6fb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -547,12 +547,12 @@ language, hence "No language". --> Night Off - System + System default Custom Keypress vibration duration - Keypress vibration amplitude + Keypress vibration intensity Keypress sound volume From 8f8c34f9c87532b6d01be087a0cf42a621454237 Mon Sep 17 00:00:00 2001 From: "Arthur K." Date: Thu, 11 Dec 2025 06:30:54 +0300 Subject: [PATCH 3/4] chore: remove redundant `VibrationType.fromString()` --- .../keyboard/latin/AudioAndHapticFeedbackManager.java | 10 +--------- .../helium314/keyboard/latin/settings/Settings.java | 3 ++- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java b/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java index a34473a46b..284f4367aa 100644 --- a/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java +++ b/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java @@ -55,15 +55,7 @@ public enum VibrationType { public String getValue() { return value; } - - public static VibrationType fromString(String value) { - try { - return VibrationType.valueOf(value.toUpperCase()); - } catch (IllegalArgumentException e) { - return VibrationType.OFF; - } - } - }; + } private AudioAndHapticFeedbackManager() { // Intentional empty constructor for singleton. diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java index ece469e6a3..0b0523bbc2 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java @@ -304,7 +304,8 @@ public static int readScreenMetrics(final Resources res) { public static AudioAndHapticFeedbackManager.VibrationType readVibrationType(final SharedPreferences prefs) { return AudioAndHapticFeedbackManager.getInstance().hasVibrator() - ? AudioAndHapticFeedbackManager.VibrationType.fromString(prefs.getString(PREF_VIBRATION_TYPE, Defaults.PREF_VIBRATION_TYPE)) + ? AudioAndHapticFeedbackManager.VibrationType.valueOf( + prefs.getString(PREF_VIBRATION_TYPE, Defaults.PREF_VIBRATION_TYPE).toUpperCase()) : AudioAndHapticFeedbackManager.VibrationType.OFF; } From ea657458a79baf1c05d63e278712bdd1c7084b62 Mon Sep 17 00:00:00 2001 From: "Arthur K." Date: Fri, 12 Dec 2025 11:45:53 +0300 Subject: [PATCH 4/4] chore: remove explicit `value` from `VibrationType` --- .../java/helium314/keyboard/latin/AppUpgrade.kt | 6 +++--- .../latin/AudioAndHapticFeedbackManager.java | 16 +++------------- .../java/helium314/keyboard/latin/LatinIME.java | 11 ++++++----- .../keyboard/latin/settings/Defaults.kt | 2 +- .../keyboard/latin/settings/Settings.java | 2 +- .../settings/screens/PreferencesScreen.kt | 6 +++--- 6 files changed, 17 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/AppUpgrade.kt b/app/src/main/java/helium314/keyboard/latin/AppUpgrade.kt index d55ffca842..1ddc341676 100644 --- a/app/src/main/java/helium314/keyboard/latin/AppUpgrade.kt +++ b/app/src/main/java/helium314/keyboard/latin/AppUpgrade.kt @@ -603,12 +603,12 @@ object AppUpgrade { prefs.edit { if (prefs.getBoolean(Settings.PREF_VIBRATE_ON, false)) if (prefs.getInt(Settings.PREF_VIBRATION_DURATION_SETTINGS, Defaults.PREF_VIBRATION_DURATION_SETTINGS) == -1) { - putString(Settings.PREF_VIBRATION_TYPE, AudioAndHapticFeedbackManager.VibrationType.SYSTEM.value) + putString(Settings.PREF_VIBRATION_TYPE, AudioAndHapticFeedbackManager.VibrationType.SYSTEM.toString()) putInt(Settings.PREF_VIBRATION_DURATION_SETTINGS, Defaults.PREF_VIBRATION_DURATION_SETTINGS) } else - putString(Settings.PREF_VIBRATION_TYPE, AudioAndHapticFeedbackManager.VibrationType.CUSTOM.value) - else putString(Settings.PREF_VIBRATION_TYPE, AudioAndHapticFeedbackManager.VibrationType.OFF.value) + putString(Settings.PREF_VIBRATION_TYPE, AudioAndHapticFeedbackManager.VibrationType.CUSTOM.toString()) + else putString(Settings.PREF_VIBRATION_TYPE, AudioAndHapticFeedbackManager.VibrationType.OFF.toString()) remove(Settings.PREF_VIBRATE_ON) } } diff --git a/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java b/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java index 284f4367aa..b932eb1e04 100644 --- a/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java +++ b/app/src/main/java/helium314/keyboard/latin/AudioAndHapticFeedbackManager.java @@ -42,19 +42,9 @@ public static AudioAndHapticFeedbackManager getInstance() { } public enum VibrationType { - OFF("off"), - SYSTEM("system"), - CUSTOM("custom"); - - private final String value; - - VibrationType(String value) { - this.value = value; - } - - public String getValue() { - return value; - } + OFF, + SYSTEM, + CUSTOM; } private AudioAndHapticFeedbackManager() { diff --git a/app/src/main/java/helium314/keyboard/latin/LatinIME.java b/app/src/main/java/helium314/keyboard/latin/LatinIME.java index cfc9b3603c..338a81901b 100644 --- a/app/src/main/java/helium314/keyboard/latin/LatinIME.java +++ b/app/src/main/java/helium314/keyboard/latin/LatinIME.java @@ -1616,16 +1616,17 @@ public void hapticAndAudioFeedback(final int code, final int repeatCount, } // TODO: Use event time that the last feedback has been generated instead of relying on // a repeat count to thin out feedback. - if (repeatCount % PERIOD_FOR_AUDIO_AND_HAPTIC_FEEDBACK_IN_KEY_REPEAT == 0) { - return; - } + +// if (repeatCount % PERIOD_FOR_AUDIO_AND_HAPTIC_FEEDBACK_IN_KEY_REPEAT == 0) { +// return; +// } } final AudioAndHapticFeedbackManager feedbackManager = AudioAndHapticFeedbackManager.getInstance(); - if (repeatCount == 0) { +// if (repeatCount == 0) { // TODO: Reconsider how to perform haptic feedback when repeating key. feedbackManager.performHapticFeedback(keyboardView, hapticEvent); - } +// } feedbackManager.performAudioFeedback(code, hapticEvent); } diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt index 684880dad8..6dde33502d 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt @@ -53,7 +53,7 @@ object Defaults { const val PREF_TOOLBAR_CUSTOM_KEY_CODES = "" const val PREF_AUTO_CAP = true @JvmField - val PREF_VIBRATION_TYPE: String = AudioAndHapticFeedbackManager.VibrationType.OFF.value + val PREF_VIBRATION_TYPE: String = AudioAndHapticFeedbackManager.VibrationType.OFF.toString() const val PREF_VIBRATE_IN_DND_MODE = false const val PREF_SOUND_ON = false const val PREF_SUGGEST_EMOJIS = true diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java index 0b0523bbc2..d23c672d81 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java @@ -305,7 +305,7 @@ public static int readScreenMetrics(final Resources res) { public static AudioAndHapticFeedbackManager.VibrationType readVibrationType(final SharedPreferences prefs) { return AudioAndHapticFeedbackManager.getInstance().hasVibrator() ? AudioAndHapticFeedbackManager.VibrationType.valueOf( - prefs.getString(PREF_VIBRATION_TYPE, Defaults.PREF_VIBRATION_TYPE).toUpperCase()) + prefs.getString(PREF_VIBRATION_TYPE, Defaults.PREF_VIBRATION_TYPE)) : AudioAndHapticFeedbackManager.VibrationType.OFF; } diff --git a/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt index b9f48d4653..995aca0a03 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt @@ -121,9 +121,9 @@ fun createPreferencesSettings(context: Context) = listOf( ListPreference( it, listOf( - stringResource(R.string.prefs_keypress_vibration_mode_off) to AudioAndHapticFeedbackManager.VibrationType.OFF.value, - stringResource(R.string.prefs_keypress_vibration_mode_system) to AudioAndHapticFeedbackManager.VibrationType.SYSTEM.value, - stringResource(R.string.prefs_keypress_vibration_mode_custom) to AudioAndHapticFeedbackManager.VibrationType.CUSTOM.value, + stringResource(R.string.prefs_keypress_vibration_mode_off) to AudioAndHapticFeedbackManager.VibrationType.OFF.toString(), + stringResource(R.string.prefs_keypress_vibration_mode_system) to AudioAndHapticFeedbackManager.VibrationType.SYSTEM.toString(), + stringResource(R.string.prefs_keypress_vibration_mode_custom) to AudioAndHapticFeedbackManager.VibrationType.CUSTOM.toString(), ), Defaults.PREF_VIBRATION_TYPE )