Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d0d4a05 authored by Michael Mikhail's avatar Michael Mikhail
Browse files

[Flexiglass] Clean code in MediaCarouselController

Flag: com.android.systemui.scene_container
Bug: 436384980
Test: Build.
Change-Id: I4c520d438f441636023d0c7e8c6638968549be47
parent 48d2463d
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -17,13 +17,16 @@
package com.android.systemui.media.controls.ui.view

import android.content.res.Resources
import android.platform.test.annotations.DisableFlags
import android.testing.TestableLooper
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.media.controls.util.MediaUiEventLogger
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.qs.PageIndicator
@@ -48,6 +51,8 @@ import org.mockito.kotlin.whenever
@SmallTest
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@RunWith(AndroidJUnit4::class)
@DisableSceneContainer
@DisableFlags(Flags.FLAG_MEDIA_CONTROLS_IN_COMPOSE)
class MediaCarouselScrollHandlerTest : SysuiTestCase() {

    private val carouselWidth = 1038
+21 −6
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import com.android.systemui.media.controls.ui.view.MediaHostState
import com.android.systemui.media.controls.ui.view.qqsMediaHost
import com.android.systemui.media.controls.ui.view.qsMediaHost
import com.android.systemui.media.remedia.data.repository.setHasMedia
import com.android.systemui.media.remedia.shared.flag.MediaControlsInComposeFlag
import com.android.systemui.qs.composefragment.viewmodel.MediaState.ACTIVE_MEDIA
import com.android.systemui.qs.composefragment.viewmodel.MediaState.ANY_MEDIA
import com.android.systemui.qs.composefragment.viewmodel.MediaState.NO_MEDIA
@@ -236,6 +237,7 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
        }

    @Test
    @DisableFlags(Flags.FLAG_MEDIA_CONTROLS_IN_COMPOSE)
    fun qqsMediaHost_initializedCorrectly() =
        with(kosmos) {
            testScope.testWithinLifecycle {
@@ -248,6 +250,7 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
        }

    @Test
    @DisableFlags(Flags.FLAG_MEDIA_CONTROLS_IN_COMPOSE)
    fun qsMediaHost_initializedCorrectly() =
        with(kosmos) {
            testScope.testWithinLifecycle {
@@ -263,9 +266,10 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
    fun qqsMediaVisible_onlyWhenActiveMedia() =
        with(kosmos) {
            testScope.testWithinLifecycle {
                if (!MediaControlsInComposeFlag.isEnabled) {
                    whenever(mediaCarouselController.isLockedAndHidden()).thenReturn(false)

                    assertThat(underTest.qqsMediaVisible).isEqualTo(underTest.qqsMediaHost.visible)
                }

                setMediaState(NO_MEDIA)
                assertThat(underTest.qqsMediaVisible).isFalse()
@@ -282,9 +286,10 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
    fun qsMediaVisible_onAnyMedia() =
        with(kosmos) {
            testScope.testWithinLifecycle {
                if (!MediaControlsInComposeFlag.isEnabled) {
                    whenever(mediaCarouselController.isLockedAndHidden()).thenReturn(false)

                    assertThat(underTest.qsMediaVisible).isEqualTo(underTest.qsMediaHost.visible)
                }

                setMediaState(NO_MEDIA)
                assertThat(underTest.qsMediaVisible).isFalse()
@@ -357,6 +362,7 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
        }

    @Test
    @DisableFlags(Flags.FLAG_MEDIA_CONTROLS_IN_COMPOSE)
    fun qqsMediaExpansion_collapsedMediaInLandscape() =
        with(kosmos) {
            testScope.testWithinLifecycle {
@@ -372,6 +378,7 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
        }

    @Test
    @DisableFlags(Flags.FLAG_MEDIA_CONTROLS_IN_COMPOSE)
    fun qqsMediaExpansion_notCollapsedMediaInLandscape_alwaysExpanded() =
        with(kosmos) {
            testScope.testWithinLifecycle {
@@ -387,6 +394,7 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
        }

    @Test
    @DisableFlags(Flags.FLAG_MEDIA_CONTROLS_IN_COMPOSE)
    fun qqsMediaExpansion_reactsToChangesInCollapsedMediaInLandscape() =
        with(kosmos) {
            testScope.testWithinLifecycle {
@@ -402,6 +410,7 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
        }

    @Test
    @DisableFlags(Flags.FLAG_MEDIA_CONTROLS_IN_COMPOSE)
    fun applyQsScrollPositionForClipping() =
        with(kosmos) {
            testScope.testWithinLifecycle {
@@ -418,6 +427,7 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
        }

    @Test
    @DisableFlags(Flags.FLAG_MEDIA_CONTROLS_IN_COMPOSE)
    fun shouldUpdateMediaSquishiness_inSplitShadeFalse_mediaSquishinessSet() =
        with(kosmos) {
            testScope.testWithinLifecycle {
@@ -436,6 +446,7 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
        }

    @Test
    @DisableFlags(Flags.FLAG_MEDIA_CONTROLS_IN_COMPOSE)
    fun inSplitShade_differentStatusBarState_mediaSquishinessSet() =
        with(kosmos) {
            testScope.testWithinLifecycle {
@@ -457,6 +468,7 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
        }

    @Test
    @DisableFlags(Flags.FLAG_MEDIA_CONTROLS_IN_COMPOSE)
    fun disappearParams() =
        with(kosmos) {
            testScope.testWithinLifecycle {
@@ -570,6 +582,9 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
            val activeMedia = state == ACTIVE_MEDIA
            val anyMedia = state != NO_MEDIA
            setHasMedia(visible = anyMedia, active = activeMedia)

            if (MediaControlsInComposeFlag.isEnabled) return

            whenever(legacyMediaDataManagerImpl.hasActiveMedia()).thenReturn(activeMedia)
            whenever(legacyMediaDataManagerImpl.hasAnyMedia()).thenReturn(anyMedia)
            qqsMediaHost.showsOnlyActiveMedia = true
+105 −386

File changed.

Preview size limit exceeded, changes collapsed.

+34 −29
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import androidx.annotation.VisibleForTesting
import com.android.app.animation.Interpolators
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.app.tracing.traceSection
import com.android.keyguard.KeyguardViewController
import com.android.systemui.Dumpable
import com.android.systemui.communal.ui.viewmodel.CommunalTransitionViewModel
import com.android.systemui.dagger.SysUISingleton
@@ -51,10 +50,10 @@ import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.dream.MediaDreamComplication
import com.android.systemui.media.remedia.shared.flag.MediaControlsInComposeFlag
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.CrossFadeHelper
@@ -112,14 +111,13 @@ constructor(
    private val bypassController: KeyguardBypassController,
    private val mediaCarouselController: MediaCarouselController,
    private val mediaManager: MediaDataManager,
    private val keyguardViewController: KeyguardViewController,
    private val dreamOverlayStateController: DreamOverlayStateController,
    private val keyguardInteractor: KeyguardInteractor,
    private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
    communalTransitionViewModel: CommunalTransitionViewModel,
    @ShadeDisplayAware configurationController: ConfigurationController,
    wakefulnessLifecycle: WakefulnessLifecycle,
    shadeInteractor: ShadeInteractor,
    private val communalTransitionViewModel: CommunalTransitionViewModel,
    @ShadeDisplayAware private val configurationController: ConfigurationController,
    private val wakefulnessLifecycle: WakefulnessLifecycle,
    private val shadeInteractor: ShadeInteractor,
    private val secureSettings: SecureSettings,
    @Background private val handler: Handler,
    @Application private val coroutineScope: CoroutineScope,
@@ -503,6 +501,12 @@ constructor(

    init {
        dumpManager.registerNormalDumpable(TAG, this)
        setUpListenersAndCallbacks()
    }

    private fun setUpListenersAndCallbacks() {
        if (MediaControlsInComposeFlag.isEnabled) return

        updateConfiguration()
        configurationController.addCallback(
            object : ConfigurationController.ConfigurationListener {
@@ -515,15 +519,18 @@ constructor(
        statusBarStateController.addCallback(
            object : StatusBarStateController.StateListener {
                override fun onStatePreChange(oldState: Int, newState: Int) {
                    // We're updating the location before the state change happens, since we want
                    // the location of the previous state to still be up to date when the animation
                    // We're updating the location before the state change happens, since we
                    // want
                    // the location of the previous state to still be up to date when the
                    // animation
                    // starts
                    if (
                        newState == StatusBarState.SHADE_LOCKED &&
                            oldState == StatusBarState.KEYGUARD &&
                            fullShadeTransitionProgress < 1.0f
                    ) {
                        // Since the new state is SHADE_LOCKED, we need to set the transition amount
                        // Since the new state is SHADE_LOCKED, we need to set the transition
                        // amount
                        // to maximum if the progress is not 1f.
                        setTransitionToFullShadeAmount(distanceForFullShadeTransition.toFloat())
                    }
@@ -658,15 +665,18 @@ constructor(
            UserHandle.USER_ALL,
        )

        // Listen to the communal UI state. Make sure that communal UI is showing and hub itself is
        // Listen to the communal UI state. Make sure that communal UI is showing and hub itself
        // is
        // available, ie. not disabled and able to be shown.
        // When dreaming, qs expansion is immediately set to 1f, so we listen to shade expansion to
        // When dreaming, qs expansion is immediately set to 1f, so we listen to shade expansion
        // to
        // calculate the new location.
        coroutineScope.launch {
            combine(
                    communalTransitionViewModel.isUmoOnCommunal,
                    keyguardInteractor.isDreaming,
                    // keep on communal before the shade is expanded enough to show the elements in
                    // keep on communal before the shade is expanded enough to show the elements
                    // in
                    // QS
                    shadeInteractor.shadeExpansion
                        .mapLatest { it < EXPANSION_THRESHOLD }
@@ -720,6 +730,8 @@ constructor(

    /** Close the guts in all players in [MediaCarouselController]. */
    fun closeGuts() {
        if (MediaControlsInComposeFlag.isEnabled) return

        mediaCarouselController.closeGuts()
    }

@@ -757,6 +769,8 @@ constructor(
        forceStateUpdate: Boolean = false,
    ) =
        traceSection("MediaHierarchyManager#updateDesiredLocation") {
            if (MediaControlsInComposeFlag.isEnabled) return

            val desiredLocation = calculateLocation()
            if (
                desiredLocation != this.desiredLocation || forceStateUpdate && !blockLocationChanges
@@ -1129,6 +1143,8 @@ constructor(
        clipBounds: Rect = EMPTY_RECT,
    ) =
        traceSection("MediaHierarchyManager#applyState") {
            if (MediaControlsInComposeFlag.isEnabled) return

            currentBounds.set(bounds)
            currentClipping = clipBounds
            carouselAlpha = if (isCurrentlyFading()) alpha else 1.0f
@@ -1159,17 +1175,7 @@ constructor(

    private fun updateHostAttachment() =
        traceSection("MediaHierarchyManager#updateHostAttachment") {
            if (SceneContainerFlag.isEnabled) {
                // No need to manage transition states - just update the desired location directly
                val host = getHost(desiredLocation)
                logger.logMediaHostAttachment(desiredLocation, host?.visible)
                mediaCarouselController.onDesiredLocationChanged(
                    desiredLocation = desiredLocation,
                    desiredHostState = host,
                    animate = false,
                )
                return
            }
            if (MediaControlsInComposeFlag.isEnabled) return

            var newLocation = resolveLocationForFading()
            // Don't use the overlay when fading or when we don't have active media
@@ -1342,6 +1348,8 @@ constructor(

    /** Update whether or not the media carousel could be visible to the user */
    private fun updateUserVisibility() {
        if (MediaControlsInComposeFlag.isEnabled) return

        val shadeVisible =
            isLockScreenVisibleToUser() ||
                isHomeScreenShadeVisibleToUser() ||
@@ -1373,9 +1381,7 @@ constructor(
    override fun dump(pw: PrintWriter, args: Array<out String>) {
        pw.apply {
            println(
                "current attachment: $currentAttachmentLocation, " +
                    "desired location: $desiredLocation, " +
                    "visible ${getHost(desiredLocation)?.visible}"
                "current attachment: $currentAttachmentLocation, desired location: $desiredLocation, visible ${getHost(desiredLocation)?.visible}"
            )
            println("previous location: $previousLocation")
            println("bounds: $currentBounds, target $targetBounds")
@@ -1384,8 +1390,7 @@ constructor(
            println("Host bounds:")
            mediaHosts.forEachIndexed { location, host ->
                println(
                    "\t$location: bounds ${host?.currentBounds}" +
                        ", clipping ${host?.currentClipping}"
                    "\t$location: bounds ${host?.currentBounds}, clipping ${host?.currentClipping}"
                )
            }
        }
+17 −14
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import com.android.settingslib.Utils
import com.android.systemui.Gefingerpoken
import com.android.systemui.classifier.Classifier.MEDIA_CAROUSEL_SWIPE
import com.android.systemui.media.controls.util.MediaUiEventLogger
import com.android.systemui.media.remedia.shared.flag.MediaControlsInComposeFlag
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.qs.PageIndicator
import com.android.systemui.res.R
@@ -202,9 +203,10 @@ class MediaCarouselScrollHandler(

    init {
        gestureDetector = GestureDetector(scrollView.context, gestureListener)
        mediaContent = scrollView.contentContainer
        if (!MediaControlsInComposeFlag.isEnabled) {
            scrollView.touchListener = touchListener
            scrollView.setOverScrollMode(View.OVER_SCROLL_NEVER)
        mediaContent = scrollView.contentContainer
            scrollView.setOnScrollChangeListener(scrollChangedListener)
            scrollView.outlineProvider =
                object : ViewOutlineProvider() {
@@ -219,6 +221,7 @@ class MediaCarouselScrollHandler(
                    }
                }
        }
    }

    fun onSettingsButtonUpdated(button: View) {
        settingsButton = button
Loading