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

Commit 601277a9 authored by Jeff DeCew's avatar Jeff DeCew Committed by Android (Google) Code Review
Browse files

Merge "Add @EnableSceneContainer and ensure it works for all SysuiTestCase tests." into main

parents 3f794cbc e49d4ce7
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ object SceneContainerFlag {
                keyguardBottomAreaRefactor() &&
                KeyguardShadeMigrationNssl.isEnabled &&
                MediaInSceneContainerFlag.isEnabled &&
                // NOTE: Changes should also be made in getSecondaryFlags and @EnableSceneContainer
                ComposeFacade.isComposeAvailable()

    /**
@@ -63,6 +64,7 @@ object SceneContainerFlag {
            FlagToken(FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR, keyguardBottomAreaRefactor()),
            KeyguardShadeMigrationNssl.token,
            MediaInSceneContainerFlag.token,
            // NOTE: Changes should also be made in isEnabled and @EnableSceneContainer
        )

    /** The full set of requirements for SceneContainer */
+6 −38
Original line number Diff line number Diff line
@@ -16,17 +16,13 @@

package com.android.systemui.scene.shared.flag

import android.platform.test.annotations.DisableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
import com.android.systemui.SysuiTestCase
import com.android.systemui.compose.ComposeFacade
import com.android.systemui.flags.Flags
import com.android.systemui.flags.setFlagValue
import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl
import com.android.systemui.media.controls.util.MediaInSceneContainerFlag
import com.android.systemui.flags.EnableSceneContainer
import com.google.common.truth.Truth
import org.junit.Assume
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

@@ -34,45 +30,17 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
internal class SceneContainerFlagsTest : SysuiTestCase() {

    @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) // note: this does not work with multivalent tests
    }

    private fun setAconfigFlagsEnabled(enabled: Boolean) {
        listOf(
                com.android.systemui.Flags.FLAG_SCENE_CONTAINER,
                com.android.systemui.Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR,
                KeyguardShadeMigrationNssl.FLAG_NAME,
                MediaInSceneContainerFlag.FLAG_NAME,
            )
            .forEach { flagName -> mSetFlagsRule.setFlagValue(flagName, enabled) }
    }

    @Test
    @DisableFlags(FLAG_SCENE_CONTAINER)
    fun isNotEnabled_withoutAconfigFlags() {
        setAconfigFlagsEnabled(false)
        Truth.assertThat(SceneContainerFlag.isEnabled).isEqualTo(false)
        Truth.assertThat(SceneContainerFlagsImpl().isEnabled()).isEqualTo(false)
    }

    @Test
    fun isEnabled_withAconfigFlags_withCompose() {
        Assume.assumeTrue(ComposeFacade.isComposeAvailable())
        setAconfigFlagsEnabled(true)
    @EnableSceneContainer
    fun isEnabled_withAconfigFlags() {
        Truth.assertThat(SceneContainerFlag.isEnabled).isEqualTo(true)
        Truth.assertThat(SceneContainerFlagsImpl().isEnabled()).isEqualTo(true)
    }

    @Test
    fun isNotEnabled_withAconfigFlags_withoutCompose() {
        Assume.assumeFalse(ComposeFacade.isComposeAvailable())
        setAconfigFlagsEnabled(true)
        Truth.assertThat(SceneContainerFlag.isEnabled).isEqualTo(false)
        Truth.assertThat(SceneContainerFlagsImpl().isEnabled()).isEqualTo(false)
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.uiautomator.UiDevice;

import com.android.systemui.broadcast.FakeBroadcastDispatcher;
import com.android.systemui.flags.SceneContainerRule;

import org.junit.After;
import org.junit.AfterClass;
@@ -68,6 +69,9 @@ public abstract class SysuiTestCase {
    @Rule
    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);

    @Rule(order = 10)
    public final SceneContainerRule mSceneContainerRule = new SceneContainerRule();

    @Rule
    public SysuiTestableContext mContext = createTestableContext();

+37 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.flags

import android.platform.test.annotations.EnableFlags
import com.android.systemui.Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR
import com.android.systemui.Flags.FLAG_KEYGUARD_SHADE_MIGRATION_NSSL
import com.android.systemui.Flags.FLAG_MEDIA_IN_SCENE_CONTAINER
import com.android.systemui.Flags.FLAG_SCENE_CONTAINER

/**
 * This includes @[EnableFlags] to work with [SetFlagsRule] to enable all aconfig flags required by
 * that feature. It is also picked up by [SceneContainerRule] to set non-aconfig prerequisites.
 */
@EnableFlags(
    FLAG_SCENE_CONTAINER,
    FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR,
    FLAG_KEYGUARD_SHADE_MIGRATION_NSSL,
    FLAG_MEDIA_IN_SCENE_CONTAINER,
)
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
annotation class EnableSceneContainer
+89 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.flags

import android.util.Log
import com.android.systemui.compose.ComposeFacade
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import org.junit.Assert
import org.junit.Assume
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement

/**
 * Should always be used with [SetFlagsRule] and should be ordered after it.
 *
 * Used to ensure tests annotated with [EnableSceneContainer] can actually get `true` from
 * [SceneContainerFlag.isEnabled].
 */
class SceneContainerRule : TestRule {
    override fun apply(base: Statement?, description: Description?): Statement {
        return object : Statement() {
            @Throws(Throwable::class)
            override fun evaluate() {
                val initialEnabledValue = Flags.SCENE_CONTAINER_ENABLED
                val hasAnnotation =
                    description?.testClass?.getAnnotation(EnableSceneContainer::class.java) !=
                        null || description?.getAnnotation(EnableSceneContainer::class.java) != null
                if (hasAnnotation) {
                    Assume.assumeTrue(
                        "Compose must be available for @EnableSceneContainer test",
                        ComposeFacade.isComposeAvailable()
                    )
                    Assume.assumeTrue(
                        "Couldn't set Flags.SCENE_CONTAINER_ENABLED for @EnableSceneContainer test",
                        trySetSceneContainerEnabled(true)
                    )
                    Assert.assertTrue(
                        "SceneContainerFlag.isEnabled is false:" +
                            "\n * Did you forget to add a new aconfig flag dependency in" +
                            " @EnableSceneContainer?" +
                            "\n * Did you forget to use SetFlagsRule with an earlier order?",
                        SceneContainerFlag.isEnabled
                    )
                }
                try {
                    base?.evaluate()
                } finally {
                    if (hasAnnotation) {
                        trySetSceneContainerEnabled(initialEnabledValue)
                    }
                }
            }
        }
    }

    companion object {
        fun trySetSceneContainerEnabled(enabled: Boolean): Boolean {
            if (Flags.SCENE_CONTAINER_ENABLED == enabled) {
                return true
            }
            return try {
                // 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, enabled) // note: this does not work with multivalent tests
                true
            } catch (t: Throwable) {
                Log.e("SceneContainerRule", "Unable to set SCENE_CONTAINER_ENABLED=$enabled", t)
                false
            }
        }
    }
}