diff options
| author | 2024-09-26 12:59:49 +0000 | |
|---|---|---|
| committer | 2024-09-27 17:34:23 +0000 | |
| commit | d70ef66c1b95e8dad20558e6959c67ca0927cb04 (patch) | |
| tree | 02ce717ecb95cab2953f9293efc2b45b9b99b0d3 | |
| parent | c116e195287946ff45f27079216b5c23dd08322a (diff) | |
Send media view holder inflation to background
This CL handles the issues happened in b/271967119 when we tried to send
inflations to background thread.
It also makes sure that onMeasure get the right measurements in case
media view controllers are not yet in added.
Flag: com.android.systemui.media_controls_umo_inflation_in_background
Fixes: 368514198
Test: atest MediaCarouselControllerTest
Change-Id: I5f2974493ae9a6c46fd792ba9bdca856bc75d42a
5 files changed, 275 insertions, 151 deletions
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index c49ffb49a1da..c1d8d554acdf 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -1128,6 +1128,16 @@ flag { } flag { + name: "media_controls_umo_inflation_in_background" + namespace: "systemui" + description: "Inflate UMO in background thread" + bug: "368514198" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { namespace: "systemui" name: "enable_view_capture_tracing" description: "Enables view capture tracing in System UI." @@ -1431,4 +1441,4 @@ flag { metadata { purpose: PURPOSE_BUGFIX } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt index bb9517a14142..bbe3d241f007 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt @@ -16,6 +16,7 @@ package com.android.systemui.media.controls.ui.controller +import android.annotation.WorkerThread import android.app.PendingIntent import android.content.Context import android.content.Intent @@ -41,6 +42,7 @@ import com.android.internal.logging.InstanceId import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.Dumpable +import com.android.systemui.Flags.mediaControlsUmoInflationInBackground import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background @@ -136,7 +138,7 @@ constructor( private val activityStarter: ActivityStarter, private val systemClock: SystemClock, @Main private val mainDispatcher: CoroutineDispatcher, - @Main executor: DelayableExecutor, + @Main private val uiExecutor: DelayableExecutor, @Background private val bgExecutor: Executor, @Background private val backgroundDispatcher: CoroutineDispatcher, private val mediaManager: MediaDataManager, @@ -224,7 +226,7 @@ constructor( private var carouselLocale: Locale? = null private val animationScaleObserver: ContentObserver = - object : ContentObserver(executor, 0) { + object : ContentObserver(uiExecutor, 0) { override fun onChange(selfChange: Boolean) { if (!SceneContainerFlag.isEnabled) { MediaPlayerData.players().forEach { it.updateAnimatorDurationScale() } @@ -347,7 +349,7 @@ constructor( MediaCarouselScrollHandler( mediaCarousel, pageIndicator, - executor, + uiExecutor, this::onSwipeToDismiss, this::updatePageIndicatorLocation, this::updateSeekbarListening, @@ -455,7 +457,17 @@ constructor( isSsReactivated: Boolean, ) { debugLogger.logMediaLoaded(key, data.active) - if (addOrUpdatePlayer(key, oldKey, data, isSsReactivated)) { + val onUiExecutionEnd = + if (mediaControlsUmoInflationInBackground()) { + Runnable { + if (immediately) { + updateHostVisibility() + } + } + } else { + null + } + if (addOrUpdatePlayer(key, oldKey, data, isSsReactivated, onUiExecutionEnd)) { // Log card received if a new resumable media card is added MediaPlayerData.getMediaPlayer(key)?.let { logSmartspaceCardReported( @@ -970,6 +982,7 @@ constructor( oldKey: String?, data: MediaData, isSsReactivated: Boolean, + onUiExecutionEnd: Runnable? = null, ): Boolean = traceSection("MediaCarouselController#addOrUpdatePlayer") { MediaPlayerData.moveIfExists(oldKey, key) @@ -977,76 +990,119 @@ constructor( val curVisibleMediaKey = MediaPlayerData.visiblePlayerKeys() .elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex) - if (existingPlayer == null) { - val newPlayer = mediaControlPanelFactory.get() - if (SceneContainerFlag.isEnabled) { - newPlayer.mediaViewController.widthInSceneContainerPx = widthInSceneContainerPx - newPlayer.mediaViewController.heightInSceneContainerPx = - heightInSceneContainerPx - } - newPlayer.attachPlayer( - MediaViewHolder.create(LayoutInflater.from(context), mediaContent) - ) - newPlayer.mediaViewController.sizeChangedListener = this::updateCarouselDimensions - val lp = - LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT, - ) - newPlayer.mediaViewHolder?.player?.setLayoutParams(lp) - newPlayer.bindPlayer(data, key) - newPlayer.setListening( - mediaCarouselScrollHandler.visibleToUser && currentlyExpanded - ) - MediaPlayerData.addMediaPlayer( - key, - data, - newPlayer, - systemClock, - isSsReactivated, - debugLogger, - ) - updateViewControllerToState(newPlayer.mediaViewController, noAnimation = true) - // Media data added from a recommendation card should starts playing. - if ( - (shouldScrollToKey && data.isPlaying == true) || - (!shouldScrollToKey && data.active) - ) { - reorderAllPlayers(curVisibleMediaKey, key) + if (mediaControlsUmoInflationInBackground()) { + if (existingPlayer == null) { + bgExecutor.execute { + val mediaViewHolder = createMediaViewHolderInBg() + // Add the new player in the main thread. + uiExecutor.execute { + setupNewPlayer( + key, + data, + isSsReactivated, + curVisibleMediaKey, + mediaViewHolder, + ) + updatePageIndicator() + mediaCarouselScrollHandler.onPlayersChanged() + mediaFrame.requiresRemeasuring = true + onUiExecutionEnd?.run() + } + } } else { - needsReordering = true + updatePlayer(key, data, isSsReactivated, curVisibleMediaKey, existingPlayer) + updatePageIndicator() + mediaCarouselScrollHandler.onPlayersChanged() + mediaFrame.requiresRemeasuring = true + onUiExecutionEnd?.run() } } else { - existingPlayer.bindPlayer(data, key) - MediaPlayerData.addMediaPlayer( - key, - data, - existingPlayer, - systemClock, - isSsReactivated, - debugLogger, - ) - val packageName = MediaPlayerData.smartspaceMediaData?.packageName ?: String() - // In case of recommendations hits. - // Check the playing status of media player and the package name. - // To make sure we scroll to the right app's media player. - if ( - isReorderingAllowed || - shouldScrollToKey && - data.isPlaying == true && - packageName == data.packageName - ) { - reorderAllPlayers(curVisibleMediaKey, key) + if (existingPlayer == null) { + val mediaViewHolder = + MediaViewHolder.create(LayoutInflater.from(context), mediaContent) + setupNewPlayer(key, data, isSsReactivated, curVisibleMediaKey, mediaViewHolder) } else { - needsReordering = true + updatePlayer(key, data, isSsReactivated, curVisibleMediaKey, existingPlayer) } + updatePageIndicator() + mediaCarouselScrollHandler.onPlayersChanged() + mediaFrame.requiresRemeasuring = true + onUiExecutionEnd?.run() } - updatePageIndicator() - mediaCarouselScrollHandler.onPlayersChanged() - mediaFrame.requiresRemeasuring = true return existingPlayer == null } + private fun updatePlayer( + key: String, + data: MediaData, + isSsReactivated: Boolean, + curVisibleMediaKey: MediaPlayerData.MediaSortKey?, + existingPlayer: MediaControlPanel, + ) { + existingPlayer.bindPlayer(data, key) + MediaPlayerData.addMediaPlayer( + key, + data, + existingPlayer, + systemClock, + isSsReactivated, + debugLogger, + ) + val packageName = MediaPlayerData.smartspaceMediaData?.packageName ?: String() + // In case of recommendations hits. + // Check the playing status of media player and the package name. + // To make sure we scroll to the right app's media player. + if ( + isReorderingAllowed || + shouldScrollToKey && data.isPlaying == true && packageName == data.packageName + ) { + reorderAllPlayers(curVisibleMediaKey, key) + } else { + needsReordering = true + } + } + + private fun setupNewPlayer( + key: String, + data: MediaData, + isSsReactivated: Boolean, + curVisibleMediaKey: MediaPlayerData.MediaSortKey?, + mediaViewHolder: MediaViewHolder, + ) { + val newPlayer = mediaControlPanelFactory.get() + newPlayer.attachPlayer(mediaViewHolder) + newPlayer.mediaViewController.sizeChangedListener = + this@MediaCarouselController::updateCarouselDimensions + val lp = + LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT, + ) + newPlayer.mediaViewHolder?.player?.setLayoutParams(lp) + newPlayer.bindPlayer(data, key) + newPlayer.setListening(mediaCarouselScrollHandler.visibleToUser && currentlyExpanded) + MediaPlayerData.addMediaPlayer( + key, + data, + newPlayer, + systemClock, + isSsReactivated, + debugLogger, + ) + updateViewControllerToState(newPlayer.mediaViewController, noAnimation = true) + // Media data added from a recommendation card should starts playing. + if ((shouldScrollToKey && data.isPlaying == true) || (!shouldScrollToKey && data.active)) { + reorderAllPlayers(curVisibleMediaKey, key) + } else { + needsReordering = true + } + } + + @WorkerThread + private fun createMediaViewHolderInBg(): MediaViewHolder { + return MediaViewHolder.create(LayoutInflater.from(context), mediaContent) + } + private fun addSmartspaceMediaRecommendations( key: String, data: SmartspaceMediaData, @@ -1163,8 +1219,16 @@ constructor( val previousVisibleKey = MediaPlayerData.visiblePlayerKeys() .elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex) + val onUiExecutionEnd = Runnable { + if (recreateMedia) { + reorderAllPlayers(previousVisibleKey) + } + } - MediaPlayerData.mediaData().forEach { (key, data, isSsMediaRec) -> + val mediaDataList = MediaPlayerData.mediaData() + // Do not loop through the original list of media data because the re-addition of media data + // is being executed in background thread. + mediaDataList.forEach { (key, data, isSsMediaRec) -> if (isSsMediaRec) { val smartspaceMediaData = MediaPlayerData.smartspaceMediaData removePlayer(key, dismissMediaData = false, dismissRecommendation = false) @@ -1175,6 +1239,7 @@ constructor( MediaPlayerData.shouldPrioritizeSs, ) } + onUiExecutionEnd.run() } else { val isSsReactivated = MediaPlayerData.isSsReactivated(key) if (recreateMedia) { @@ -1185,11 +1250,9 @@ constructor( oldKey = null, data = data, isSsReactivated = isSsReactivated, + onUiExecutionEnd = onUiExecutionEnd, ) } - if (recreateMedia) { - reorderAllPlayers(previousVisibleKey) - } } } diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHostStatesManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHostStatesManager.kt index 8660d12bcb85..782da4bd6a41 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHostStatesManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHostStatesManager.kt @@ -17,6 +17,7 @@ package com.android.systemui.media.controls.ui.controller import com.android.app.tracing.traceSection +import com.android.systemui.Flags.mediaControlsUmoInflationInBackground import com.android.systemui.dagger.SysUISingleton import com.android.systemui.media.controls.ui.view.MediaHostState import com.android.systemui.util.animation.MeasurementOutput @@ -71,23 +72,34 @@ class MediaHostStatesManager @Inject constructor() { */ fun updateCarouselDimensions( @MediaLocation location: Int, - hostState: MediaHostState + hostState: MediaHostState, ): MeasurementOutput = traceSection("MediaHostStatesManager#updateCarouselDimensions") { val result = MeasurementOutput(0, 0) + var changed = false for (controller in controllers) { val measurement = controller.getMeasurementsForState(hostState) measurement?.let { if (it.measuredHeight > result.measuredHeight) { result.measuredHeight = it.measuredHeight + changed = true } if (it.measuredWidth > result.measuredWidth) { result.measuredWidth = it.measuredWidth + changed = true } } } - carouselSizes[location] = result - return result + if (mediaControlsUmoInflationInBackground()) { + // Set carousel size if result measurements changed. This avoids setting carousel + // size when this method gets called before the addition of media view controllers + if (!carouselSizes.contains(location) || changed) { + carouselSizes[location] = result + } + } else { + carouselSizes[location] = result + } + return carouselSizes[location] ?: result } /** Add a callback to be called when a MediaState has updated */ diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/view/MediaHost.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/view/MediaHost.kt index 09a618110f21..5ddc3470da43 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/view/MediaHost.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/view/MediaHost.kt @@ -20,6 +20,7 @@ import android.graphics.Rect import android.util.ArraySet import android.view.View import android.view.View.OnAttachStateChangeListener +import com.android.systemui.Flags.mediaControlsUmoInflationInBackground import com.android.systemui.media.controls.domain.pipeline.MediaDataManager import com.android.systemui.media.controls.shared.model.MediaData import com.android.systemui.media.controls.shared.model.SmartspaceMediaData @@ -91,8 +92,10 @@ class MediaHost( data: MediaData, immediately: Boolean, receivedSmartspaceCardLatency: Int, - isSsReactivated: Boolean + isSsReactivated: Boolean, ) { + if (mediaControlsUmoInflationInBackground()) return + if (immediately) { updateViewVisibility() } @@ -101,7 +104,7 @@ class MediaHost( override fun onSmartspaceMediaDataLoaded( key: String, data: SmartspaceMediaData, - shouldPrioritize: Boolean + shouldPrioritize: Boolean, ) { updateViewVisibility() } @@ -171,7 +174,7 @@ class MediaHost( input.widthMeasureSpec = View.MeasureSpec.makeMeasureSpec( View.MeasureSpec.getSize(input.widthMeasureSpec), - View.MeasureSpec.EXACTLY + View.MeasureSpec.EXACTLY, ) } // This will trigger a state change that ensures that we now have a state diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt index 03667cfb8a3b..570c64065c4a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt @@ -21,19 +21,19 @@ import android.content.res.ColorStateList import android.content.res.Configuration import android.database.ContentObserver import android.os.LocaleList +import android.platform.test.flag.junit.FlagsParameterization import android.provider.Settings import android.testing.TestableLooper import android.util.MathUtils.abs import android.view.View -import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.compose.animation.scene.ObservableTransitionState import com.android.compose.animation.scene.SceneKey import com.android.internal.logging.InstanceId import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback +import com.android.systemui.Flags.mediaControlsUmoInflationInBackground import com.android.systemui.SysuiTestCase -import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.dump.DumpManager import com.android.systemui.flags.DisableSceneContainer @@ -71,7 +71,6 @@ import com.android.systemui.statusbar.notification.collection.provider.OnReorder import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.testKosmos -import com.android.systemui.util.concurrency.DelayableExecutor import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.settings.GlobalSettings import com.android.systemui.util.settings.unconfinedDispatcherFakeSettings @@ -106,6 +105,8 @@ import org.mockito.MockitoAnnotations import org.mockito.kotlin.any import org.mockito.kotlin.capture import org.mockito.kotlin.eq +import platform.test.runner.parameterized.ParameterizedAndroidJunit4 +import platform.test.runner.parameterized.Parameters private val DATA = MediaTestUtils.emptyMediaData @@ -116,8 +117,8 @@ private const val PLAYING_LOCAL = "playing local" @ExperimentalCoroutinesApi @SmallTest @TestableLooper.RunWithLooper(setAsMainLooper = true) -@RunWith(AndroidJUnit4::class) -class MediaCarouselControllerTest : SysuiTestCase() { +@RunWith(ParameterizedAndroidJunit4::class) +class MediaCarouselControllerTest(flags: FlagsParameterization) : SysuiTestCase() { private val kosmos = testKosmos() private val testDispatcher = kosmos.unconfinedTestDispatcher private val secureSettings = kosmos.unconfinedDispatcherFakeSettings @@ -129,7 +130,6 @@ class MediaCarouselControllerTest : SysuiTestCase() { @Mock lateinit var mediaHostStatesManager: MediaHostStatesManager @Mock lateinit var mediaHostState: MediaHostState @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 falsingManager: FalsingManager @@ -153,16 +153,33 @@ class MediaCarouselControllerTest : SysuiTestCase() { private val clock = FakeSystemClock() private lateinit var bgExecutor: FakeExecutor + private lateinit var uiExecutor: FakeExecutor private lateinit var mediaCarouselController: MediaCarouselController private var originalResumeSetting = Settings.Secure.getInt(context.contentResolver, Settings.Secure.MEDIA_CONTROLS_RESUME, 1) + companion object { + @JvmStatic + @Parameters(name = "{0}") + fun getParams(): List<FlagsParameterization> { + return FlagsParameterization.progressionOf( + com.android.systemui.Flags.FLAG_MEDIA_CONTROLS_UMO_INFLATION_IN_BACKGROUND + ) + } + } + + init { + mSetFlagsRule.setFlagsParameterization(flags) + } + @Before fun setup() { MockitoAnnotations.initMocks(this) context.resources.configuration.setLocales(LocaleList(Locale.US, Locale.UK)) bgExecutor = FakeExecutor(clock) + uiExecutor = FakeExecutor(clock) + mediaCarouselController = MediaCarouselController( applicationScope = kosmos.applicationCoroutineScope, @@ -173,7 +190,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { activityStarter = activityStarter, systemClock = clock, mainDispatcher = kosmos.testDispatcher, - executor = executor, + uiExecutor = uiExecutor, bgExecutor = bgExecutor, backgroundDispatcher = testDispatcher, mediaManager = mediaDataManager, @@ -201,10 +218,11 @@ class MediaCarouselControllerTest : SysuiTestCase() { whenever(mediaFlags.isPersistentSsCardEnabled()).thenReturn(false) MediaPlayerData.clear() FakeExecutor.exhaustExecutors(bgExecutor) + FakeExecutor.exhaustExecutors(uiExecutor) verify(globalSettings) .registerContentObserverSync( eq(Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE)), - capture(settingsObserverCaptor) + capture(settingsObserverCaptor), ) } @@ -213,7 +231,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { Settings.Secure.putInt( context.contentResolver, Settings.Secure.MEDIA_CONTROLS_RESUME, - originalResumeSetting + originalResumeSetting, ) } @@ -227,9 +245,9 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = true, isPlaying = true, playbackLocation = MediaData.PLAYBACK_LOCAL, - resumption = false + resumption = false, ), - 4500L + 4500L, ) val playingCast = @@ -239,9 +257,9 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = true, isPlaying = true, playbackLocation = MediaData.PLAYBACK_CAST_LOCAL, - resumption = false + resumption = false, ), - 5000L + 5000L, ) val pausedLocal = @@ -251,9 +269,9 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = true, isPlaying = false, playbackLocation = MediaData.PLAYBACK_LOCAL, - resumption = false + resumption = false, ), - 1000L + 1000L, ) val pausedCast = @@ -263,9 +281,9 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = true, isPlaying = false, playbackLocation = MediaData.PLAYBACK_CAST_LOCAL, - resumption = false + resumption = false, ), - 2000L + 2000L, ) val playingRcn = @@ -275,9 +293,9 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = true, isPlaying = true, playbackLocation = MediaData.PLAYBACK_CAST_REMOTE, - resumption = false + resumption = false, ), - 5000L + 5000L, ) val pausedRcn = @@ -287,9 +305,9 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = true, isPlaying = false, playbackLocation = MediaData.PLAYBACK_CAST_REMOTE, - resumption = false + resumption = false, ), - 5000L + 5000L, ) val active = @@ -299,9 +317,9 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = true, isPlaying = false, playbackLocation = MediaData.PLAYBACK_LOCAL, - resumption = true + resumption = true, ), - 250L + 250L, ) val resume1 = @@ -311,9 +329,9 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = false, isPlaying = false, playbackLocation = MediaData.PLAYBACK_LOCAL, - resumption = true + resumption = true, ), - 500L + 500L, ) val resume2 = @@ -323,9 +341,9 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = false, isPlaying = false, playbackLocation = MediaData.PLAYBACK_LOCAL, - resumption = true + resumption = true, ), - 1000L + 1000L, ) val activeMoreRecent = @@ -336,9 +354,9 @@ class MediaCarouselControllerTest : SysuiTestCase() { isPlaying = false, playbackLocation = MediaData.PLAYBACK_LOCAL, resumption = true, - lastActive = 2L + lastActive = 2L, ), - 1000L + 1000L, ) val activeLessRecent = @@ -349,9 +367,9 @@ class MediaCarouselControllerTest : SysuiTestCase() { isPlaying = false, playbackLocation = MediaData.PLAYBACK_LOCAL, resumption = true, - lastActive = 1L + lastActive = 1L, ), - 1000L + 1000L, ) // Expected ordering for media players: // Actively playing local sessions @@ -370,7 +388,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { pausedRcn, active, resume2, - resume1 + resume1, ) expected.forEach { @@ -380,7 +398,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { it.second.copy(notificationKey = it.first), panel, clock, - isSsReactivated = false + isSsReactivated = false, ) } @@ -403,7 +421,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { EMPTY_SMARTSPACE_MEDIA_DATA.copy(isActive = true), panel, true, - clock + clock, ) // Then it should be shown immediately after any actively playing controls @@ -421,7 +439,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { listener.value.onSmartspaceMediaDataLoaded( SMARTSPACE_KEY, EMPTY_SMARTSPACE_MEDIA_DATA.copy(isActive = true), - true + true, ) // Then it should be shown immediately after any actively playing controls @@ -439,7 +457,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { EMPTY_SMARTSPACE_MEDIA_DATA.copy(isActive = true), panel, false, - clock + clock, ) // Then it should be shown at the end of the carousel's active entries @@ -461,8 +479,8 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = true, isPlaying = true, playbackLocation = MediaData.PLAYBACK_LOCAL, - resumption = false - ) + resumption = false, + ), ) listener.value.onMediaDataLoaded( PLAYING_LOCAL, @@ -471,19 +489,20 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = true, isPlaying = false, playbackLocation = MediaData.PLAYBACK_LOCAL, - resumption = true - ) + resumption = true, + ), ) + runAllReady() assertEquals( MediaPlayerData.getMediaPlayerIndex(PAUSED_LOCAL), - mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex + mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex, ) // paused player order should stays the same in visibleMediaPLayer map. // paused player order should be first in mediaPlayer map. assertEquals( MediaPlayerData.visiblePlayerKeys().elementAt(3), - MediaPlayerData.playerKeys().elementAt(0) + MediaPlayerData.playerKeys().elementAt(0), ) } @@ -506,7 +525,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { mediaCarouselController.onDesiredLocationChanged( LOCATION_QS, mediaHostState, - animate = false + animate = false, ) bgExecutor.runAllReady() verify(logger).logCarouselPosition(LOCATION_QS) @@ -517,7 +536,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { mediaCarouselController.onDesiredLocationChanged( MediaHierarchyManager.LOCATION_QQS, mediaHostState, - animate = false + animate = false, ) bgExecutor.runAllReady() verify(logger).logCarouselPosition(MediaHierarchyManager.LOCATION_QQS) @@ -528,7 +547,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { mediaCarouselController.onDesiredLocationChanged( MediaHierarchyManager.LOCATION_LOCKSCREEN, mediaHostState, - animate = false + animate = false, ) bgExecutor.runAllReady() verify(logger).logCarouselPosition(MediaHierarchyManager.LOCATION_LOCKSCREEN) @@ -539,7 +558,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { mediaCarouselController.onDesiredLocationChanged( MediaHierarchyManager.LOCATION_DREAM_OVERLAY, mediaHostState, - animate = false + animate = false, ) bgExecutor.runAllReady() verify(logger).logCarouselPosition(MediaHierarchyManager.LOCATION_DREAM_OVERLAY) @@ -570,8 +589,8 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = true, isPlaying = true, playbackLocation = MediaData.PLAYBACK_LOCAL, - resumption = false - ) + resumption = false, + ), ) listener.value.onMediaDataLoaded( PAUSED_LOCAL, @@ -580,14 +599,15 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = true, isPlaying = false, playbackLocation = MediaData.PLAYBACK_LOCAL, - resumption = false - ) + resumption = false, + ), ) + runAllReady() // adding a media recommendation card. listener.value.onSmartspaceMediaDataLoaded( SMARTSPACE_KEY, EMPTY_SMARTSPACE_MEDIA_DATA, - false + false, ) mediaCarouselController.shouldScrollToKey = true // switching between media players. @@ -598,8 +618,8 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = true, isPlaying = false, playbackLocation = MediaData.PLAYBACK_LOCAL, - resumption = true - ) + resumption = true, + ), ) listener.value.onMediaDataLoaded( PAUSED_LOCAL, @@ -608,13 +628,14 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = true, isPlaying = true, playbackLocation = MediaData.PLAYBACK_LOCAL, - resumption = false - ) + resumption = false, + ), ) + runAllReady() assertEquals( MediaPlayerData.getMediaPlayerIndex(PAUSED_LOCAL), - mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex + mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex, ) } @@ -626,7 +647,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { listener.value.onSmartspaceMediaDataLoaded( SMARTSPACE_KEY, EMPTY_SMARTSPACE_MEDIA_DATA.copy(packageName = "PACKAGE_NAME", isActive = true), - false + false, ) listener.value.onMediaDataLoaded( PLAYING_LOCAL, @@ -635,14 +656,15 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = true, isPlaying = true, playbackLocation = MediaData.PLAYBACK_LOCAL, - resumption = false - ) + resumption = false, + ), ) + runAllReady() var playerIndex = MediaPlayerData.getMediaPlayerIndex(PLAYING_LOCAL) assertEquals( playerIndex, - mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex + mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex, ) assertEquals(playerIndex, 0) @@ -657,9 +679,10 @@ class MediaCarouselControllerTest : SysuiTestCase() { isPlaying = true, playbackLocation = MediaData.PLAYBACK_LOCAL, resumption = false, - packageName = "PACKAGE_NAME" - ) + packageName = "PACKAGE_NAME", + ), ) + runAllReady() playerIndex = MediaPlayerData.getMediaPlayerIndex(PLAYING_LOCAL) assertEquals(playerIndex, 0) } @@ -704,7 +727,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { player1.second.copy(notificationKey = player1.first), panel, clock, - isSsReactivated = false + isSsReactivated = false, ) assertEquals(mediaCarouselController.getCurrentVisibleMediaContentIntent(), clickIntent1) @@ -717,7 +740,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { player2.second.copy(notificationKey = player2.first), panel, clock, - isSsReactivated = false + isSsReactivated = false, ) // mediaCarouselScrollHandler.visibleMediaIndex is unchanged (= 0), and the new player is @@ -732,7 +755,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { player3.second.copy(notificationKey = player3.first), panel, clock, - isSsReactivated = false + isSsReactivated = false, ) // mediaCarouselScrollHandler.visibleMediaIndex is unchanged (= 0), and the new player is @@ -822,7 +845,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { listener.value.onSmartspaceMediaDataLoaded( SMARTSPACE_KEY, EMPTY_SMARTSPACE_MEDIA_DATA.copy(isActive = true), - true + true, ) // Then the carousel is updated @@ -841,7 +864,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { listener.value.onSmartspaceMediaDataLoaded( SMARTSPACE_KEY, EMPTY_SMARTSPACE_MEDIA_DATA, - false + false, ) // Then it is added to the carousel with correct state @@ -886,7 +909,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { transitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE, - this + this, ) verify(mediaCarousel).visibility = View.VISIBLE @@ -932,7 +955,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { transitionRepository.sendTransitionSteps( from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN, - this + this, ) assertEquals(true, updatedVisibility) @@ -961,7 +984,7 @@ class MediaCarouselControllerTest : SysuiTestCase() { transitionRepository.sendTransitionSteps( from = KeyguardState.GONE, to = KeyguardState.LOCKSCREEN, - this + this, ) assertEquals(true, updatedVisibility) @@ -1125,12 +1148,14 @@ class MediaCarouselControllerTest : SysuiTestCase() { Settings.Secure.putInt(context.contentResolver, Settings.Secure.MEDIA_CONTROLS_RESUME, 0) val pausedMedia = DATA.copy(isPlaying = false) listener.value.onMediaDataLoaded(PAUSED_LOCAL, PAUSED_LOCAL, pausedMedia) + runAllReady() mediaCarouselController.onSwipeToDismiss() // When it can be removed immediately on update whenever(visualStabilityProvider.isReorderingAllowed).thenReturn(true) val inactiveMedia = pausedMedia.copy(active = false) listener.value.onMediaDataLoaded(PAUSED_LOCAL, PAUSED_LOCAL, inactiveMedia) + runAllReady() // This is processed as a user-initiated dismissal verify(debugLogger).logMediaRemoved(eq(PAUSED_LOCAL), eq(true)) @@ -1148,12 +1173,14 @@ class MediaCarouselControllerTest : SysuiTestCase() { val pausedMedia = DATA.copy(isPlaying = false) listener.value.onMediaDataLoaded(PAUSED_LOCAL, PAUSED_LOCAL, pausedMedia) + runAllReady() mediaCarouselController.onSwipeToDismiss() // When it can't be removed immediately on update whenever(visualStabilityProvider.isReorderingAllowed).thenReturn(false) val inactiveMedia = pausedMedia.copy(active = false) listener.value.onMediaDataLoaded(PAUSED_LOCAL, PAUSED_LOCAL, inactiveMedia) + runAllReady() visualStabilityCallback.value.onReorderingAllowed() // This is processed as a user-initiated dismissal @@ -1175,8 +1202,8 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = true, isPlaying = true, playbackLocation = MediaData.PLAYBACK_LOCAL, - resumption = false - ) + resumption = false, + ), ) listener.value.onMediaDataLoaded( PAUSED_LOCAL, @@ -1185,18 +1212,20 @@ class MediaCarouselControllerTest : SysuiTestCase() { active = true, isPlaying = false, playbackLocation = MediaData.PLAYBACK_LOCAL, - resumption = false - ) + resumption = false, + ), ) + runAllReady() val playersSize = MediaPlayerData.players().size reset(pageIndicator) function() + runAllReady() assertEquals(playersSize, MediaPlayerData.players().size) assertEquals( MediaPlayerData.getMediaPlayerIndex(PLAYING_LOCAL), - mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex + mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex, ) } @@ -1225,4 +1254,11 @@ class MediaCarouselControllerTest : SysuiTestCase() { ) runCurrent() } + + private fun runAllReady() { + if (mediaControlsUmoInflationInBackground()) { + bgExecutor.runAllReady() + uiExecutor.runAllReady() + } + } } |