Loading packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt +26 −7 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.systemui.scene.shared.flag import androidx.annotation.VisibleForTesting import com.android.systemui.FeatureFlags import com.android.systemui.Flags as AConfigFlags import com.android.systemui.compose.ComposeFacade import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FeatureFlagsClassic Loading Loading @@ -47,15 +49,15 @@ interface SceneContainerFlags { class SceneContainerFlagsImpl @AssistedInject constructor( private val featureFlags: FeatureFlagsClassic, private val featureFlagsClassic: FeatureFlagsClassic, featureFlags: FeatureFlags, @Assisted private val isComposeAvailable: Boolean, ) : SceneContainerFlags { companion object { @VisibleForTesting val flags: List<Flag<Boolean>> = val classicFlagTokens: List<Flag<Boolean>> = listOf( Flags.SCENE_CONTAINER, Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA, Flags.MIGRATE_LOCK_ICON, Flags.MIGRATE_NSSL, Loading @@ -67,7 +69,13 @@ constructor( /** The list of requirements, all must be met for the feature to be enabled. */ private val requirements = flags.map { FlagMustBeEnabled(it) } + listOf( AconfigFlagMustBeEnabled( flagName = AConfigFlags.FLAG_SCENE_CONTAINER, flagValue = featureFlags.sceneContainer(), ), ) + classicFlagTokens.map { flagToken -> FlagMustBeEnabled(flagToken) } + listOf(ComposeMustBeAvailable(), CompileTimeFlagMustBeEnabled()) override fun isEnabled(): Boolean { Loading Loading @@ -115,14 +123,25 @@ constructor( override fun isMet(): Boolean { return when (flag) { is ResourceBooleanFlag -> featureFlags.isEnabled(flag) is ReleasedFlag -> featureFlags.isEnabled(flag) is UnreleasedFlag -> featureFlags.isEnabled(flag) is ResourceBooleanFlag -> featureFlagsClassic.isEnabled(flag) is ReleasedFlag -> featureFlagsClassic.isEnabled(flag) is UnreleasedFlag -> featureFlagsClassic.isEnabled(flag) else -> error("Unsupported flag type ${flag.javaClass}") } } } private inner class AconfigFlagMustBeEnabled( flagName: String, private val flagValue: Boolean, ) : Requirement { override val name: String = "Aconfig flag $flagName must be enabled" override fun isMet(): Boolean { return flagValue } } @AssistedFactory interface Factory { fun create(isComposeAvailable: Boolean): SceneContainerFlagsImpl Loading packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt +7 −3 Original line number Diff line number Diff line Loading @@ -22,11 +22,11 @@ import android.os.PowerManager import android.view.Display import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.Flags as AconfigFlags import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.domain.model.AuthenticationMethodModel import com.android.systemui.classifier.FalsingCollector import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.Flags import com.android.systemui.model.SysUiState import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest Loading @@ -45,7 +45,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Assume.assumeTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.clearInvocations Loading Loading @@ -87,6 +87,11 @@ class SceneContainerStartableTest : SysuiTestCase() { powerInteractor = powerInteractor, ) @Before fun setUp() { mSetFlagsRule.enableFlags(AconfigFlags.FLAG_SCENE_CONTAINER) } @Test fun hydrateVisibility() = testScope.runTest { Loading Loading @@ -520,7 +525,6 @@ class SceneContainerStartableTest : SysuiTestCase() { authenticationMethod: AuthenticationMethodModel? = null, startsAwake: Boolean = true, ): MutableStateFlow<ObservableTransitionState> { assumeTrue(Flags.SCENE_CONTAINER_ENABLED) sceneContainerFlags.enabled = true utils.deviceEntryRepository.setUnlocked(isDeviceUnlocked) utils.deviceEntryRepository.setBypassEnabled(isBypassEnabled) Loading packages/SystemUI/tests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt +35 −9 Original line number Diff line number Diff line Loading @@ -16,7 +16,10 @@ package com.android.systemui.scene.shared.flag import android.platform.test.flag.junit.SetFlagsRule import androidx.test.filters.SmallTest import com.android.systemui.FakeFeatureFlagsImpl import com.android.systemui.Flags as AconfigFlags import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FakeFeatureFlagsClassic import com.android.systemui.flags.Flags Loading @@ -24,8 +27,8 @@ import com.android.systemui.flags.ReleasedFlag import com.android.systemui.flags.ResourceBooleanFlag import com.android.systemui.flags.UnreleasedFlag import com.google.common.truth.Truth.assertThat import org.junit.Assume.assumeTrue import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized Loading @@ -36,27 +39,50 @@ internal class SceneContainerFlagsTest( private val testCase: TestCase, ) : SysuiTestCase() { @Rule @JvmField val setFlagsRule: SetFlagsRule = SetFlagsRule() private lateinit var underTest: SceneContainerFlags @Before fun setUp() { // TODO(b/283300105): remove this reflection setting once the hard-coded // Flags.SCENE_CONTAINER_ENABLED is no longer needed. val field = Flags::class.java.getField("SCENE_CONTAINER_ENABLED") field.isAccessible = true field.set(null, true) val featureFlags = FakeFeatureFlagsClassic().apply { SceneContainerFlagsImpl.flags.forEach { flag -> when (flag) { is ResourceBooleanFlag -> set(flag, testCase.areAllFlagsSet) is ReleasedFlag -> set(flag, testCase.areAllFlagsSet) is UnreleasedFlag -> set(flag, testCase.areAllFlagsSet) else -> error("Unsupported flag type ${flag.javaClass}") SceneContainerFlagsImpl.classicFlagTokens.forEach { flagToken -> when (flagToken) { is ResourceBooleanFlag -> set(flagToken, testCase.areAllFlagsSet) is ReleasedFlag -> set(flagToken, testCase.areAllFlagsSet) is UnreleasedFlag -> set(flagToken, testCase.areAllFlagsSet) else -> error("Unsupported flag type ${flagToken.javaClass}") } } } underTest = SceneContainerFlagsImpl(featureFlags, testCase.isComposeAvailable) // TODO(b/306421592): get the aconfig FeatureFlags from the SetFlagsRule. val aconfigFlags = FakeFeatureFlagsImpl() listOf( AconfigFlags.FLAG_SCENE_CONTAINER, ) .forEach { flagToken -> setFlagsRule.enableFlags(flagToken) aconfigFlags.setFlag(flagToken, testCase.areAllFlagsSet) } underTest = SceneContainerFlagsImpl( featureFlagsClassic = featureFlags, featureFlags = aconfigFlags, isComposeAvailable = testCase.isComposeAvailable, ) } @Test fun isEnabled() { assumeTrue(Flags.SCENE_CONTAINER_ENABLED) assertThat(underTest.isEnabled()).isEqualTo(testCase.expectedEnabled) } Loading Loading
packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt +26 −7 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.systemui.scene.shared.flag import androidx.annotation.VisibleForTesting import com.android.systemui.FeatureFlags import com.android.systemui.Flags as AConfigFlags import com.android.systemui.compose.ComposeFacade import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FeatureFlagsClassic Loading Loading @@ -47,15 +49,15 @@ interface SceneContainerFlags { class SceneContainerFlagsImpl @AssistedInject constructor( private val featureFlags: FeatureFlagsClassic, private val featureFlagsClassic: FeatureFlagsClassic, featureFlags: FeatureFlags, @Assisted private val isComposeAvailable: Boolean, ) : SceneContainerFlags { companion object { @VisibleForTesting val flags: List<Flag<Boolean>> = val classicFlagTokens: List<Flag<Boolean>> = listOf( Flags.SCENE_CONTAINER, Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA, Flags.MIGRATE_LOCK_ICON, Flags.MIGRATE_NSSL, Loading @@ -67,7 +69,13 @@ constructor( /** The list of requirements, all must be met for the feature to be enabled. */ private val requirements = flags.map { FlagMustBeEnabled(it) } + listOf( AconfigFlagMustBeEnabled( flagName = AConfigFlags.FLAG_SCENE_CONTAINER, flagValue = featureFlags.sceneContainer(), ), ) + classicFlagTokens.map { flagToken -> FlagMustBeEnabled(flagToken) } + listOf(ComposeMustBeAvailable(), CompileTimeFlagMustBeEnabled()) override fun isEnabled(): Boolean { Loading Loading @@ -115,14 +123,25 @@ constructor( override fun isMet(): Boolean { return when (flag) { is ResourceBooleanFlag -> featureFlags.isEnabled(flag) is ReleasedFlag -> featureFlags.isEnabled(flag) is UnreleasedFlag -> featureFlags.isEnabled(flag) is ResourceBooleanFlag -> featureFlagsClassic.isEnabled(flag) is ReleasedFlag -> featureFlagsClassic.isEnabled(flag) is UnreleasedFlag -> featureFlagsClassic.isEnabled(flag) else -> error("Unsupported flag type ${flag.javaClass}") } } } private inner class AconfigFlagMustBeEnabled( flagName: String, private val flagValue: Boolean, ) : Requirement { override val name: String = "Aconfig flag $flagName must be enabled" override fun isMet(): Boolean { return flagValue } } @AssistedFactory interface Factory { fun create(isComposeAvailable: Boolean): SceneContainerFlagsImpl Loading
packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt +7 −3 Original line number Diff line number Diff line Loading @@ -22,11 +22,11 @@ import android.os.PowerManager import android.view.Display import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.Flags as AconfigFlags import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.domain.model.AuthenticationMethodModel import com.android.systemui.classifier.FalsingCollector import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.Flags import com.android.systemui.model.SysUiState import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest Loading @@ -45,7 +45,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Assume.assumeTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.clearInvocations Loading Loading @@ -87,6 +87,11 @@ class SceneContainerStartableTest : SysuiTestCase() { powerInteractor = powerInteractor, ) @Before fun setUp() { mSetFlagsRule.enableFlags(AconfigFlags.FLAG_SCENE_CONTAINER) } @Test fun hydrateVisibility() = testScope.runTest { Loading Loading @@ -520,7 +525,6 @@ class SceneContainerStartableTest : SysuiTestCase() { authenticationMethod: AuthenticationMethodModel? = null, startsAwake: Boolean = true, ): MutableStateFlow<ObservableTransitionState> { assumeTrue(Flags.SCENE_CONTAINER_ENABLED) sceneContainerFlags.enabled = true utils.deviceEntryRepository.setUnlocked(isDeviceUnlocked) utils.deviceEntryRepository.setBypassEnabled(isBypassEnabled) Loading
packages/SystemUI/tests/src/com/android/systemui/scene/shared/flag/SceneContainerFlagsTest.kt +35 −9 Original line number Diff line number Diff line Loading @@ -16,7 +16,10 @@ package com.android.systemui.scene.shared.flag import android.platform.test.flag.junit.SetFlagsRule import androidx.test.filters.SmallTest import com.android.systemui.FakeFeatureFlagsImpl import com.android.systemui.Flags as AconfigFlags import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FakeFeatureFlagsClassic import com.android.systemui.flags.Flags Loading @@ -24,8 +27,8 @@ import com.android.systemui.flags.ReleasedFlag import com.android.systemui.flags.ResourceBooleanFlag import com.android.systemui.flags.UnreleasedFlag import com.google.common.truth.Truth.assertThat import org.junit.Assume.assumeTrue import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized Loading @@ -36,27 +39,50 @@ internal class SceneContainerFlagsTest( private val testCase: TestCase, ) : SysuiTestCase() { @Rule @JvmField val setFlagsRule: SetFlagsRule = SetFlagsRule() private lateinit var underTest: SceneContainerFlags @Before fun setUp() { // TODO(b/283300105): remove this reflection setting once the hard-coded // Flags.SCENE_CONTAINER_ENABLED is no longer needed. val field = Flags::class.java.getField("SCENE_CONTAINER_ENABLED") field.isAccessible = true field.set(null, true) val featureFlags = FakeFeatureFlagsClassic().apply { SceneContainerFlagsImpl.flags.forEach { flag -> when (flag) { is ResourceBooleanFlag -> set(flag, testCase.areAllFlagsSet) is ReleasedFlag -> set(flag, testCase.areAllFlagsSet) is UnreleasedFlag -> set(flag, testCase.areAllFlagsSet) else -> error("Unsupported flag type ${flag.javaClass}") SceneContainerFlagsImpl.classicFlagTokens.forEach { flagToken -> when (flagToken) { is ResourceBooleanFlag -> set(flagToken, testCase.areAllFlagsSet) is ReleasedFlag -> set(flagToken, testCase.areAllFlagsSet) is UnreleasedFlag -> set(flagToken, testCase.areAllFlagsSet) else -> error("Unsupported flag type ${flagToken.javaClass}") } } } underTest = SceneContainerFlagsImpl(featureFlags, testCase.isComposeAvailable) // TODO(b/306421592): get the aconfig FeatureFlags from the SetFlagsRule. val aconfigFlags = FakeFeatureFlagsImpl() listOf( AconfigFlags.FLAG_SCENE_CONTAINER, ) .forEach { flagToken -> setFlagsRule.enableFlags(flagToken) aconfigFlags.setFlag(flagToken, testCase.areAllFlagsSet) } underTest = SceneContainerFlagsImpl( featureFlagsClassic = featureFlags, featureFlags = aconfigFlags, isComposeAvailable = testCase.isComposeAvailable, ) } @Test fun isEnabled() { assumeTrue(Flags.SCENE_CONTAINER_ENABLED) assertThat(underTest.isEnabled()).isEqualTo(testCase.expectedEnabled) } Loading