diff options
author | Beth Thibodeau <ethibodeau@google.com> | 2021-10-06 23:25:37 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-10-06 23:25:37 +0000 |
commit | bb9ecdd2aff4021da077ee3005c467310a272b7a (patch) | |
tree | d3be1f06bc7c90fbb35d7452175bf68a19179749 | |
parent | d29e0cdfd0d365a934c922a3c7376e389d40c0ad (diff) | |
parent | 8340c2b0e01740ec3ae382a2a0be89f2717edeed (diff) |
Merge "Fix sorting issues with remote and resume controls" into sc-v2-dev
6 files changed, 181 insertions, 4 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt index c743fe125cf7..0e70945be225 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt @@ -833,11 +833,12 @@ internal object MediaPlayerData { ) private val comparator = - compareByDescending<MediaSortKey> { it.data.isPlaying } + compareByDescending<MediaSortKey> { it.data.isPlaying == true && it.data.isLocalSession } + .thenByDescending { it.data.isPlaying } .thenByDescending { if (shouldPrioritizeSs) it.isSsMediaRec else !it.isSsMediaRec } - .thenByDescending { it.data.isLocalSession } .thenByDescending { !it.data.resumption } .thenByDescending { it.updateTime } + .thenByDescending { !it.data.isLocalSession } private val mediaPlayers = TreeMap<MediaSortKey, MediaControlPanel>(comparator) private val mediaData: MutableMap<String, MediaSortKey> = mutableMapOf() diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt index 06a1eeac425d..3631d2fa04fb 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt @@ -768,7 +768,7 @@ class MediaDataManager( val resumeAction = getResumeMediaAction(removed.resumeAction!!) val updated = removed.copy(token = null, actions = listOf(resumeAction), actionsToShowInCompact = listOf(0), active = false, resumption = true, - isClearable = true) + isPlaying = false, isClearable = true) val pkg = removed.packageName val migrate = mediaEntries.put(pkg, updated) == null // Notify listeners of "new" controls when migrating or removed and update when not diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt new file mode 100644 index 000000000000..175ec87fd943 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2021 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. + */ + +package com.android.systemui.media + +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.classifier.FalsingCollector +import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.dump.DumpManager +import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.plugins.FalsingManager +import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager +import com.android.systemui.statusbar.policy.ConfigurationController +import com.android.systemui.util.concurrency.DelayableExecutor +import com.android.systemui.util.time.FakeSystemClock +import junit.framework.Assert.assertEquals +import junit.framework.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.MockitoAnnotations +import javax.inject.Provider + +private val DATA = MediaData( + userId = -1, + initialized = false, + backgroundColor = 0, + app = null, + appIcon = null, + artist = null, + song = null, + artwork = null, + actions = emptyList(), + actionsToShowInCompact = emptyList(), + packageName = "INVALID", + token = null, + clickIntent = null, + device = null, + active = true, + resumeAction = null) + +private val SMARTSPACE_KEY = "smartspace" + +@SmallTest +@TestableLooper.RunWithLooper(setAsMainLooper = true) +@RunWith(AndroidTestingRunner::class) +class MediaCarouselControllerTest : SysuiTestCase() { + + @Mock lateinit var mediaControlPanelFactory: Provider<MediaControlPanel> + @Mock lateinit var panel: MediaControlPanel + @Mock lateinit var visualStabilityManager: VisualStabilityManager + @Mock lateinit var mediaHostStatesManager: MediaHostStatesManager + @Mock lateinit var activityStarter: ActivityStarter + @Mock @Main private lateinit var executor: DelayableExecutor + @Mock lateinit var mediaDataManager: MediaDataManager + @Mock lateinit var configurationController: ConfigurationController + @Mock lateinit var falsingCollector: FalsingCollector + @Mock lateinit var falsingManager: FalsingManager + @Mock lateinit var dumpManager: DumpManager + + private val clock = FakeSystemClock() + private lateinit var mediaCarouselController: MediaCarouselController + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + + mediaCarouselController = MediaCarouselController( + context, + mediaControlPanelFactory, + visualStabilityManager, + mediaHostStatesManager, + activityStarter, + clock, + executor, + mediaDataManager, + configurationController, + falsingCollector, + falsingManager, + dumpManager + ) + + MediaPlayerData.clear() + } + + @Test + fun testPlayerOrdering() { + // Test values: key, data, last active time + val playingLocal = Triple("playing local", + DATA.copy(active = true, isPlaying = true, isLocalSession = true, resumption = false), + 4500L) + + val playingRemote = Triple("playing remote", + DATA.copy(active = true, isPlaying = true, isLocalSession = false, resumption = false), + 5000L) + + val pausedLocal = Triple("paused local", + DATA.copy(active = true, isPlaying = false, isLocalSession = true, resumption = false), + 1000L) + + val pausedRemote = Triple("paused remote", + DATA.copy(active = true, isPlaying = false, isLocalSession = false, resumption = false), + 2000L) + + val resume1 = Triple("resume 1", + DATA.copy(active = false, isPlaying = false, isLocalSession = true, resumption = true), + 500L) + + val resume2 = Triple("resume 2", + DATA.copy(active = false, isPlaying = false, isLocalSession = true, resumption = true), + 1000L) + + // Expected ordering for media players: + // Actively playing local sessions + // Actively playing remote sessions + // Paused sessions, by last active + // Resume controls, by last active + + val expected = listOf(playingLocal, playingRemote, pausedRemote, pausedLocal, resume2, + resume1) + + expected.forEach { + clock.setCurrentTimeMillis(it.third) + MediaPlayerData.addMediaPlayer(it.first, it.second.copy(notificationKey = it.first), + panel, clock) + } + + for ((index, key) in MediaPlayerData.playerKeys().withIndex()) { + assertEquals(expected.get(index).first, key.data.notificationKey) + } + } + + @Test + fun testOrderWithSmartspace_prioritized() { + testPlayerOrdering() + + // If smartspace is prioritized + MediaPlayerData.addMediaRecommendation(SMARTSPACE_KEY, EMPTY_SMARTSPACE_MEDIA_DATA, panel, + true, clock) + + // Then it should be shown immediately after any actively playing controls + assertTrue(MediaPlayerData.playerKeys().elementAt(2).isSsMediaRec) + } + + @Test + fun testOrderWithSmartspace_notPrioritized() { + testPlayerOrdering() + + // If smartspace is not prioritized + MediaPlayerData.addMediaRecommendation(SMARTSPACE_KEY, EMPTY_SMARTSPACE_MEDIA_DATA, panel, + false, clock) + + // Then it should be shown at the end of the carousel + val size = MediaPlayerData.playerKeys().size + assertTrue(MediaPlayerData.playerKeys().elementAt(size - 1).isSsMediaRec) + } +}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt index 28aed2085528..a435e7961b35 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt @@ -86,6 +86,7 @@ class MediaDataFilterTest : SysuiTestCase() { @Before fun setup() { MockitoAnnotations.initMocks(this) + MediaPlayerData.clear() mediaDataFilter = MediaDataFilter(context, broadcastDispatcher, mediaResumeListener, lockscreenUserManager, executor, clock) mediaDataFilter.mediaDataManager = mediaDataManager diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt index d864aaeadee3..2b2fc513d03c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt @@ -255,6 +255,7 @@ class MediaDataManagerTest : SysuiTestCase() { .onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true), eq(false)) assertThat(mediaDataCaptor.value.resumption).isTrue() + assertThat(mediaDataCaptor.value.isPlaying).isFalse() } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt index e9e965e92303..8dc9eff97ab9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt @@ -127,7 +127,7 @@ public class MediaPlayerDataTest : SysuiTestCase() { val players = MediaPlayerData.players() assertThat(players).hasSize(6) assertThat(players).containsExactly(playerIsPlaying, playerIsPlayingAndRemote, - playerIsStoppedAndLocal, playerCanResume, playerIsStoppedAndRemote, + playerIsStoppedAndRemote, playerIsStoppedAndLocal, playerCanResume, playerUndetermined).inOrder() } |