From 25c0e4af431d7b6170858db4442cee8d10b324c3 Mon Sep 17 00:00:00 2001 From: cketti Date: Wed, 9 Mar 2022 21:54:30 +0100 Subject: [PATCH] Extract vibration settings to separate class `NotificationVibration` --- .../fsck/k9/AccountPreferenceSerializer.kt | 18 +++--- .../java/com/fsck/k9/NotificationSettings.kt | 59 +----------------- .../java/com/fsck/k9/NotificationVibration.kt | 62 +++++++++++++++++++ .../BaseNotificationDataCreator.kt | 2 +- .../NotificationChannelManager.kt | 8 +-- .../BaseNotificationDataCreatorTest.kt | 12 +++- .../account/AccountSettingsDataStore.kt | 21 ++++--- .../account/VibrationDialogFragment.kt | 4 +- .../settings/account/VibrationPreference.kt | 4 +- 9 files changed, 104 insertions(+), 86 deletions(-) create mode 100644 app/core/src/main/java/com/fsck/k9/NotificationVibration.kt diff --git a/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt b/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt index 12f725b17..c881cb312 100644 --- a/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt +++ b/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt @@ -142,9 +142,11 @@ class AccountPreferenceSerializer( isRingEnabled = storage.getBoolean("$accountUuid.ring", true), ringtone = storage.getString("$accountUuid.ringtone", DEFAULT_RINGTONE_URI), light = getEnumStringPref(storage, "$accountUuid.notificationLight", NotificationLight.Disabled), - isVibrateEnabled = storage.getBoolean("$accountUuid.vibrate", false), - vibratePattern = VibratePattern.deserialize(storage.getInt("$accountUuid.vibratePattern", 0)), - vibrateTimes = storage.getInt("$accountUuid.vibrateTimes", 5) + vibration = NotificationVibration( + isEnabled = storage.getBoolean("$accountUuid.vibrate", false), + pattern = VibratePattern.deserialize(storage.getInt("$accountUuid.vibratePattern", 0)), + repeatCount = storage.getInt("$accountUuid.vibrateTimes", 5) + ) ) } @@ -322,9 +324,9 @@ class AccountPreferenceSerializer( editor.putBoolean("$accountUuid.markMessageAsReadOnDelete", isMarkMessageAsReadOnDelete) editor.putBoolean("$accountUuid.alwaysShowCcBcc", isAlwaysShowCcBcc) - editor.putBoolean("$accountUuid.vibrate", notificationSettings.isVibrateEnabled) - editor.putInt("$accountUuid.vibratePattern", notificationSettings.vibratePattern.serialize()) - editor.putInt("$accountUuid.vibrateTimes", notificationSettings.vibrateTimes) + editor.putBoolean("$accountUuid.vibrate", notificationSettings.vibration.isEnabled) + editor.putInt("$accountUuid.vibratePattern", notificationSettings.vibration.pattern.serialize()) + editor.putInt("$accountUuid.vibrateTimes", notificationSettings.vibration.repeatCount) editor.putBoolean("$accountUuid.ring", notificationSettings.isRingEnabled) editor.putString("$accountUuid.ringtone", notificationSettings.ringtone) editor.putString("$accountUuid.notificationLight", notificationSettings.light.name) @@ -607,9 +609,7 @@ class AccountPreferenceSerializer( isRingEnabled = true, ringtone = DEFAULT_RINGTONE_URI, light = NotificationLight.Disabled, - isVibrateEnabled = false, - vibratePattern = VibratePattern.Default, - vibrateTimes = 5 + vibration = NotificationVibration.DEFAULT ) } diff --git a/app/core/src/main/java/com/fsck/k9/NotificationSettings.kt b/app/core/src/main/java/com/fsck/k9/NotificationSettings.kt index b94eec51b..5852e4b14 100644 --- a/app/core/src/main/java/com/fsck/k9/NotificationSettings.kt +++ b/app/core/src/main/java/com/fsck/k9/NotificationSettings.kt @@ -7,60 +7,5 @@ data class NotificationSettings( val isRingEnabled: Boolean = false, val ringtone: String? = null, val light: NotificationLight = NotificationLight.Disabled, - val isVibrateEnabled: Boolean = false, - val vibratePattern: VibratePattern = VibratePattern.Default, - val vibrateTimes: Int = 0 -) { - val vibrationPattern: LongArray - get() = getVibrationPattern(vibratePattern, vibrateTimes) - - companion object { - fun getVibrationPattern(vibratePattern: VibratePattern, times: Int): LongArray { - val selectedPattern = vibratePattern.vibrationPattern - val repeatedPattern = LongArray(selectedPattern.size * times) - for (n in 0 until times) { - System.arraycopy(selectedPattern, 0, repeatedPattern, n * selectedPattern.size, selectedPattern.size) - } - - // Do not wait before starting the vibration pattern. - repeatedPattern[0] = 0 - - return repeatedPattern - } - } -} - -enum class VibratePattern( - /** - * These are "off, on" patterns, specified in milliseconds. - */ - val vibrationPattern: LongArray -) { - Default(vibrationPattern = longArrayOf(300, 200)), - Pattern1(vibrationPattern = longArrayOf(100, 200)), - Pattern2(vibrationPattern = longArrayOf(100, 500)), - Pattern3(vibrationPattern = longArrayOf(200, 200)), - Pattern4(vibrationPattern = longArrayOf(200, 500)), - Pattern5(vibrationPattern = longArrayOf(500, 500)); - - fun serialize(): Int = when (this) { - Default -> 0 - Pattern1 -> 1 - Pattern2 -> 2 - Pattern3 -> 3 - Pattern4 -> 4 - Pattern5 -> 5 - } - - companion object { - fun deserialize(value: Int): VibratePattern = when (value) { - 0 -> Default - 1 -> Pattern1 - 2 -> Pattern2 - 3 -> Pattern3 - 4 -> Pattern4 - 5 -> Pattern5 - else -> error("Unknown VibratePattern value: $value") - } - } -} + val vibration: NotificationVibration = NotificationVibration.DEFAULT +) diff --git a/app/core/src/main/java/com/fsck/k9/NotificationVibration.kt b/app/core/src/main/java/com/fsck/k9/NotificationVibration.kt new file mode 100644 index 000000000..0986baeff --- /dev/null +++ b/app/core/src/main/java/com/fsck/k9/NotificationVibration.kt @@ -0,0 +1,62 @@ +package com.fsck.k9 + +data class NotificationVibration( + val isEnabled: Boolean, + val pattern: VibratePattern, + val repeatCount: Int +) { + val systemPattern: LongArray + get() = getSystemPattern(pattern, repeatCount) + + companion object { + val DEFAULT = NotificationVibration(isEnabled = false, pattern = VibratePattern.Default, repeatCount = 5) + + fun getSystemPattern(vibratePattern: VibratePattern, repeatCount: Int): LongArray { + val selectedPattern = vibratePattern.vibrationPattern + val repeatedPattern = LongArray(selectedPattern.size * repeatCount) + for (n in 0 until repeatCount) { + System.arraycopy(selectedPattern, 0, repeatedPattern, n * selectedPattern.size, selectedPattern.size) + } + + // Do not wait before starting the vibration pattern. + repeatedPattern[0] = 0 + + return repeatedPattern + } + } +} + +enum class VibratePattern( + /** + * These are "off, on" patterns, specified in milliseconds. + */ + val vibrationPattern: LongArray +) { + Default(vibrationPattern = longArrayOf(300, 200)), + Pattern1(vibrationPattern = longArrayOf(100, 200)), + Pattern2(vibrationPattern = longArrayOf(100, 500)), + Pattern3(vibrationPattern = longArrayOf(200, 200)), + Pattern4(vibrationPattern = longArrayOf(200, 500)), + Pattern5(vibrationPattern = longArrayOf(500, 500)); + + fun serialize(): Int = when (this) { + Default -> 0 + Pattern1 -> 1 + Pattern2 -> 2 + Pattern3 -> 3 + Pattern4 -> 4 + Pattern5 -> 5 + } + + companion object { + fun deserialize(value: Int): VibratePattern = when (value) { + 0 -> Default + 1 -> Pattern1 + 2 -> Pattern2 + 3 -> Pattern3 + 4 -> Pattern4 + 5 -> Pattern5 + else -> error("Unknown VibratePattern value: $value") + } + } +} diff --git a/app/core/src/main/java/com/fsck/k9/notification/BaseNotificationDataCreator.kt b/app/core/src/main/java/com/fsck/k9/notification/BaseNotificationDataCreator.kt index b07b78276..9fe65d367 100644 --- a/app/core/src/main/java/com/fsck/k9/notification/BaseNotificationDataCreator.kt +++ b/app/core/src/main/java/com/fsck/k9/notification/BaseNotificationDataCreator.kt @@ -41,7 +41,7 @@ internal class BaseNotificationDataCreator { private fun createNotificationAppearance(account: Account): NotificationAppearance { return with(account.notificationSettings) { - val vibrationPattern = if (isVibrateEnabled) vibrationPattern else null + val vibrationPattern = vibration.systemPattern.takeIf { vibration.isEnabled } NotificationAppearance(ringtone, vibrationPattern, account.notificationSettings.light.toColor(account)) } } diff --git a/app/core/src/main/java/com/fsck/k9/notification/NotificationChannelManager.kt b/app/core/src/main/java/com/fsck/k9/notification/NotificationChannelManager.kt index 4970c4a41..a2349ed74 100644 --- a/app/core/src/main/java/com/fsck/k9/notification/NotificationChannelManager.kt +++ b/app/core/src/main/java/com/fsck/k9/notification/NotificationChannelManager.kt @@ -213,8 +213,8 @@ class NotificationChannelManager( val notificationSettings = account.notificationSettings return sound == notificationSettings.ringtoneUri && systemLight == notificationSettings.light && - shouldVibrate() == notificationSettings.isVibrateEnabled && - vibrationPattern.contentEquals(notificationSettings.vibrationPattern) + shouldVibrate() == notificationSettings.vibration.isEnabled && + vibrationPattern.contentEquals(notificationSettings.vibration.systemPattern) } @RequiresApi(Build.VERSION_CODES.O) @@ -244,8 +244,8 @@ class NotificationChannelManager( val isLightEnabled = notificationSettings.light != NotificationLight.Disabled enableLights(isLightEnabled) - vibrationPattern = notificationSettings.vibrationPattern - enableVibration(notificationSettings.isVibrateEnabled) + vibrationPattern = notificationSettings.vibration.systemPattern + enableVibration(notificationSettings.vibration.isEnabled) } private val Account.messagesNotificationChannelSuffix: String diff --git a/app/core/src/test/java/com/fsck/k9/notification/BaseNotificationDataCreatorTest.kt b/app/core/src/test/java/com/fsck/k9/notification/BaseNotificationDataCreatorTest.kt index f1520fc49..65dea9c1e 100644 --- a/app/core/src/test/java/com/fsck/k9/notification/BaseNotificationDataCreatorTest.kt +++ b/app/core/src/test/java/com/fsck/k9/notification/BaseNotificationDataCreatorTest.kt @@ -5,7 +5,7 @@ import com.fsck.k9.Identity import com.fsck.k9.K9 import com.fsck.k9.K9.LockScreenNotificationVisibility import com.fsck.k9.NotificationLight -import com.fsck.k9.NotificationSettings +import com.fsck.k9.NotificationVibration import com.fsck.k9.VibratePattern import com.google.common.truth.Truth.assertThat import org.junit.Test @@ -151,14 +151,20 @@ class BaseNotificationDataCreatorTest { @Test fun `vibration pattern`() { account.updateNotificationSettings { - it.copy(isVibrateEnabled = true, vibratePattern = VibratePattern.Pattern3, vibrateTimes = 2) + it.copy( + vibration = NotificationVibration( + isEnabled = true, + pattern = VibratePattern.Pattern3, + repeatCount = 2 + ) + ) } val notificationData = createNotificationData() val result = notificationDataCreator.createBaseNotificationData(notificationData) assertThat(result.appearance.vibrationPattern).isEqualTo( - NotificationSettings.getVibrationPattern(VibratePattern.Pattern3, 2) + NotificationVibration.getSystemPattern(VibratePattern.Pattern3, 2) ) } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsDataStore.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsDataStore.kt index 250964d0a..9672c8936 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsDataStore.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsDataStore.kt @@ -4,6 +4,7 @@ import androidx.preference.PreferenceDataStore import com.fsck.k9.Account import com.fsck.k9.Account.SpecialFolderSelection import com.fsck.k9.NotificationLight +import com.fsck.k9.NotificationVibration import com.fsck.k9.Preferences import com.fsck.k9.job.K9JobManager import com.fsck.k9.notification.NotificationChannelManager @@ -263,20 +264,24 @@ class AccountSettingsDataStore( } private fun getCombinedVibrationValue(): String { - return VibrationPreference.encode( - isVibrationEnabled = account.notificationSettings.isVibrateEnabled, - vibratePattern = account.notificationSettings.vibratePattern, - vibrationTimes = account.notificationSettings.vibrateTimes - ) + return with(account.notificationSettings.vibration) { + VibrationPreference.encode( + isVibrationEnabled = isEnabled, + vibratePattern = pattern, + vibrationTimes = repeatCount + ) + } } private fun setCombinedVibrationValue(value: String) { val (isVibrationEnabled, vibrationPattern, vibrationTimes) = VibrationPreference.decode(value) account.updateNotificationSettings { notificationSettings -> notificationSettings.copy( - isVibrateEnabled = isVibrationEnabled, - vibratePattern = vibrationPattern, - vibrateTimes = vibrationTimes, + vibration = NotificationVibration( + isEnabled = isVibrationEnabled, + pattern = vibrationPattern, + repeatCount = vibrationTimes, + ) ) } notificationSettingsChanged = true diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/VibrationDialogFragment.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/VibrationDialogFragment.kt index d978d2c3b..4ecedb8ba 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/VibrationDialogFragment.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/VibrationDialogFragment.kt @@ -16,7 +16,7 @@ import androidx.appcompat.app.AlertDialog import androidx.appcompat.widget.SwitchCompat import androidx.core.content.getSystemService import androidx.preference.PreferenceDialogFragmentCompat -import com.fsck.k9.NotificationSettings +import com.fsck.k9.NotificationVibration import com.fsck.k9.VibratePattern import com.fsck.k9.ui.R import com.fsck.k9.ui.getEnum @@ -81,7 +81,7 @@ class VibrationDialogFragment : PreferenceDialogFragmentCompat() { private fun playVibration() { val vibratePattern = adapter.vibratePattern val vibrationTimes = adapter.vibrationTimes - val vibrationPattern = NotificationSettings.getVibrationPattern(vibratePattern, vibrationTimes) + val vibrationPattern = NotificationVibration.getSystemPattern(vibratePattern, vibrationTimes) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val vibrationEffect = VibrationEffect.createWaveform(vibrationPattern, -1) diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/VibrationPreference.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/VibrationPreference.kt index 825f75a85..cc656a010 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/VibrationPreference.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/VibrationPreference.kt @@ -5,7 +5,7 @@ import android.content.Context import android.util.AttributeSet import androidx.core.content.res.TypedArrayUtils import androidx.preference.ListPreference -import com.fsck.k9.NotificationSettings +import com.fsck.k9.NotificationVibration import com.fsck.k9.VibratePattern import com.fsck.k9.ui.R import com.takisoft.preferencex.PreferenceFragmentCompat @@ -75,7 +75,7 @@ constructor( VibratePattern.deserialize(serializedVibratePattern) } .firstOrNull { vibratePattern -> - val testPattern = NotificationSettings.getVibrationPattern(vibratePattern, vibrationTimes) + val testPattern = NotificationVibration.getSystemPattern(vibratePattern, vibrationTimes) testPattern.contentEquals(combinedPatternArray) } ?: DEFAULT_VIBRATE_PATTERN