summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt62
4 files changed, 77 insertions, 2 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
index b7658a9f178d..51c157a56560 100644
--- a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
@@ -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
diff --git a/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
index dd83e42cde2d..142510030a5f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
@@ -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()
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java b/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java
index e636707a9722..dcb0f883b016 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java
@@ -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);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt
index f316d0480fac..28a3d6a32a61 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt
@@ -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
@@ -102,6 +108,22 @@ public class SeekBarViewModelTest : SysuiTestCase() {
}
@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
val duration = -1L
@@ -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()
+ }
}