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

Commit 40747bb1 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Revert "Update media progress bar content description"" into main

parents cefbb15c 0250eecf
Loading
Loading
Loading
Loading
+7 −28
Original line number Diff line number Diff line
@@ -18,9 +18,6 @@ package com.android.systemui.media.controls.ui.binder

import android.animation.Animator
import android.animation.ObjectAnimator
import android.icu.text.MeasureFormat
import android.icu.util.Measure
import android.icu.util.MeasureUnit
import android.testing.TestableLooper
import android.view.View
import android.widget.SeekBar
@@ -33,7 +30,6 @@ import com.android.systemui.media.controls.ui.view.MediaViewHolder
import com.android.systemui.media.controls.ui.viewmodel.SeekBarViewModel
import com.android.systemui.res.R
import com.google.common.truth.Truth.assertThat
import java.util.Locale
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -65,11 +61,11 @@ class SeekBarObserverTest : SysuiTestCase() {
    fun setUp() {
        context.orCreateTestableResources.addOverride(
            R.dimen.qs_media_enabled_seekbar_height,
            enabledHeight,
            enabledHeight
        )
        context.orCreateTestableResources.addOverride(
            R.dimen.qs_media_disabled_seekbar_height,
            disabledHeight,
            disabledHeight
        )

        seekBarView = SeekBar(context)
@@ -114,31 +110,14 @@ class SeekBarObserverTest : SysuiTestCase() {

    @Test
    fun seekBarProgress() {
        val elapsedTime = 3000
        val duration = (1.5 * 60 * 60 * 1000).toInt()
        // WHEN part of the track has been played
        val data = SeekBarViewModel.Progress(true, true, true, false, elapsedTime, duration, true)
        val data = SeekBarViewModel.Progress(true, true, true, false, 3000, 120000, true)
        observer.onChanged(data)
        // THEN seek bar shows the progress
        assertThat(seekBarView.progress).isEqualTo(elapsedTime)
        assertThat(seekBarView.max).isEqualTo(duration)

        val expectedProgress =
            MeasureFormat.getInstance(Locale.getDefault(), MeasureFormat.FormatWidth.WIDE)
                .formatMeasures(Measure(3, MeasureUnit.SECOND))
        val expectedDuration =
            MeasureFormat.getInstance(Locale.getDefault(), MeasureFormat.FormatWidth.WIDE)
                .formatMeasures(
                    Measure(1, MeasureUnit.HOUR),
                    Measure(30, MeasureUnit.MINUTE),
                    Measure(0, MeasureUnit.SECOND),
                )
        val desc =
            context.getString(
                R.string.controls_media_seekbar_description,
                expectedProgress,
                expectedDuration,
            )
        assertThat(seekBarView.progress).isEqualTo(3000)
        assertThat(seekBarView.max).isEqualTo(120000)

        val desc = context.getString(R.string.controls_media_seekbar_description, "00:03", "02:00")
        assertThat(seekBarView.contentDescription).isEqualTo(desc)
    }

+2 −2
Original line number Diff line number Diff line
@@ -3176,8 +3176,8 @@
    <string name="controls_media_settings_button">Settings</string>
    <!-- Description for media control's playing media item, including information for the media's title, the artist, and source app [CHAR LIMIT=NONE]-->
    <string name="controls_media_playing_item_description"><xliff:g id="song_name" example="Daily mix">%1$s</xliff:g> by <xliff:g id="artist_name" example="Various artists">%2$s</xliff:g> is playing from <xliff:g id="app_label" example="Spotify">%3$s</xliff:g></string>
    <!-- Content description for media controls progress bar [CHAR_LIMIT=NONE] -->
    <string name="controls_media_seekbar_description"><xliff:g id="elapsed_time" example="1 hour 2 minutes 30 seconds">%1$s</xliff:g> of <xliff:g id="total_time" example="4 hours 5 seconds">%2$s</xliff:g></string>
    <!-- Content description for media cotnrols progress bar [CHAR_LIMIT=NONE] -->
    <string name="controls_media_seekbar_description"><xliff:g id="elapsed_time" example="1:30">%1$s</xliff:g> of <xliff:g id="total_time" example="3:00">%2$s</xliff:g></string>
    <!-- Placeholder title to inform user that an app has posted media controls [CHAR_LIMIT=NONE] -->
    <string name="controls_media_empty_title"><xliff:g id="app_name" example="Foo Music App">%1$s</xliff:g> is running</string>

+8 −55
Original line number Diff line number Diff line
@@ -18,9 +18,6 @@ package com.android.systemui.media.controls.ui.binder

import android.animation.Animator
import android.animation.ObjectAnimator
import android.icu.text.MeasureFormat
import android.icu.util.Measure
import android.icu.util.MeasureUnit
import android.text.format.DateUtils
import androidx.annotation.UiThread
import androidx.lifecycle.Observer
@@ -31,11 +28,8 @@ import com.android.systemui.media.controls.ui.drawable.SquigglyProgress
import com.android.systemui.media.controls.ui.view.MediaViewHolder
import com.android.systemui.media.controls.ui.viewmodel.SeekBarViewModel
import com.android.systemui.res.R
import java.util.Locale

private const val TAG = "SeekBarObserver"
private const val MIN_IN_SEC = 60
private const val HOUR_IN_SEC = MIN_IN_SEC * 60

/**
 * Observer for changes from SeekBarViewModel.
@@ -133,9 +127,10 @@ open class SeekBarObserver(private val holder: MediaViewHolder) :
        }

        holder.seekBar.setMax(data.duration)
        val totalTimeDescription = formatTimeContentDescription(data.duration)
        val totalTimeString =
            DateUtils.formatElapsedTime(data.duration / DateUtils.SECOND_IN_MILLIS)
        if (data.scrubbing) {
            holder.scrubbingTotalTimeView.text = formatTimeLabel(data.duration)
            holder.scrubbingTotalTimeView.text = totalTimeString
        }

        data.elapsedTime?.let {
@@ -153,62 +148,20 @@ open class SeekBarObserver(private val holder: MediaViewHolder) :
                }
            }

            val elapsedTimeDescription = formatTimeContentDescription(it)
            val elapsedTimeString = DateUtils.formatElapsedTime(it / DateUtils.SECOND_IN_MILLIS)
            if (data.scrubbing) {
                holder.scrubbingElapsedTimeView.text = formatTimeLabel(it)
                holder.scrubbingElapsedTimeView.text = elapsedTimeString
            }

            holder.seekBar.contentDescription =
                holder.seekBar.context.getString(
                    R.string.controls_media_seekbar_description,
                    elapsedTimeDescription,
                    totalTimeDescription,
                    elapsedTimeString,
                    totalTimeString
                )
        }
    }

    /** Returns a time string suitable for display, e.g. "12:34" */
    private fun formatTimeLabel(milliseconds: Int): CharSequence {
        return DateUtils.formatElapsedTime(milliseconds / DateUtils.SECOND_IN_MILLIS)
    }

    /**
     * Returns a time string suitable for content description, e.g. "12 minutes 34 seconds"
     *
     * Follows same logic as Chronometer#formatDuration
     */
    private fun formatTimeContentDescription(milliseconds: Int): CharSequence {
        var seconds = milliseconds / DateUtils.SECOND_IN_MILLIS

        val hours =
            if (seconds >= HOUR_IN_SEC) {
                seconds / HOUR_IN_SEC
            } else {
                0
            }
        seconds -= hours * HOUR_IN_SEC

        val minutes =
            if (seconds >= MIN_IN_SEC) {
                seconds / MIN_IN_SEC
            } else {
                0
            }
        seconds -= minutes * MIN_IN_SEC

        val measures = arrayListOf<Measure>()
        if (hours > 0) {
            measures.add(Measure(hours, MeasureUnit.HOUR))
        }
        if (minutes > 0) {
            measures.add(Measure(minutes, MeasureUnit.MINUTE))
        }
        measures.add(Measure(seconds, MeasureUnit.SECOND))

        return MeasureFormat.getInstance(Locale.getDefault(), MeasureFormat.FormatWidth.WIDE)
            .formatMeasures(*measures.toTypedArray())
    }

    @VisibleForTesting
    open fun buildResetAnimator(targetTime: Int): Animator {
        val animator =
@@ -216,7 +169,7 @@ open class SeekBarObserver(private val holder: MediaViewHolder) :
                holder.seekBar,
                "progress",
                holder.seekBar.progress,
                targetTime + RESET_ANIMATION_DURATION_MS,
                targetTime + RESET_ANIMATION_DURATION_MS
            )
        animator.setAutoCancel(true)
        animator.duration = RESET_ANIMATION_DURATION_MS.toLong()