Loading src/com/android/settings/accessibility/VibrationIntensitySettingsStore.kt +11 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.settings.accessibility import android.content.Context import android.os.VibrationAttributes.Usage import android.os.Vibrator import android.provider.Settings import com.android.settings.R import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.KeyValueStoreDelegate Loading @@ -33,11 +34,20 @@ class VibrationIntensitySettingsStore( private val supportedIntensityLevels: Int = context.getSupportedVibrationIntensityLevels(), ) : KeyValueStoreDelegate { /** Returns true if the settings key should be enabled, false otherwise. */ fun isPreferenceEnabled() = keyValueStoreDelegate.getBoolean(Settings.System.VIBRATE_ON) ?: true override fun <T : Any> getDefaultValue(key: String, valueType: Class<T>) = intensityToValue(valueType, defaultIntensity) override fun <T : Any> getValue(key: String, valueType: Class<T>) = if (isPreferenceEnabled()) { intensityToValue(valueType, keyValueStoreDelegate.getInt(key) ?: defaultIntensity) } else { // Preference must show intensity off when disabled, but value stored must be preserved. intensityToValue(valueType, Vibrator.VIBRATION_INTENSITY_OFF) } override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) = keyValueStoreDelegate.setInt(key, value?.let { valueToIntensity(valueType, it) }) Loading src/com/android/settings/accessibility/VibrationIntensitySliderPreference.kt +20 −2 Original line number Diff line number Diff line Loading @@ -34,6 +34,12 @@ import kotlin.math.min * * This implementation uses VibrationIntensitySettingsStore to save the vibration intensity value, * also playing a haptic preview on slider changes. * * This preference observes the state of the VibrationMainSwitchPreference in this fragment, * disabling and displaying intensity OFF this slider when the main switch is unchecked. This "off" * state should not be persisted, as the original user settings value must be preserved and restored * once the main switch is turned back on. This behavior reflects the actual system behavior that * restricts all vibrations when the main switch is off. */ // LINT.IfChange open class VibrationIntensitySliderPreference( Loading @@ -43,6 +49,8 @@ open class VibrationIntensitySliderPreference( @StringRes override val summary: Int = 0, ) : IntRangeValuePreference, SliderPreferenceBinding, OnPreferenceChangeListener { private var storage: VibrationIntensitySettingsStore? = null override fun getMinValue(context: Context) = Vibrator.VIBRATION_INTENSITY_OFF override fun getMaxValue(context: Context) = Loading @@ -50,8 +58,15 @@ open class VibrationIntensitySliderPreference( override fun getIncrementStep(context: Context) = 1 override fun storage(context: Context): KeyValueStore = VibrationIntensitySettingsStore(context, vibrationUsage) override fun storage(context: Context): KeyValueStore { if (storage == null) { storage = VibrationIntensitySettingsStore(context, vibrationUsage) } return storage!! } override fun dependencies(context: Context) = arrayOf(VibrationMainSwitchPreference.KEY) @CallSuper override fun bind(preference: Preference, metadata: PreferenceMetadata) { Loading @@ -70,5 +85,8 @@ open class VibrationIntensitySliderPreference( } return true } @CallSuper override fun isEnabled(context: Context) = storage?.isPreferenceEnabled() ?: true } // LINT.ThenChange(VibrationIntensityPreferenceController.java) src/com/android/settings/accessibility/VibrationIntensitySwitchPreference.kt +19 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,12 @@ import com.android.settingslib.preference.SwitchPreferenceBinding * * This implementation uses VibrationIntensitySettingsStore to save the device default vibration * intensity value when the switch is turned on, also playing a haptic preview. * * This preference observes the state of the VibrationMainSwitchPreference in this fragment, * disabling and unchecking this switch when the main switch is unchecked. This "unchecked" state * should not be persisted, as the original user settings value must be preserved and restored once * the main switch is turned back on. This behavior reflects the actual system behavior that * restricts all vibrations when the main switch is off. */ // LINT.IfChange open class VibrationIntensitySwitchPreference( Loading @@ -42,8 +48,16 @@ open class VibrationIntensitySwitchPreference( OnPreferenceChangeListener, SwitchPreferenceBinding { override fun storage(context: Context): KeyValueStore = VibrationIntensitySettingsStore(context, vibrationUsage) private var storage: VibrationIntensitySettingsStore? = null override fun storage(context: Context): KeyValueStore { if (storage == null) { storage = VibrationIntensitySettingsStore(context, vibrationUsage) } return storage!! } override fun dependencies(context: Context) = arrayOf(VibrationMainSwitchPreference.KEY) @CallSuper override fun bind(preference: Preference, metadata: PreferenceMetadata) { Loading @@ -57,5 +71,8 @@ open class VibrationIntensitySwitchPreference( } return true } @CallSuper override fun isEnabled(context: Context) = storage?.isPreferenceEnabled() ?: true } // LINT.ThenChange(VibrationTogglePreferenceController.java) tests/robotests/src/com/android/settings/accessibility/VibrationIntensityScreenTest.kt +5 −5 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ import org.robolectric.annotation.Config @RunWith(AndroidJUnit4::class) @Config(shadows = [ShadowAudioManager::class]) class VibrationIntensityScreenTest : CatalystScreenTestCase() { private lateinit var mockVibrator: Vibrator private lateinit var vibratorMock: Vibrator private val resourcesSpy: Resources = spy((ApplicationProvider.getApplicationContext() as Context).resources) Loading @@ -50,7 +50,7 @@ class VibrationIntensityScreenTest : CatalystScreenTestCase() { object : ContextWrapper(ApplicationProvider.getApplicationContext()) { override fun getSystemService(name: String): Any? = when { name == VIBRATOR_SERVICE -> mockVibrator name == VIBRATOR_SERVICE -> vibratorMock else -> super.getSystemService(name) } Loading @@ -74,7 +74,7 @@ class VibrationIntensityScreenTest : CatalystScreenTestCase() { @Test fun isAvailable_noVibrator_unavailable() { mockVibrator = mock { on { hasVibrator() } doReturn false } vibratorMock = mock { on { hasVibrator() } doReturn false } resourcesSpy.stub { on { getInteger(R.integer.config_vibration_supported_intensity_levels) } doReturn 3 } Loading @@ -83,7 +83,7 @@ class VibrationIntensityScreenTest : CatalystScreenTestCase() { @Test fun isAvailable_hasVibratorAndSingleIntensityLevel_unavailable() { mockVibrator = mock { on { hasVibrator() } doReturn true } vibratorMock = mock { on { hasVibrator() } doReturn true } resourcesSpy.stub { on { getInteger(R.integer.config_vibration_supported_intensity_levels) } doReturn 1 } Loading @@ -92,7 +92,7 @@ class VibrationIntensityScreenTest : CatalystScreenTestCase() { @Test fun isAvailable_hasVibratorAndMultipleIntensityLevels_available() { mockVibrator = mock { on { hasVibrator() } doReturn true } vibratorMock = mock { on { hasVibrator() } doReturn true } resourcesSpy.stub { on { getInteger(R.integer.config_vibration_supported_intensity_levels) } doReturn 2 } Loading tests/robotests/src/com/android/settings/accessibility/VibrationIntensitySettingsStoreTest.kt +32 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,28 @@ class VibrationIntensitySettingsStoreTest { supportedIntensityLevels = SUPPORTED_INTENSITIES, ) @Test fun isPreferenceEnabled_returnsVibrateOnSettingOrTrue() { settingsStore.setBoolean(Settings.System.VIBRATE_ON, null) assertThat(store.isPreferenceEnabled()).isTrue() settingsStore.setBoolean(Settings.System.VIBRATE_ON, true) assertThat(store.isPreferenceEnabled()).isTrue() settingsStore.setBoolean(Settings.System.VIBRATE_ON, false) assertThat(store.isPreferenceEnabled()).isFalse() } @Test fun getValue_preferenceDisabledByMainSwitch_returnsIntensityOffAndPreservesValue() { settingsStore.setBoolean(Settings.System.VIBRATE_ON, false) setIntValue(Vibrator.VIBRATION_INTENSITY_HIGH) assertThat(settingsStore.getInt(KEY)).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH) assertThat(store.getBoolean(KEY)).isFalse() assertThat(store.getInt(KEY)).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF) } @Test fun getValue_valueNull_returnDefaultIntensity() { setIntValue(null) Loading Loading @@ -98,6 +120,16 @@ class VibrationIntensitySettingsStoreTest { assertThat(store.getInt(KEY)).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF) } @Test fun getValue_preferenceDisabled_returnOffAndPreservesValue() { settingsStore.setBoolean(Settings.System.VIBRATE_ON, false) setBooleanValue(true) assertThat(settingsStore.getInt(KEY)).isEqualTo(DEFAULT_INTENSITY) assertThat(store.getBoolean(KEY)).isFalse() assertThat(store.getInt(KEY)).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF) } @Test fun setValue_updatesCorrectly() { setBooleanValue(null) Loading Loading
src/com/android/settings/accessibility/VibrationIntensitySettingsStore.kt +11 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.settings.accessibility import android.content.Context import android.os.VibrationAttributes.Usage import android.os.Vibrator import android.provider.Settings import com.android.settings.R import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.KeyValueStoreDelegate Loading @@ -33,11 +34,20 @@ class VibrationIntensitySettingsStore( private val supportedIntensityLevels: Int = context.getSupportedVibrationIntensityLevels(), ) : KeyValueStoreDelegate { /** Returns true if the settings key should be enabled, false otherwise. */ fun isPreferenceEnabled() = keyValueStoreDelegate.getBoolean(Settings.System.VIBRATE_ON) ?: true override fun <T : Any> getDefaultValue(key: String, valueType: Class<T>) = intensityToValue(valueType, defaultIntensity) override fun <T : Any> getValue(key: String, valueType: Class<T>) = if (isPreferenceEnabled()) { intensityToValue(valueType, keyValueStoreDelegate.getInt(key) ?: defaultIntensity) } else { // Preference must show intensity off when disabled, but value stored must be preserved. intensityToValue(valueType, Vibrator.VIBRATION_INTENSITY_OFF) } override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) = keyValueStoreDelegate.setInt(key, value?.let { valueToIntensity(valueType, it) }) Loading
src/com/android/settings/accessibility/VibrationIntensitySliderPreference.kt +20 −2 Original line number Diff line number Diff line Loading @@ -34,6 +34,12 @@ import kotlin.math.min * * This implementation uses VibrationIntensitySettingsStore to save the vibration intensity value, * also playing a haptic preview on slider changes. * * This preference observes the state of the VibrationMainSwitchPreference in this fragment, * disabling and displaying intensity OFF this slider when the main switch is unchecked. This "off" * state should not be persisted, as the original user settings value must be preserved and restored * once the main switch is turned back on. This behavior reflects the actual system behavior that * restricts all vibrations when the main switch is off. */ // LINT.IfChange open class VibrationIntensitySliderPreference( Loading @@ -43,6 +49,8 @@ open class VibrationIntensitySliderPreference( @StringRes override val summary: Int = 0, ) : IntRangeValuePreference, SliderPreferenceBinding, OnPreferenceChangeListener { private var storage: VibrationIntensitySettingsStore? = null override fun getMinValue(context: Context) = Vibrator.VIBRATION_INTENSITY_OFF override fun getMaxValue(context: Context) = Loading @@ -50,8 +58,15 @@ open class VibrationIntensitySliderPreference( override fun getIncrementStep(context: Context) = 1 override fun storage(context: Context): KeyValueStore = VibrationIntensitySettingsStore(context, vibrationUsage) override fun storage(context: Context): KeyValueStore { if (storage == null) { storage = VibrationIntensitySettingsStore(context, vibrationUsage) } return storage!! } override fun dependencies(context: Context) = arrayOf(VibrationMainSwitchPreference.KEY) @CallSuper override fun bind(preference: Preference, metadata: PreferenceMetadata) { Loading @@ -70,5 +85,8 @@ open class VibrationIntensitySliderPreference( } return true } @CallSuper override fun isEnabled(context: Context) = storage?.isPreferenceEnabled() ?: true } // LINT.ThenChange(VibrationIntensityPreferenceController.java)
src/com/android/settings/accessibility/VibrationIntensitySwitchPreference.kt +19 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,12 @@ import com.android.settingslib.preference.SwitchPreferenceBinding * * This implementation uses VibrationIntensitySettingsStore to save the device default vibration * intensity value when the switch is turned on, also playing a haptic preview. * * This preference observes the state of the VibrationMainSwitchPreference in this fragment, * disabling and unchecking this switch when the main switch is unchecked. This "unchecked" state * should not be persisted, as the original user settings value must be preserved and restored once * the main switch is turned back on. This behavior reflects the actual system behavior that * restricts all vibrations when the main switch is off. */ // LINT.IfChange open class VibrationIntensitySwitchPreference( Loading @@ -42,8 +48,16 @@ open class VibrationIntensitySwitchPreference( OnPreferenceChangeListener, SwitchPreferenceBinding { override fun storage(context: Context): KeyValueStore = VibrationIntensitySettingsStore(context, vibrationUsage) private var storage: VibrationIntensitySettingsStore? = null override fun storage(context: Context): KeyValueStore { if (storage == null) { storage = VibrationIntensitySettingsStore(context, vibrationUsage) } return storage!! } override fun dependencies(context: Context) = arrayOf(VibrationMainSwitchPreference.KEY) @CallSuper override fun bind(preference: Preference, metadata: PreferenceMetadata) { Loading @@ -57,5 +71,8 @@ open class VibrationIntensitySwitchPreference( } return true } @CallSuper override fun isEnabled(context: Context) = storage?.isPreferenceEnabled() ?: true } // LINT.ThenChange(VibrationTogglePreferenceController.java)
tests/robotests/src/com/android/settings/accessibility/VibrationIntensityScreenTest.kt +5 −5 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ import org.robolectric.annotation.Config @RunWith(AndroidJUnit4::class) @Config(shadows = [ShadowAudioManager::class]) class VibrationIntensityScreenTest : CatalystScreenTestCase() { private lateinit var mockVibrator: Vibrator private lateinit var vibratorMock: Vibrator private val resourcesSpy: Resources = spy((ApplicationProvider.getApplicationContext() as Context).resources) Loading @@ -50,7 +50,7 @@ class VibrationIntensityScreenTest : CatalystScreenTestCase() { object : ContextWrapper(ApplicationProvider.getApplicationContext()) { override fun getSystemService(name: String): Any? = when { name == VIBRATOR_SERVICE -> mockVibrator name == VIBRATOR_SERVICE -> vibratorMock else -> super.getSystemService(name) } Loading @@ -74,7 +74,7 @@ class VibrationIntensityScreenTest : CatalystScreenTestCase() { @Test fun isAvailable_noVibrator_unavailable() { mockVibrator = mock { on { hasVibrator() } doReturn false } vibratorMock = mock { on { hasVibrator() } doReturn false } resourcesSpy.stub { on { getInteger(R.integer.config_vibration_supported_intensity_levels) } doReturn 3 } Loading @@ -83,7 +83,7 @@ class VibrationIntensityScreenTest : CatalystScreenTestCase() { @Test fun isAvailable_hasVibratorAndSingleIntensityLevel_unavailable() { mockVibrator = mock { on { hasVibrator() } doReturn true } vibratorMock = mock { on { hasVibrator() } doReturn true } resourcesSpy.stub { on { getInteger(R.integer.config_vibration_supported_intensity_levels) } doReturn 1 } Loading @@ -92,7 +92,7 @@ class VibrationIntensityScreenTest : CatalystScreenTestCase() { @Test fun isAvailable_hasVibratorAndMultipleIntensityLevels_available() { mockVibrator = mock { on { hasVibrator() } doReturn true } vibratorMock = mock { on { hasVibrator() } doReturn true } resourcesSpy.stub { on { getInteger(R.integer.config_vibration_supported_intensity_levels) } doReturn 2 } Loading
tests/robotests/src/com/android/settings/accessibility/VibrationIntensitySettingsStoreTest.kt +32 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,28 @@ class VibrationIntensitySettingsStoreTest { supportedIntensityLevels = SUPPORTED_INTENSITIES, ) @Test fun isPreferenceEnabled_returnsVibrateOnSettingOrTrue() { settingsStore.setBoolean(Settings.System.VIBRATE_ON, null) assertThat(store.isPreferenceEnabled()).isTrue() settingsStore.setBoolean(Settings.System.VIBRATE_ON, true) assertThat(store.isPreferenceEnabled()).isTrue() settingsStore.setBoolean(Settings.System.VIBRATE_ON, false) assertThat(store.isPreferenceEnabled()).isFalse() } @Test fun getValue_preferenceDisabledByMainSwitch_returnsIntensityOffAndPreservesValue() { settingsStore.setBoolean(Settings.System.VIBRATE_ON, false) setIntValue(Vibrator.VIBRATION_INTENSITY_HIGH) assertThat(settingsStore.getInt(KEY)).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH) assertThat(store.getBoolean(KEY)).isFalse() assertThat(store.getInt(KEY)).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF) } @Test fun getValue_valueNull_returnDefaultIntensity() { setIntValue(null) Loading Loading @@ -98,6 +120,16 @@ class VibrationIntensitySettingsStoreTest { assertThat(store.getInt(KEY)).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF) } @Test fun getValue_preferenceDisabled_returnOffAndPreservesValue() { settingsStore.setBoolean(Settings.System.VIBRATE_ON, false) setBooleanValue(true) assertThat(settingsStore.getInt(KEY)).isEqualTo(DEFAULT_INTENSITY) assertThat(store.getBoolean(KEY)).isFalse() assertThat(store.getInt(KEY)).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF) } @Test fun setValue_updatesCorrectly() { setBooleanValue(null) Loading