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

Commit ba22f5f6 authored by Fabián Kozynski's avatar Fabián Kozynski
Browse files

Prevent creating NPVC in other users

The BrightnessDialog could be created for a secondary user (separate bug
to address that). This would cause NPVC (as a
BrightnessMirrorShowingInteractor) to be created on a secondary user,
which leads to crashes.

Instead, prevent creation of the interactor when we don't need the
mirror (i.e. BrightnessDialog). Also, use a passthrough interactor if we
need it in other process (as we don't need NPVC animations).

Test: manual, no crashes in secondary user
Test: atest BrightnessSliderViewModelTest
Flag: com.android.systemui.qs_ui_refactor_compose_fragment
Fixes: 407920471
Change-Id: I4de84dd5ba495fab4d420e90ed62420281461dce
parent caf93858
Loading
Loading
Loading
Loading
+45 −16
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@ import com.android.systemui.classifier.domain.interactor.falsingInteractor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.graphics.imageLoader
import com.android.systemui.graphics.imageLoader
import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory
import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.testScope
import com.android.systemui.lifecycle.activateIn
import com.android.systemui.lifecycle.activateIn
import com.android.systemui.res.R
import com.android.systemui.res.R
@@ -51,20 +52,9 @@ class BrightnessSliderViewModelTest : SysuiTestCase() {


    private val kosmos = testKosmos()
    private val kosmos = testKosmos()


    private val underTest by lazy {
    private var brightnessMirrorInteractorRetrieved = false
        with(kosmos) {

            BrightnessSliderViewModel(
    private val underTest by lazy { kosmos.create(true) }
                screenBrightnessInteractor,
                brightnessPolicyEnforcementInteractor,
                sliderHapticsViewModelFactory,
                brightnessMirrorShowingInteractor,
                falsingInteractor,
                supportsMirroring = true,
                brightnessWarningToast,
                imageLoader,
            )
        }
    }


    @Before
    @Before
    fun setUp() {
    fun setUp() {
@@ -72,13 +62,14 @@ class BrightnessSliderViewModelTest : SysuiTestCase() {
            LinearBrightness(minBrightness),
            LinearBrightness(minBrightness),
            LinearBrightness(maxBrightness),
            LinearBrightness(maxBrightness),
        )
        )
        underTest.activateIn(kosmos.testScope)
    }
    }


    @Test
    @Test
    fun brightnessChangeInRepository_changeInFlow() =
    fun brightnessChangeInRepository_changeInFlow() =
        with(kosmos) {
        with(kosmos) {
            testScope.runTest {
            testScope.runTest {
                underTest.activateIn(this)

                var brightness = 0.6f
                var brightness = 0.6f
                fakeScreenBrightnessRepository.setBrightness(LinearBrightness(brightness))
                fakeScreenBrightnessRepository.setBrightness(LinearBrightness(brightness))
                runCurrent()
                runCurrent()
@@ -123,6 +114,8 @@ class BrightnessSliderViewModelTest : SysuiTestCase() {
    fun dragging_temporaryBrightnessSet_currentBrightnessDoesntChange() =
    fun dragging_temporaryBrightnessSet_currentBrightnessDoesntChange() =
        with(kosmos) {
        with(kosmos) {
            testScope.runTest {
            testScope.runTest {
                underTest.activateIn(this)

                val temporaryBrightness by
                val temporaryBrightness by
                    collectLastValue(fakeScreenBrightnessRepository.temporaryBrightness)
                    collectLastValue(fakeScreenBrightnessRepository.temporaryBrightness)


@@ -148,6 +141,8 @@ class BrightnessSliderViewModelTest : SysuiTestCase() {
    fun draggingStopped_currentBrightnessChanges() =
    fun draggingStopped_currentBrightnessChanges() =
        with(kosmos) {
        with(kosmos) {
            testScope.runTest {
            testScope.runTest {
                underTest.activateIn(this)

                val newBrightness = underTest.maxBrightness.value / 3
                val newBrightness = underTest.maxBrightness.value / 3
                val drag = Drag.Stopped(GammaBrightness(newBrightness))
                val drag = Drag.Stopped(GammaBrightness(newBrightness))


@@ -180,6 +175,8 @@ class BrightnessSliderViewModelTest : SysuiTestCase() {
    fun supportedMirror_mirrorShowingWhenDragging() =
    fun supportedMirror_mirrorShowingWhenDragging() =
        with(kosmos) {
        with(kosmos) {
            testScope.runTest {
            testScope.runTest {
                underTest.activateIn(this)

                val mirrorInInteractor by
                val mirrorInInteractor by
                    collectLastValue(brightnessMirrorShowingInteractor.isShowing)
                    collectLastValue(brightnessMirrorShowingInteractor.isShowing)


@@ -200,7 +197,8 @@ class BrightnessSliderViewModelTest : SysuiTestCase() {
                val mirrorInInteractor by
                val mirrorInInteractor by
                    collectLastValue(brightnessMirrorShowingInteractor.isShowing)
                    collectLastValue(brightnessMirrorShowingInteractor.isShowing)


                val noMirrorViewModel = brightnessSliderViewModelFactory.create(false)
                val noMirrorViewModel = create(false)
                noMirrorViewModel.activateIn(this)


                noMirrorViewModel.setIsDragging(true)
                noMirrorViewModel.setIsDragging(true)
                assertThat(mirrorInInteractor).isEqualTo(false)
                assertThat(mirrorInInteractor).isEqualTo(false)
@@ -211,4 +209,35 @@ class BrightnessSliderViewModelTest : SysuiTestCase() {
                assertThat(noMirrorViewModel.showMirror).isEqualTo(false)
                assertThat(noMirrorViewModel.showMirror).isEqualTo(false)
            }
            }
        }
        }

    @Test
    fun unsupportedMirror_interactorNeverRetrieved() {
        with(kosmos) {
            runTest {
                val noMirrorViewModel = brightnessSliderViewModelFactory.create(false)
                noMirrorViewModel.activateIn(this)

                noMirrorViewModel.setIsDragging(true)
                noMirrorViewModel.setIsDragging(false)

                assertThat(brightnessMirrorInteractorRetrieved).isFalse()
            }
        }
    }

    private fun Kosmos.create(supportsMirror: Boolean = true): BrightnessSliderViewModel {
        return BrightnessSliderViewModel(
            screenBrightnessInteractor,
            brightnessPolicyEnforcementInteractor,
            sliderHapticsViewModelFactory,
            {
                brightnessMirrorInteractorRetrieved = true
                brightnessMirrorShowingInteractor
            },
            falsingInteractor,
            supportsMirror,
            brightnessWarningToast,
            imageLoader,
        )
    }
}
}
+21 −3
Original line number Original line Diff line number Diff line
@@ -36,9 +36,11 @@ import com.android.systemui.res.R
import com.android.systemui.settings.brightness.domain.interactor.BrightnessMirrorShowingInteractor
import com.android.systemui.settings.brightness.domain.interactor.BrightnessMirrorShowingInteractor
import com.android.systemui.settings.brightness.ui.BrightnessWarningToast
import com.android.systemui.settings.brightness.ui.BrightnessWarningToast
import com.android.systemui.utils.PolicyRestriction
import com.android.systemui.utils.PolicyRestriction
import dagger.Lazy
import dagger.assisted.Assisted
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dagger.assisted.AssistedInject
import kotlinx.coroutines.flow.MutableStateFlow


/**
/**
 * View Model for a brightness slider.
 * View Model for a brightness slider.
@@ -55,13 +57,20 @@ constructor(
    private val screenBrightnessInteractor: ScreenBrightnessInteractor,
    private val screenBrightnessInteractor: ScreenBrightnessInteractor,
    private val brightnessPolicyEnforcementInteractor: BrightnessPolicyEnforcementInteractor,
    private val brightnessPolicyEnforcementInteractor: BrightnessPolicyEnforcementInteractor,
    val hapticsViewModelFactory: SliderHapticsViewModel.Factory,
    val hapticsViewModelFactory: SliderHapticsViewModel.Factory,
    private val brightnessMirrorShowingInteractor: BrightnessMirrorShowingInteractor,
    private val brightnessMirrorShowingInteractorLazy: Lazy<BrightnessMirrorShowingInteractor>,
    private val falsingInteractor: FalsingInteractor,
    private val falsingInteractor: FalsingInteractor,
    @Assisted private val supportsMirroring: Boolean,
    @Assisted private val supportsMirroring: Boolean,
    private val brightnessWarningToast: BrightnessWarningToast,
    private val brightnessWarningToast: BrightnessWarningToast,
    private val imageLoader: ImageLoader,
    private val imageLoader: ImageLoader,
) : ExclusiveActivatable() {
) : ExclusiveActivatable() {


    init {
        if (supportsMirroring) {
            // Create eagerly only if supported
            brightnessMirrorShowingInteractorLazy.get()
        }
    }

    private val hydrator = Hydrator("BrightnessSliderViewModel.hydrator")
    private val hydrator = Hydrator("BrightnessSliderViewModel.hydrator")


    val currentBrightness by
    val currentBrightness by
@@ -114,11 +123,20 @@ constructor(
    }
    }


    fun setIsDragging(dragging: Boolean) {
    fun setIsDragging(dragging: Boolean) {
        brightnessMirrorShowingInteractor.setMirrorShowing(dragging && supportsMirroring)
        if (supportsMirroring) {
            brightnessMirrorShowingInteractorLazy.get().setMirrorShowing(dragging)
        }
    }
    }


    val showMirror by
    val showMirror by
        hydrator.hydratedStateOf("showMirror", brightnessMirrorShowingInteractor.isShowing)
        hydrator.hydratedStateOf(
            "showMirror",
            if (supportsMirroring) {
                brightnessMirrorShowingInteractorLazy.get().isShowing
            } else {
                MutableStateFlow(false)
            },
        )


    override suspend fun onActivated(): Nothing {
    override suspend fun onActivated(): Nothing {
        hydrator.activate()
        hydrator.activate()
+6 −1
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.systemui.shade
package com.android.systemui.shade


import android.os.UserHandle
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogBufferFactory
import com.android.systemui.log.LogBufferFactory
@@ -162,7 +163,11 @@ abstract class ShadeModule {
            sceneContainerOn: Provider<BrightnessMirrorShowingInteractorPassThrough>,
            sceneContainerOn: Provider<BrightnessMirrorShowingInteractorPassThrough>,
            sceneContainerOff: Provider<NotificationPanelViewController>,
            sceneContainerOff: Provider<NotificationPanelViewController>,
        ): BrightnessMirrorShowingInteractor {
        ): BrightnessMirrorShowingInteractor {
            return if (SceneContainerFlag.isEnabled) {
            // Do not use NPVC if the user is not system. We don't want to create an NPVC in that
            // case.
            return if (
                SceneContainerFlag.isEnabled || UserHandle.myUserId() != UserHandle.USER_SYSTEM
            ) {
                sceneContainerOn.get()
                sceneContainerOn.get()
            } else {
            } else {
                sceneContainerOff.get()
                sceneContainerOff.get()
+1 −1
Original line number Original line Diff line number Diff line
@@ -33,7 +33,7 @@ val Kosmos.brightnessSliderViewModelFactory: BrightnessSliderViewModel.Factory b
                    screenBrightnessInteractor = screenBrightnessInteractor,
                    screenBrightnessInteractor = screenBrightnessInteractor,
                    brightnessPolicyEnforcementInteractor = brightnessPolicyEnforcementInteractor,
                    brightnessPolicyEnforcementInteractor = brightnessPolicyEnforcementInteractor,
                    hapticsViewModelFactory = sliderHapticsViewModelFactory,
                    hapticsViewModelFactory = sliderHapticsViewModelFactory,
                    brightnessMirrorShowingInteractor = brightnessMirrorShowingInteractor,
                    brightnessMirrorShowingInteractorLazy = { brightnessMirrorShowingInteractor },
                    supportsMirroring = allowsMirroring,
                    supportsMirroring = allowsMirroring,
                    falsingInteractor = falsingInteractor,
                    falsingInteractor = falsingInteractor,
                    brightnessWarningToast = brightnessWarningToast,
                    brightnessWarningToast = brightnessWarningToast,