Merge "Handle null media metadata" into rvc-qpr-dev am: 4c438e2082

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/12205023

Change-Id: I3a55463182c949b46a1e0c481917ea7d634197f4
This commit is contained in:
TreeHugger Robot
2020-07-22 00:21:45 +00:00
committed by Automerger Merge Worker
4 changed files with 27 additions and 16 deletions

View File

@@ -316,18 +316,13 @@ class MediaDataManager(
as MediaSession.Token? as MediaSession.Token?
val metadata = mediaControllerFactory.create(token).metadata val metadata = mediaControllerFactory.create(token).metadata
if (metadata == null) {
// TODO: handle this better, removing media notification
return
}
// Foreground and Background colors computed from album art // Foreground and Background colors computed from album art
val notif: Notification = sbn.notification val notif: Notification = sbn.notification
var artworkBitmap = metadata.getBitmap(MediaMetadata.METADATA_KEY_ART) var artworkBitmap = metadata?.getBitmap(MediaMetadata.METADATA_KEY_ART)
if (artworkBitmap == null) { if (artworkBitmap == null) {
artworkBitmap = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART) artworkBitmap = metadata?.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART)
} }
if (artworkBitmap == null) { if (artworkBitmap == null && metadata != null) {
artworkBitmap = loadBitmapFromUri(metadata) artworkBitmap = loadBitmapFromUri(metadata)
} }
val artWorkIcon = if (artworkBitmap == null) { val artWorkIcon = if (artworkBitmap == null) {
@@ -363,16 +358,16 @@ class MediaDataManager(
val smallIconDrawable: Drawable = sbn.notification.smallIcon.loadDrawable(context) val smallIconDrawable: Drawable = sbn.notification.smallIcon.loadDrawable(context)
// Song name // Song name
var song: CharSequence? = metadata.getString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE) var song: CharSequence? = metadata?.getString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE)
if (song == null) { if (song == null) {
song = metadata.getString(MediaMetadata.METADATA_KEY_TITLE) song = metadata?.getString(MediaMetadata.METADATA_KEY_TITLE)
} }
if (song == null) { if (song == null) {
song = HybridGroupManager.resolveTitle(notif) song = HybridGroupManager.resolveTitle(notif)
} }
// Artist name // Artist name
var artist: CharSequence? = metadata.getString(MediaMetadata.METADATA_KEY_ARTIST) var artist: CharSequence? = metadata?.getString(MediaMetadata.METADATA_KEY_ARTIST)
if (artist == null) { if (artist == null) {
artist = HybridGroupManager.resolveText(notif) artist = HybridGroupManager.resolveText(notif)
} }

View File

@@ -71,7 +71,7 @@ private fun PlaybackState.computePosition(duration: Long): Long {
/** ViewModel for seek bar in QS media player. */ /** ViewModel for seek bar in QS media player. */
class SeekBarViewModel @Inject constructor(@Background private val bgExecutor: RepeatableExecutor) { class SeekBarViewModel @Inject constructor(@Background private val bgExecutor: RepeatableExecutor) {
private var _data = Progress(false, false, null, null) private var _data = Progress(false, false, null, 0)
set(value) { set(value) {
field = value field = value
_progress.postValue(value) _progress.postValue(value)
@@ -186,10 +186,10 @@ class SeekBarViewModel @Inject constructor(@Background private val bgExecutor: R
val mediaMetadata = controller?.metadata val mediaMetadata = controller?.metadata
val seekAvailable = ((playbackState?.actions ?: 0L) and PlaybackState.ACTION_SEEK_TO) != 0L val seekAvailable = ((playbackState?.actions ?: 0L) and PlaybackState.ACTION_SEEK_TO) != 0L
val position = playbackState?.position?.toInt() val position = playbackState?.position?.toInt()
val duration = mediaMetadata?.getLong(MediaMetadata.METADATA_KEY_DURATION)?.toInt() val duration = mediaMetadata?.getLong(MediaMetadata.METADATA_KEY_DURATION)?.toInt() ?: 0
val enabled = if (playbackState == null || val enabled = if (playbackState == null ||
playbackState?.getState() == PlaybackState.STATE_NONE || playbackState?.getState() == PlaybackState.STATE_NONE ||
(duration != null && duration <= 0)) false else true (duration <= 0)) false else true
_data = Progress(enabled, seekAvailable, position, duration) _data = Progress(enabled, seekAvailable, position, duration)
checkIfPollingNeeded() checkIfPollingNeeded()
} }
@@ -408,6 +408,6 @@ class SeekBarViewModel @Inject constructor(@Background private val bgExecutor: R
val enabled: Boolean, val enabled: Boolean,
val seekAvailable: Boolean, val seekAvailable: Boolean,
val elapsedTime: Int?, val elapsedTime: Int?,
val duration: Int? val duration: Int
) )
} }

View File

@@ -69,7 +69,7 @@ public class SeekBarObserverTest : SysuiTestCase() {
fun seekBarGone() { fun seekBarGone() {
// WHEN seek bar is disabled // WHEN seek bar is disabled
val isEnabled = false val isEnabled = false
val data = SeekBarViewModel.Progress(isEnabled, false, null, null) val data = SeekBarViewModel.Progress(isEnabled, false, null, 0)
observer.onChanged(data) observer.onChanged(data)
// THEN seek bar shows just a thin line with no text // THEN seek bar shows just a thin line with no text
assertThat(seekBarView.isEnabled()).isFalse() assertThat(seekBarView.isEnabled()).isFalse()

View File

@@ -203,6 +203,22 @@ public class SeekBarViewModelTest : SysuiTestCase() {
assertThat(viewModel.progress.value!!.enabled).isFalse() assertThat(viewModel.progress.value!!.enabled).isFalse()
} }
@Test
fun updateDurationNoMetadata() {
// GIVEN that the metadata is null
whenever(mockController.getMetadata()).thenReturn(null)
// 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)
// THEN the seek bar is disabled
assertThat(viewModel.progress.value!!.enabled).isFalse()
}
@Test @Test
fun updateElapsedTime() { fun updateElapsedTime() {
// GIVEN that the PlaybackState contains the current position // GIVEN that the PlaybackState contains the current position