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

Commit a334ce6c authored by Bhavuk Jain's avatar Bhavuk Jain Committed by Android Build Coastguard Worker
Browse files

Fixed selection of clock slider

This CL makes sure we announce the range of slider without requiring a
custom accesibility delegate. Having a custom delegate removes any
pre-defined slider a11y features which leads to more issues.

Bug: 418222523
Flag: EXEMPT bugfix
Test: Tested by building & installing picker on local, checking talkback
announcement, also by checking if we are able to change clock face width
using talkback.
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:d5116d0e6932318aac9ad38b0616859a575c572d)
Merged-In: I00c25c943ee089680c29d0cccd19eaf5b76610db
Change-Id: I00c25c943ee089680c29d0cccd19eaf5b76610db
parent 30d367aa
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -669,8 +669,8 @@

    <!--
    Accessibility announcement template for a numerical range.
    %1$d is the minimum value, %2$d is the maximum value.
    Example: "range from 1 to 7". [CHAR LIMIT=none]
    %1$d is the current value, %1$d is the minimum value, %2$d is the maximum value.
    Example: "value 3, range from 1 to 7". [CHAR LIMIT=none]
    -->
    <string name="range_announcement_template">range from %1$d to %2$d</string>
    <string name="slider_state_description_template">%1$d, range from %2$d to %3$d</string>
</resources>
+25 −57
Original line number Diff line number Diff line
@@ -20,12 +20,10 @@ import android.content.Context
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.view.accessibility.AccessibilityNodeInfo
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
import androidx.core.view.get
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
@@ -149,6 +147,14 @@ object ClockFloatingSheetBinder {
                )
            }

        val sliderLabel = appContext.getString(R.string.clock_face_width)
        axisPresetSlider.contentDescription = sliderLabel

        axisPresetSlider.setLabelFormatter { value ->
            val mappedValueInt = Math.round(value + 1.0f)
            mappedValueInt.toString()
        }

        ColorUpdateBinder.bind(
            setColor = { color ->
                axisPresetSliderContainer
@@ -160,61 +166,6 @@ object ClockFloatingSheetBinder {
            lifecycleOwner = lifecycleOwner,
        )

        // Setting content description for the clock face width slider
        val sliderLabel = appContext.getString(R.string.clock_face_width)
        axisPresetSlider.contentDescription = sliderLabel
        axisPresetSlider.setAccessibilityDelegate(
            object : View.AccessibilityDelegate() {
                override fun onInitializeAccessibilityNodeInfo(
                    host: View,
                    info: AccessibilityNodeInfo,
                ) {
                    super.onInitializeAccessibilityNodeInfo(host, info)
                    val infoCompat = AccessibilityNodeInfoCompat.wrap(info)

                    if (host !is Slider) return

                    // increased these values by 1.0 in order to announce for content description
                    val actualMin = host.valueFrom + 1.0f
                    val actualMax = host.valueTo + 1.0f
                    val currentValueActual = host.value + 1.0f

                    val normalizedPosition =
                        if (actualMax - actualMin == 0f) {
                            0f
                        } else {
                            ((currentValueActual - actualMin) / (actualMax - actualMin)).coerceIn(
                                0f,
                                1f,
                            )
                        }
                    val mappedValueFloat = actualMin + normalizedPosition * (actualMax - actualMin)
                    val mappedValueInt = Math.round(mappedValueFloat)

                    val conceptualMinInt = actualMin.toInt()
                    val conceptualMaxInt = actualMax.toInt()
                    // this is a workaround that is needed because talkback isn't announcing the
                    // range using RangeInfo on the material slider.
                    val hardcodedRangeText =
                        appContext.getString(
                            R.string.range_announcement_template,
                            conceptualMinInt,
                            conceptualMaxInt,
                        )
                    val customRangeInfo =
                        AccessibilityNodeInfoCompat.RangeInfoCompat.obtain(
                            AccessibilityNodeInfoCompat.RangeInfoCompat.RANGE_TYPE_INT,
                            actualMin,
                            actualMax,
                            mappedValueInt.toFloat(),
                        )
                    infoCompat.rangeInfo = customRangeInfo
                    infoCompat.text = null
                    infoCompat.stateDescription = "$mappedValueInt, $hardcodedRangeText"
                }
            }
        )

        val clockColorContent: View = view.requireViewById(R.id.clock_floating_sheet_color_content)

        val clockColorAdapter =
@@ -602,9 +553,12 @@ object ClockFloatingSheetBinder {
                        )
                        axisPresetSlider.clearOnChangeListeners()
                        axisPresetSlider.addOnChangeListener { slider, value, fromUser ->
                            updateAccessibilityStateDescription(slider, slider.context)

                            if (optionsViewModel.isAccessibilityEnabled(slider.context)) {
                                axisPresetsSliderViewModel.onSliderStopTrackingTouch(value)
                            }
                            updateAccessibilityStateDescription(axisPresetSlider, slider.context)
                        }
                    }
                }
@@ -616,6 +570,20 @@ object ClockFloatingSheetBinder {
        }
    }

    private fun updateAccessibilityStateDescription(slider: Slider, appContext: Context) {
        val currentValueInt = Math.round(slider.value + 1.0f)
        val minInt = (slider.valueFrom + 1.0f).toInt()
        val maxInt = (slider.valueTo + 1.0f).toInt()

        slider.stateDescription =
            appContext.getString(
                R.string.slider_state_description_template,
                currentValueInt,
                minInt,
                maxInt,
            )
    }

    private fun createClockStyleOptionItemAdapter(
        colorUpdateViewModel: ColorUpdateViewModel,
        shouldAnimateColor: () -> Boolean,