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

Commit fb8742d7 authored by Robert Snoeberger's avatar Robert Snoeberger
Browse files

Show disabled seek bar when session is destroyed

Fixes: 153579050
Test: manual - play music, dismiss app, verify that seek bar is
disabled.

Change-Id: I2ac44eb18d57fb4ac8a67aebe042bdb8b1b7f9e9
parent 72a3d447
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ class SeekBarObserver(view: View) : Observer<SeekBarViewModel.Progress> {
        if (!data.enabled) {
            seekBarView.setEnabled(false)
            seekBarView.getThumb().setAlpha(0)
            seekBarView.setProgress(0)
            elapsedTimeView.setText("")
            totalTimeView.setText("")
            return
+13 −1
Original line number Diff line number Diff line
@@ -77,13 +77,25 @@ class SeekBarViewModel(val bgExecutor: DelayableExecutor) {
        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()
        val enabled = if (duration != null && duration <= 0) false else true
        val enabled = if (playbackState == null ||
                playbackState?.getState() == PlaybackState.STATE_NONE ||
                (duration != null && duration <= 0)) false else true
        _data = Progress(enabled, seekAvailable, position, duration, color)
        if (shouldPollPlaybackPosition()) {
            checkPlaybackPosition()
        }
    }

    /**
     * Puts the seek bar into a resumption state.
     *
     * This should be called when the media session behind the controller has been destroyed.
     */
    @AnyThread
    fun clearController() = bgExecutor.execute {
        _data = _data.copy(enabled = false)
    }

    @AnyThread
    private fun checkPlaybackPosition(): Runnable = bgExecutor.executeDelayed({
        val currentPosition = controller?.playbackState?.position?.toInt()
+2 −0
Original line number Diff line number Diff line
@@ -171,6 +171,8 @@ public class QSMediaPlayer extends MediaControlPanel {
    public void clearControls() {
        super.clearControls();

        mSeekBarViewModel.clearController();

        View guts = mMediaNotifView.findViewById(R.id.media_guts);
        View options = mMediaNotifView.findViewById(R.id.qs_media_controls_options);

+61 −1
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ public class SeekBarViewModelTest : SysuiTestCase() {
    }

    @Test
    fun updateDuration() {
    fun updateDurationWithPlayback() {
        // GIVEN that the duration is contained within the metadata
        val duration = 12000L
        val metadata = MediaMetadata.Builder().run {
@@ -94,6 +94,12 @@ public class SeekBarViewModelTest : SysuiTestCase() {
            build()
        }
        whenever(mockController.getMetadata()).thenReturn(metadata)
        // AND a valid playback state (ie. media session is not destroyed)
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, 200L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        // WHEN the controller is updated
        viewModel.updateController(mockController, Color.RED)
        // THEN the duration is extracted
@@ -101,6 +107,22 @@ public class SeekBarViewModelTest : SysuiTestCase() {
        assertThat(viewModel.progress.value!!.enabled).isTrue()
    }

    @Test
    fun updateDurationWithoutPlayback() {
        // GIVEN that the duration is contained within the metadata
        val duration = 12000L
        val metadata = MediaMetadata.Builder().run {
            putLong(MediaMetadata.METADATA_KEY_DURATION, duration)
            build()
        }
        whenever(mockController.getMetadata()).thenReturn(metadata)
        // WHEN the controller is updated
        viewModel.updateController(mockController, Color.RED)
        // THEN the duration is extracted
        assertThat(viewModel.progress.value!!.duration).isEqualTo(duration)
        assertThat(viewModel.progress.value!!.enabled).isFalse()
    }

    @Test
    fun updateDurationNegative() {
        // GIVEN that the duration is negative
@@ -110,6 +132,12 @@ public class SeekBarViewModelTest : SysuiTestCase() {
            build()
        }
        whenever(mockController.getMetadata()).thenReturn(metadata)
        // AND a valid playback state (ie. media session is not destroyed)
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, 200L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        // WHEN the controller is updated
        viewModel.updateController(mockController, Color.RED)
        // THEN the seek bar is disabled
@@ -125,6 +153,12 @@ public class SeekBarViewModelTest : SysuiTestCase() {
            build()
        }
        whenever(mockController.getMetadata()).thenReturn(metadata)
        // AND a valid playback state (ie. media session is not destroyed)
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, 200L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        // WHEN the controller is updated
        viewModel.updateController(mockController, Color.RED)
        // THEN the seek bar is disabled
@@ -372,4 +406,30 @@ public class SeekBarViewModelTest : SysuiTestCase() {
        // THEN an update task is queued
        assertThat(fakeExecutor.numPending()).isEqualTo(1)
    }

    @Test
    fun clearSeekBar() {
        // GIVEN that the duration is contained within the metadata
        val metadata = MediaMetadata.Builder().run {
            putLong(MediaMetadata.METADATA_KEY_DURATION, 12000L)
            build()
        }
        whenever(mockController.getMetadata()).thenReturn(metadata)
        // AND a valid playback state (ie. media session is not destroyed)
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, 200L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        // AND the controller has been updated
        viewModel.updateController(mockController, Color.RED)
        // WHEN the controller is cleared on the event when the session is destroyed
        viewModel.clearController()
        with(fakeExecutor) {
            advanceClockToNext()
            runAllReady()
        }
        // THEN the seek bar is disabled
        assertThat(viewModel.progress.value!!.enabled).isFalse()
    }
}