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

Commit dddf4fca authored by Lucas Dupin's avatar Lucas Dupin
Browse files

Implement seekbar animation

Test: manual
Test: atest SeekBarObserverTest
Test: atest SquigglyProgressTest
Bug: 220873625
Change-Id: I161fe0eeb30bde425c1fbad5d5fdad924e628f2d
parent 89489bb5
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2022 The Android Open Source Project
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->
<com.android.systemui.media.SquigglyProgress />
 No newline at end of file
+4 −0
Original line number Diff line number Diff line
@@ -979,6 +979,10 @@
    <dimen name="qs_media_session_disabled_seekbar_vertical_padding">16dp</dimen>
    <dimen name="qs_media_session_height_expanded">184dp</dimen>
    <dimen name="qs_media_session_height_collapsed">128dp</dimen>
    <dimen name="qs_media_seekbar_progress_wavelength">20dp</dimen>
    <dimen name="qs_media_seekbar_progress_amplitude">1.5dp</dimen>
    <dimen name="qs_media_seekbar_progress_phase">8dp</dimen>
    <dimen name="qs_media_seekbar_progress_stroke_width">2dp</dimen>

    <!-- Size of Smartspace media recommendations cards in the QSPanel carousel -->
    <dimen name="qs_aa_media_rec_album_size_collapsed">72dp</dimen>
+1 −0
Original line number Diff line number Diff line
@@ -590,6 +590,7 @@

    <style name="MediaPlayer.ProgressBar" parent="@android:style/Widget.ProgressBar.Horizontal">
        <item name="android:thumbTint">?android:attr/textColorPrimary</item>
        <item name="android:progressDrawable">@drawable/media_squiggly_progress</item>
        <item name="android:progressTint">?android:attr/textColorPrimary</item>
        <item name="android:progressBackgroundTint">?android:attr/textColorTertiary</item>
        <item name="android:clickable">true</item>
+28 −7
Original line number Diff line number Diff line
@@ -50,25 +50,46 @@ class SeekBarObserver(
                .getDimensionPixelSize(R.dimen.qs_media_disabled_seekbar_vertical_padding)
    }

    init {
        val seekBarProgressWavelength = holder.seekBar.context.resources
                .getDimensionPixelSize(R.dimen.qs_media_seekbar_progress_wavelength).toFloat()
        val seekBarProgressAmplitude = holder.seekBar.context.resources
                .getDimensionPixelSize(R.dimen.qs_media_seekbar_progress_amplitude).toFloat()
        val seekBarProgressPhase = holder.seekBar.context.resources
                .getDimensionPixelSize(R.dimen.qs_media_seekbar_progress_phase).toFloat()
        val seekBarProgressStrokeWidth = holder.seekBar.context.resources
                .getDimensionPixelSize(R.dimen.qs_media_seekbar_progress_stroke_width).toFloat()
        val progressDrawable = holder.seekBar.progressDrawable as? SquigglyProgress
        progressDrawable?.let {
            it.waveLength = seekBarProgressWavelength
            it.lineAmplitude = seekBarProgressAmplitude
            it.phaseSpeed = seekBarProgressPhase
            it.strokeWidth = seekBarProgressStrokeWidth
        }
    }

    /** Updates seek bar views when the data model changes. */
    @UiThread
    override fun onChanged(data: SeekBarViewModel.Progress) {
        val progressDrawable = holder.seekBar.progressDrawable as? SquigglyProgress
        if (!data.enabled) {
            if (holder.seekBar.maxHeight != seekBarDisabledHeight) {
                holder.seekBar.maxHeight = seekBarDisabledHeight
                setVerticalPadding(seekBarDisabledVerticalPadding)
            }
            holder.seekBar.setEnabled(false)
            holder.seekBar.getThumb().setAlpha(0)
            holder.seekBar.setProgress(0)
            holder.elapsedTimeView?.setText("")
            holder.totalTimeView?.setText("")
            holder.seekBar.isEnabled = false
            progressDrawable?.animate = false
            holder.seekBar.thumb.alpha = 0
            holder.seekBar.progress = 0
            holder.elapsedTimeView?.text = ""
            holder.totalTimeView?.text = ""
            holder.seekBar.contentDescription = ""
            return
        }

        holder.seekBar.getThumb().setAlpha(if (data.seekAvailable) 255 else 0)
        holder.seekBar.setEnabled(data.seekAvailable)
        holder.seekBar.thumb.alpha = if (data.seekAvailable) 255 else 0
        holder.seekBar.isEnabled = data.seekAvailable
        progressDrawable?.animate = data.playing

        if (holder.seekBar.maxHeight != seekBarEnabledMaxHeight) {
            holder.seekBar.maxHeight = seekBarEnabledMaxHeight
+6 −2
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import androidx.core.view.GestureDetectorCompat
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.statusbar.NotificationMediaManager
import com.android.systemui.util.concurrency.RepeatableExecutor
import javax.inject.Inject

@@ -73,7 +74,7 @@ private fun PlaybackState.computePosition(duration: Long): Long {
class SeekBarViewModel @Inject constructor(
    @Background private val bgExecutor: RepeatableExecutor
) {
    private var _data = Progress(false, false, null, 0)
    private var _data = Progress(false, false, false, null, 0)
        set(value) {
            field = value
            _progress.postValue(value)
@@ -192,10 +193,12 @@ class SeekBarViewModel @Inject constructor(
        val seekAvailable = ((playbackState?.actions ?: 0L) and PlaybackState.ACTION_SEEK_TO) != 0L
        val position = playbackState?.position?.toInt()
        val duration = mediaMetadata?.getLong(MediaMetadata.METADATA_KEY_DURATION)?.toInt() ?: 0
        val playing = NotificationMediaManager
                .isPlayingState(playbackState?.state ?: PlaybackState.STATE_NONE)
        val enabled = if (playbackState == null ||
                playbackState?.getState() == PlaybackState.STATE_NONE ||
                (duration <= 0)) false else true
        _data = Progress(enabled, seekAvailable, position, duration)
        _data = Progress(enabled, seekAvailable, playing, position, duration)
        checkIfPollingNeeded()
    }

@@ -412,6 +415,7 @@ class SeekBarViewModel @Inject constructor(
    data class Progress(
        val enabled: Boolean,
        val seekAvailable: Boolean,
        val playing: Boolean,
        val elapsedTime: Int?,
        val duration: Int
    )
Loading