From 66098febbc5dac0cb179b91bca5256a717152fac Mon Sep 17 00:00:00 2001 From: shaoweishen Date: Thu, 18 Aug 2022 03:52:05 +0000 Subject: [PATCH] [Sound Panel] Fix bugs for sound panel slice 1. notify item change when slice live data has update 2. keep showing Output Switcher slice when media state is in "Pause" state Bug: 247043239 Bug: 238715094 Bug: 204165377 Test: verified on device Change-Id: Ic56a70f2f2835231519e2fccf0d2e649d41b106e --- .../settings/media/MediaOutputUtils.java | 4 +- .../android/settings/panel/PanelFragment.java | 8 ++- .../settings/panel/PanelSlicesAdapter.java | 15 +++-- .../settings/media/MediaOutputUtilsTest.java | 59 +++++++++++++++++-- 4 files changed, 71 insertions(+), 15 deletions(-) diff --git a/src/com/android/settings/media/MediaOutputUtils.java b/src/com/android/settings/media/MediaOutputUtils.java index 977c5178165..fcb2fb2b524 100644 --- a/src/com/android/settings/media/MediaOutputUtils.java +++ b/src/com/android/settings/media/MediaOutputUtils.java @@ -64,7 +64,9 @@ public class MediaOutputUtils { + ", play back type : " + pi.getPlaybackType() + ", play back state : " + playbackState.getState()); } - if (playbackState.getState() != PlaybackState.STATE_PLAYING) { + if (playbackState.getState() == PlaybackState.STATE_STOPPED + || playbackState.getState() == PlaybackState.STATE_NONE + || playbackState.getState() == PlaybackState.STATE_ERROR) { // do nothing continue; } diff --git a/src/com/android/settings/panel/PanelFragment.java b/src/com/android/settings/panel/PanelFragment.java index 04ae3116176..1ce4492ba16 100644 --- a/src/com/android/settings/panel/PanelFragment.java +++ b/src/com/android/settings/panel/PanelFragment.java @@ -60,6 +60,7 @@ import com.android.settingslib.utils.ThreadUtils; import com.google.android.setupdesign.DividerItemDecoration; +import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; @@ -339,8 +340,13 @@ public class PanelFragment extends Fragment { mSliceLiveData.put(uri, sliceLiveData); sliceLiveData.observe(getViewLifecycleOwner(), slice -> { - // If the Slice has already loaded, do nothing. + + // If the Slice has already loaded, refresh list with slice data. if (mPanelSlicesLoaderCountdownLatch.isSliceLoaded(uri)) { + if (mAdapter != null) { + int itemIndex = (new ArrayList<>(mSliceLiveData.keySet())).indexOf(uri); + mAdapter.notifyItemChanged(itemIndex); + } return; } diff --git a/src/com/android/settings/panel/PanelSlicesAdapter.java b/src/com/android/settings/panel/PanelSlicesAdapter.java index afccc785af8..d7283667787 100644 --- a/src/com/android/settings/panel/PanelSlicesAdapter.java +++ b/src/com/android/settings/panel/PanelSlicesAdapter.java @@ -84,7 +84,7 @@ public class PanelSlicesAdapter @Override public void onBindViewHolder(@NonNull SliceRowViewHolder sliceRowViewHolder, int position) { - sliceRowViewHolder.onBind(mSliceLiveData.get(position), position); + sliceRowViewHolder.onBind(mSliceLiveData.get(position).getValue()); } /** @@ -132,15 +132,14 @@ public class PanelSlicesAdapter /** * Called when the view is displayed. */ - public void onBind(LiveData sliceLiveData, int position) { - sliceLiveData.observe(mPanelFragment.getViewLifecycleOwner(), sliceView); - - // Do not show the divider above media devices switcher slice per request - final Slice slice = sliceLiveData.getValue(); - + public void onBind(Slice slice) { // Hides slice which reports with error hint or not contain any slice sub-item. if (slice == null || !isValidSlice(slice)) { sliceView.setVisibility(View.GONE); + return; + } else { + sliceView.setSlice(slice); + sliceView.setVisibility(View.VISIBLE); } // Add divider for the end icon @@ -154,7 +153,7 @@ public class PanelSlicesAdapter .action(0 /* attribution */, SettingsEnums.ACTION_PANEL_INTERACTION, mMetricsCategory, - sliceLiveData.getValue().getUri().getLastPathSegment() + slice.getUri().getLastPathSegment() /* log key */, eventInfo.actionType /* value */); }) diff --git a/tests/robotests/src/com/android/settings/media/MediaOutputUtilsTest.java b/tests/robotests/src/com/android/settings/media/MediaOutputUtilsTest.java index dea6a2c81ab..5fa7fdd0c64 100644 --- a/tests/robotests/src/com/android/settings/media/MediaOutputUtilsTest.java +++ b/tests/robotests/src/com/android/settings/media/MediaOutputUtilsTest.java @@ -66,7 +66,18 @@ public class MediaOutputUtilsTest { @Test public void getActiveLocalMediaController_localMediaPlaying_returnController() { - initPlayback(); + initPlayback(PlaybackState.STATE_PLAYING); + + when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo); + when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState); + + assertThat(MediaOutputUtils.getActiveLocalMediaController(mMediaSessionManager)).isEqualTo( + mMediaController); + } + + @Test + public void getActiveLocalMediaController_localMediaPause_returnController() { + initPlayback(PlaybackState.STATE_PAUSED); when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo); when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState); @@ -113,6 +124,44 @@ public class MediaOutputUtilsTest { assertThat(MediaOutputUtils.getActiveLocalMediaController(mMediaSessionManager)).isNull(); } + @Test + public void getActiveLocalMediaController_localMediaNone_returnNull() { + mPlaybackInfo = new MediaController.PlaybackInfo( + MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL, + VolumeProvider.VOLUME_CONTROL_ABSOLUTE, + 100, + 10, + new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(), + null); + mPlaybackState = new PlaybackState.Builder() + .setState(PlaybackState.STATE_NONE, 0, 1) + .build(); + + when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo); + when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState); + + assertThat(MediaOutputUtils.getActiveLocalMediaController(mMediaSessionManager)).isNull(); + } + + @Test + public void getActiveLocalMediaController_localMediaError_returnNull() { + mPlaybackInfo = new MediaController.PlaybackInfo( + MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL, + VolumeProvider.VOLUME_CONTROL_ABSOLUTE, + 100, + 10, + new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(), + null); + mPlaybackState = new PlaybackState.Builder() + .setState(PlaybackState.STATE_ERROR, 0, 1) + .build(); + + when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo); + when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState); + + assertThat(MediaOutputUtils.getActiveLocalMediaController(mMediaSessionManager)).isNull(); + } + @Test public void getActiveLocalMediaController_bothHaveRemoteMediaAndLocalMedia_returnNull() { mMediaControllers.clear(); @@ -130,7 +179,7 @@ public class MediaOutputUtilsTest { mMediaControllers.add(remoteMediaController); mMediaControllers.add(mMediaController); - initPlayback(); + initPlayback(PlaybackState.STATE_PLAYING); when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo); when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState); @@ -155,7 +204,7 @@ public class MediaOutputUtilsTest { final MediaController remoteMediaController = mock(MediaController.class); mMediaControllers.add(remoteMediaController); - initPlayback(); + initPlayback(PlaybackState.STATE_PLAYING); when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo); when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState); @@ -165,7 +214,7 @@ public class MediaOutputUtilsTest { assertThat(MediaOutputUtils.getActiveLocalMediaController(mMediaSessionManager)).isNull(); } - private void initPlayback() { + private void initPlayback(int playbackState) { mPlaybackInfo = new MediaController.PlaybackInfo( MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL, VolumeProvider.VOLUME_CONTROL_ABSOLUTE, @@ -174,7 +223,7 @@ public class MediaOutputUtilsTest { new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(), null); mPlaybackState = new PlaybackState.Builder() - .setState(PlaybackState.STATE_PLAYING, 0, 1) + .setState(playbackState, 0, 1) .build(); } }