Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 361804bd authored by Josep del Rio's avatar Josep del Rio Committed by Josep del Río
Browse files

Trigger haptics preview after setting has been applied

An issue has been reported that there is no haptic preview when
toggling it from the vibration settings panel. This revealed a
larger problem, as the preference change API will be called before
the setting is applied, which causes the preview to use the
previous configuration. This CL changes the haptic preview
triggering to be asynchronous, so it is executed after the
preference has been applied.

Bug: 410756621
Test: Manual, robotest
Flag: EXEMPT bugfix
NO_IFTTT=No changes necessary

Change-Id: I64b2ba4153ddb580f05c4ece3b60a6c80545b084
parent 868f4f3b
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -27,8 +27,8 @@ import kotlin.math.min

/** SettingsStore for vibration intensity preferences with custom default value. */
class VibrationIntensitySettingsStore(
    context: Context,
    @Usage vibrationUsage: Int,
    private val context: Context,
    @Usage private val vibrationUsage: Int,
    override val keyValueStoreDelegate: KeyValueStore = SettingsSystemStore.get(context),
    private val defaultIntensity: Int = context.getDefaultVibrationIntensity(vibrationUsage),
    private val supportedIntensityLevels: Int = context.getSupportedVibrationIntensityLevels(),
@@ -49,8 +49,17 @@ class VibrationIntensitySettingsStore(
            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) })
    override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) {
        val intensityValue: Int? = value?.let { nonNullValue ->
            valueToIntensity(valueType, nonNullValue)
        }
        keyValueStoreDelegate.setInt(key, intensityValue)
        if (isPreferenceEnabled() &&
                intensityValue != null &&
                intensityValue != Vibrator.VIBRATION_INTENSITY_OFF) {
            context.playVibrationSettingsPreview(vibrationUsage)
        }
    }

    @Suppress("UNCHECKED_CAST")
    private fun <T: Any> intensityToValue(valueType: Class<T>, intensity: Int): T? =
+1 −10
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import android.os.Vibrator
import androidx.annotation.CallSuper
import androidx.annotation.StringRes
import androidx.preference.Preference
import androidx.preference.Preference.OnPreferenceChangeListener
import com.android.settingslib.datastore.KeyValueStore
import com.android.settingslib.metadata.IntRangeValuePreference
import com.android.settingslib.metadata.PreferenceMetadata
@@ -47,7 +46,7 @@ open class VibrationIntensitySliderPreference(
    @Usage val vibrationUsage: Int,
    @StringRes override val title: Int = 0,
    @StringRes override val summary: Int = 0,
) : IntRangeValuePreference, SliderPreferenceBinding, OnPreferenceChangeListener {
) : IntRangeValuePreference, SliderPreferenceBinding {

    private var storage: VibrationIntensitySettingsStore? = null

@@ -71,7 +70,6 @@ open class VibrationIntensitySliderPreference(
    @CallSuper
    override fun bind(preference: Preference, metadata: PreferenceMetadata) {
        super.bind(preference, metadata)
        preference.onPreferenceChangeListener = this
        (preference as SliderPreference).apply {
            // Haptics previews played by the Settings app don't bypass user settings to be played.
            // The sliders continuously updates the intensity value so the previews can apply them.
@@ -79,13 +77,6 @@ open class VibrationIntensitySliderPreference(
        }
    }

    override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
        if (newValue as Int != Vibrator.VIBRATION_INTENSITY_OFF) {
            preference.context.playVibrationSettingsPreview(vibrationUsage)
        }
        return true
    }

    @CallSuper
    override fun isEnabled(context: Context) = storage?.isPreferenceEnabled() ?: true
}
+0 −15
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import android.os.VibrationAttributes.Usage
import androidx.annotation.CallSuper
import androidx.annotation.StringRes
import androidx.preference.Preference
import androidx.preference.Preference.OnPreferenceChangeListener
import com.android.settingslib.datastore.KeyValueStore
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.SwitchPreference
@@ -45,7 +44,6 @@ open class VibrationIntensitySwitchPreference(
    @StringRes title: Int = 0,
    @StringRes summary: Int = 0,
) : SwitchPreference(key, title, summary),
    OnPreferenceChangeListener,
    SwitchPreferenceBinding {

    private var storage: VibrationIntensitySettingsStore? = null
@@ -59,19 +57,6 @@ open class VibrationIntensitySwitchPreference(

    override fun dependencies(context: Context) = arrayOf(VibrationMainSwitchPreference.KEY)

    @CallSuper
    override fun bind(preference: Preference, metadata: PreferenceMetadata) {
        super.bind(preference, metadata)
        preference.onPreferenceChangeListener = this
    }

    override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
        if (newValue as Boolean) {
            preference.context.playVibrationSettingsPreview(vibrationUsage)
        }
        return true
    }

    @CallSuper
    override fun isEnabled(context: Context) = storage?.isPreferenceEnabled() ?: true
}
+9 −16
Original line number Diff line number Diff line
@@ -39,8 +39,7 @@ import com.android.settingslib.widget.MainSwitchPreferenceBinding
class VibrationMainSwitchPreference :
    BooleanValuePreference,
    MainSwitchPreferenceBinding,
    PreferenceActionMetricsProvider,
    Preference.OnPreferenceChangeListener {
    PreferenceActionMetricsProvider {

    override val key
        get() = KEY
@@ -71,19 +70,6 @@ class VibrationMainSwitchPreference :
    override val sensitivityLevel: Int
        get() = SensitivityLevel.NO_SENSITIVITY

    override fun bind(preference: Preference, metadata: PreferenceMetadata) {
        super.bind(preference, metadata)
        preference.onPreferenceChangeListener = this
    }

    override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
        if (newValue as Boolean) {
            // Play a haptic as preview for the main toggle only when touch feedback is enabled.
            preference.context.playVibrationSettingsPreview(VibrationAttributes.USAGE_TOUCH)
        }
        return true
    }

    companion object {
        const val KEY = Settings.System.VIBRATE_ON
    }
@@ -91,13 +77,20 @@ class VibrationMainSwitchPreference :

/** Provides SettingsStore for vibration main switch with custom default value. */
class VibrationMainSwitchStore(
    context: Context,
    private val context: Context,
    override val keyValueStoreDelegate: KeyValueStore = SettingsSystemStore.get(context),
) : KeyValueStoreDelegate {

    @Suppress("UNCHECKED_CAST")
    override fun <T : Any> getDefaultValue(key: String, valueType: Class<T>) = DEFAULT_VALUE as T

    override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) {
        keyValueStoreDelegate.setValue(key, valueType, value)
        if (value == true) {
            context.playVibrationSettingsPreview(VibrationAttributes.USAGE_TOUCH)
        }
    }

    companion object {
        private const val DEFAULT_VALUE = true
    }