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 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.graphics.imageLoader
import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.lifecycle.activateIn
import com.android.systemui.res.R
@@ -51,20 +52,9 @@ class BrightnessSliderViewModelTest : SysuiTestCase() {

    private val kosmos = testKosmos()

    private val underTest by lazy {
        with(kosmos) {
            BrightnessSliderViewModel(
                screenBrightnessInteractor,
                brightnessPolicyEnforcementInteractor,
                sliderHapticsViewModelFactory,
                brightnessMirrorShowingInteractor,
                falsingInteractor,
                supportsMirroring = true,
                brightnessWarningToast,
                imageLoader,
            )
        }
    }
    private var brightnessMirrorInteractorRetrieved = false

    private val underTest by lazy { kosmos.create(true) }

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

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

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

                val temporaryBrightness by
                    collectLastValue(fakeScreenBrightnessRepository.temporaryBrightness)

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

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

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

                val mirrorInInteractor by
                    collectLastValue(brightnessMirrorShowingInteractor.isShowing)

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

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

                noMirrorViewModel.setIsDragging(true)
                assertThat(mirrorInInteractor).isEqualTo(false)
@@ -211,4 +209,35 @@ class BrightnessSliderViewModelTest : SysuiTestCase() {
                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 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.ui.BrightnessWarningToast
import com.android.systemui.utils.PolicyRestriction
import dagger.Lazy
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.flow.MutableStateFlow

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

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

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

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

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

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

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

package com.android.systemui.shade

import android.os.UserHandle
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogBufferFactory
@@ -162,7 +163,11 @@ abstract class ShadeModule {
            sceneContainerOn: Provider<BrightnessMirrorShowingInteractorPassThrough>,
            sceneContainerOff: Provider<NotificationPanelViewController>,
        ): 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()
            } else {
                sceneContainerOff.get()
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ val Kosmos.brightnessSliderViewModelFactory: BrightnessSliderViewModel.Factory b
                    screenBrightnessInteractor = screenBrightnessInteractor,
                    brightnessPolicyEnforcementInteractor = brightnessPolicyEnforcementInteractor,
                    hapticsViewModelFactory = sliderHapticsViewModelFactory,
                    brightnessMirrorShowingInteractor = brightnessMirrorShowingInteractor,
                    brightnessMirrorShowingInteractorLazy = { brightnessMirrorShowingInteractor },
                    supportsMirroring = allowsMirroring,
                    falsingInteractor = falsingInteractor,
                    brightnessWarningToast = brightnessWarningToast,