Loading packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt +30 −16 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.os.Parcelable interface Flag<T> { val id: Int val teamfood: Boolean } interface ParcelableFlag<T> : Flag<T>, Parcelable { Loading @@ -44,7 +45,8 @@ interface SysPropFlag<T> : Flag<T> { data class BooleanFlag @JvmOverloads constructor( override val id: Int, override val default: Boolean = false override val default: Boolean = false, override val teamfood: Boolean = false ) : ParcelableFlag<Boolean> { companion object { Loading @@ -66,20 +68,25 @@ data class BooleanFlag @JvmOverloads constructor( } } data class ResourceBooleanFlag constructor( data class ResourceBooleanFlag @JvmOverloads constructor( override val id: Int, @BoolRes override val resourceId: Int @BoolRes override val resourceId: Int, override val teamfood: Boolean = false ) : ResourceFlag<Boolean> data class SysPropBooleanFlag constructor( data class SysPropBooleanFlag @JvmOverloads constructor( override val id: Int, override val name: String, override val default: Boolean = false ) : SysPropFlag<Boolean> ) : SysPropFlag<Boolean> { // TODO(b/223379190): Teamfood not supported for sysprop flags yet. override val teamfood: Boolean = false } data class StringFlag @JvmOverloads constructor( override val id: Int, override val default: String = "" override val default: String = "", override val teamfood: Boolean = false ) : ParcelableFlag<String> { companion object { @JvmField Loading @@ -100,14 +107,16 @@ data class StringFlag @JvmOverloads constructor( } } data class ResourceStringFlag constructor( data class ResourceStringFlag @JvmOverloads constructor( override val id: Int, @StringRes override val resourceId: Int @StringRes override val resourceId: Int, override val teamfood: Boolean = false ) : ResourceFlag<String> data class IntFlag @JvmOverloads constructor( override val id: Int, override val default: Int = 0 override val default: Int = 0, override val teamfood: Boolean = false ) : ParcelableFlag<Int> { companion object { Loading @@ -129,14 +138,16 @@ data class IntFlag @JvmOverloads constructor( } } data class ResourceIntFlag constructor( data class ResourceIntFlag @JvmOverloads constructor( override val id: Int, @IntegerRes override val resourceId: Int @IntegerRes override val resourceId: Int, override val teamfood: Boolean = false ) : ResourceFlag<Int> data class LongFlag @JvmOverloads constructor( override val id: Int, override val default: Long = 0 override val default: Long = 0, override val teamfood: Boolean = false ) : ParcelableFlag<Long> { companion object { Loading @@ -160,7 +171,8 @@ data class LongFlag @JvmOverloads constructor( data class FloatFlag @JvmOverloads constructor( override val id: Int, override val default: Float = 0f override val default: Float = 0f, override val teamfood: Boolean = false ) : ParcelableFlag<Float> { companion object { Loading @@ -182,14 +194,16 @@ data class FloatFlag @JvmOverloads constructor( } } data class ResourceFloatFlag constructor( data class ResourceFloatFlag @JvmOverloads constructor( override val id: Int, override val resourceId: Int override val resourceId: Int, override val teamfood: Boolean = false ) : ResourceFlag<Int> data class DoubleFlag @JvmOverloads constructor( override val id: Int, override val default: Double = 0.0 override val default: Double = 0.0, override val teamfood: Boolean = false ) : ParcelableFlag<Double> { companion object { Loading packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt +2 −2 Original line number Diff line number Diff line Loading @@ -64,7 +64,7 @@ class FlagManager constructor( intent.setPackage(RECEIVING_PACKAGE) return CallbackToFutureAdapter.getFuture { completer: CallbackToFutureAdapter.Completer<Any?> -> completer: CallbackToFutureAdapter.Completer<Collection<Flag<*>>> -> context.sendOrderedBroadcast(intent, null, object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { Loading @@ -79,7 +79,7 @@ class FlagManager constructor( } }, null, Activity.RESULT_OK, "extra data", null) "QueryingFlags" } as ListenableFuture<Collection<Flag<*>>> } } /** Loading packages/SystemUI/src-debug/com/android/systemui/flags/FlagsModule.kt +4 −2 Original line number Diff line number Diff line Loading @@ -19,11 +19,12 @@ package com.android.systemui.flags import android.content.Context import android.os.Handler import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.flags.FeatureFlagsDebug.ALL_FLAGS import com.android.systemui.util.settings.SettingsUtilModule import dagger.Binds import dagger.Module import dagger.Provides import java.util.function.Supplier import javax.inject.Named @Module(includes = [ SettingsUtilModule::class Loading @@ -42,6 +43,7 @@ abstract class FlagsModule { @JvmStatic @Provides fun providesFlagCollector(): Supplier<Map<Int, Flag<*>>>? = null @Named(ALL_FLAGS) fun providesAllFlags(): Map<Int, Flag<*>> = Flags.collectFlags() } } No newline at end of file packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java +35 −16 Original line number Diff line number Diff line Loading @@ -50,9 +50,9 @@ import java.util.Map; import java.util.Objects; import java.util.TreeMap; import java.util.function.Consumer; import java.util.function.Supplier; import javax.inject.Inject; import javax.inject.Named; /** * Concrete implementation of the a Flag manager that returns default values for debug builds Loading @@ -66,12 +66,13 @@ import javax.inject.Inject; @SysUISingleton public class FeatureFlagsDebug implements FeatureFlags, Dumpable { private static final String TAG = "SysUIFlags"; static final String ALL_FLAGS = "all_flags"; private final FlagManager mFlagManager; private final SecureSettings mSecureSettings; private final Resources mResources; private final SystemPropertiesHelper mSystemProperties; private final Supplier<Map<Integer, Flag<?>>> mFlagsCollector; private final Map<Integer, Flag<?>> mAllFlags; private final Map<Integer, Boolean> mBooleanFlagCache = new TreeMap<>(); private final Map<Integer, String> mStringFlagCache = new TreeMap<>(); private final IStatusBarService mBarService; Loading @@ -84,13 +85,13 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { SystemPropertiesHelper systemProperties, @Main Resources resources, DumpManager dumpManager, @Nullable Supplier<Map<Integer, Flag<?>>> flagsCollector, @Named(ALL_FLAGS) Map<Integer, Flag<?>> allFlags, IStatusBarService barService) { mFlagManager = flagManager; mSecureSettings = secureSettings; mResources = resources; mSystemProperties = systemProperties; mFlagsCollector = flagsCollector != null ? flagsCollector : Flags::collectFlags; mAllFlags = allFlags; IntentFilter filter = new IntentFilter(); filter.addAction(ACTION_SET_FLAG); filter.addAction(ACTION_GET_FLAGS); Loading @@ -107,7 +108,7 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { int id = flag.getId(); if (!mBooleanFlagCache.containsKey(id)) { mBooleanFlagCache.put(id, readFlagValue(id, flag.getDefault(), BooleanFlagSerializer.INSTANCE)); readFlagValue(id, flag.getDefault())); } return mBooleanFlagCache.get(id); Loading @@ -118,8 +119,7 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { int id = flag.getId(); if (!mBooleanFlagCache.containsKey(id)) { mBooleanFlagCache.put(id, readFlagValue(id, mResources.getBoolean(flag.getResourceId()), BooleanFlagSerializer.INSTANCE)); readFlagValue(id, mResources.getBoolean(flag.getResourceId()))); } return mBooleanFlagCache.get(id); Loading @@ -129,8 +129,13 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { public boolean isEnabled(@NonNull SysPropBooleanFlag flag) { int id = flag.getId(); if (!mBooleanFlagCache.containsKey(id)) { // Use #readFlagValue to get the default. That will allow it to fall through to // teamfood if need be. mBooleanFlagCache.put( id, mSystemProperties.getBoolean(flag.getName(), flag.getDefault())); id, mSystemProperties.getBoolean( flag.getName(), readFlagValue(id, flag.getDefault()))); } return mBooleanFlagCache.get(id); Loading Loading @@ -161,6 +166,19 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { return mStringFlagCache.get(id); } /** Specific override for Boolean flags that checks against the teamfood list.*/ private boolean readFlagValue(int id, boolean defaultValue) { Boolean result = readFlagValueInternal(id, BooleanFlagSerializer.INSTANCE); // Only check for teamfood if the default is false. if (!defaultValue && result == null && id != Flags.TEAMFOOD.getId()) { if (mAllFlags.containsKey(id) && mAllFlags.get(id).getTeamfood()) { return isEnabled(Flags.TEAMFOOD); } } return result == null ? defaultValue : result; } @NonNull private <T> T readFlagValue(int id, @NonNull T defaultValue, FlagSerializer<T> serializer) { requireNonNull(defaultValue, "defaultValue"); Loading Loading @@ -266,8 +284,7 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { if (ACTION_SET_FLAG.equals(action)) { handleSetFlag(intent.getExtras()); } else if (ACTION_GET_FLAGS.equals(action)) { Map<Integer, Flag<?>> knownFlagMap = mFlagsCollector.get(); ArrayList<Flag<?>> flags = new ArrayList<>(knownFlagMap.values()); ArrayList<Flag<?>> flags = new ArrayList<>(mAllFlags.values()); // Convert all flags to parcelable flags. ArrayList<ParcelableFlag<?>> pFlags = new ArrayList<>(); Loading Loading @@ -296,12 +313,11 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { return; } Map<Integer, Flag<?>> flagMap = mFlagsCollector.get(); if (!flagMap.containsKey(id)) { if (!mAllFlags.containsKey(id)) { Log.w(TAG, "Tried to set unknown id: " + id); return; } Flag<?> flag = flagMap.get(id); Flag<?> flag = mAllFlags.get(id); if (!extras.containsKey(EXTRA_VALUE)) { eraseFlag(flag); Loading Loading @@ -338,13 +354,16 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { @Nullable private ParcelableFlag<?> toParcelableFlag(Flag<?> f) { if (f instanceof BooleanFlag) { return new BooleanFlag(f.getId(), isEnabled((BooleanFlag) f)); return new BooleanFlag(f.getId(), isEnabled((BooleanFlag) f), f.getTeamfood()); } if (f instanceof ResourceBooleanFlag) { return new BooleanFlag(f.getId(), isEnabled((ResourceBooleanFlag) f)); return new BooleanFlag( f.getId(), isEnabled((ResourceBooleanFlag) f), f.getTeamfood()); } if (f instanceof SysPropBooleanFlag) { return new BooleanFlag(f.getId(), isEnabled((SysPropBooleanFlag) f)); // TODO(b/223379190): Teamfood not supported for sysprop flags yet. return new BooleanFlag( f.getId(), isEnabled((SysPropBooleanFlag) f), false); } // TODO: add support for other flag types. Loading packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt +45 −2 Original line number Diff line number Diff line Loading @@ -67,9 +67,14 @@ class FeatureFlagsDebugTest : SysuiTestCase() { private lateinit var mBroadcastReceiver: BroadcastReceiver private lateinit var mClearCacheAction: Consumer<Int> private val teamfoodableFlagA = BooleanFlag(500, false, true) private val teamfoodableFlagB = BooleanFlag(501, true, true) @Before fun setup() { MockitoAnnotations.initMocks(this) mFlagMap.put(teamfoodableFlagA.id, teamfoodableFlagA) mFlagMap.put(teamfoodableFlagB.id, teamfoodableFlagB) mFeatureFlagsDebug = FeatureFlagsDebug( mFlagManager, mMockContext, Loading @@ -77,7 +82,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { mSystemProperties, mResources, mDumpManager, { mFlagMap }, mFlagMap, mBarService ) verify(mFlagManager).onSettingsChangedAction = any() Loading @@ -93,12 +98,50 @@ class FeatureFlagsDebugTest : SysuiTestCase() { @Test fun testReadBooleanFlag() { // Remember that the TEAMFOOD flag is id#1 and has special behavior. whenever(mFlagManager.readFlagValue<Boolean>(eq(3), any())).thenReturn(true) whenever(mFlagManager.readFlagValue<Boolean>(eq(4), any())).thenReturn(false) assertThat(mFeatureFlagsDebug.isEnabled(BooleanFlag(1, false))).isFalse() assertThat(mFeatureFlagsDebug.isEnabled(BooleanFlag(2, true))).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(BooleanFlag(3, false))).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(BooleanFlag(4, true))).isFalse() assertThat(mFeatureFlagsDebug.isEnabled(BooleanFlag(5, false))).isFalse() } @Test fun testTeamFoodFlag_False() { whenever(mFlagManager.readFlagValue<Boolean>(eq(1), any())).thenReturn(false) assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isFalse() assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue() // Regular boolean flags should still test the same. // Only our teamfoodableFlag should change. testReadBooleanFlag() } @Test fun testTeamFoodFlag_True() { whenever(mFlagManager.readFlagValue<Boolean>(eq(1), any())).thenReturn(true) assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue() // Regular boolean flags should still test the same. // Only our teamfoodableFlag should change. testReadBooleanFlag() } @Test fun testTeamFoodFlag_Overridden() { whenever(mFlagManager.readFlagValue<Boolean>(eq(teamfoodableFlagA.id), any())) .thenReturn(true) whenever(mFlagManager.readFlagValue<Boolean>(eq(teamfoodableFlagB.id), any())) .thenReturn(false) whenever(mFlagManager.readFlagValue<Boolean>(eq(1), any())).thenReturn(true) assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isFalse() // Regular boolean flags should still test the same. // Only our teamfoodableFlag should change. testReadBooleanFlag() } @Test Loading Loading
packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt +30 −16 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.os.Parcelable interface Flag<T> { val id: Int val teamfood: Boolean } interface ParcelableFlag<T> : Flag<T>, Parcelable { Loading @@ -44,7 +45,8 @@ interface SysPropFlag<T> : Flag<T> { data class BooleanFlag @JvmOverloads constructor( override val id: Int, override val default: Boolean = false override val default: Boolean = false, override val teamfood: Boolean = false ) : ParcelableFlag<Boolean> { companion object { Loading @@ -66,20 +68,25 @@ data class BooleanFlag @JvmOverloads constructor( } } data class ResourceBooleanFlag constructor( data class ResourceBooleanFlag @JvmOverloads constructor( override val id: Int, @BoolRes override val resourceId: Int @BoolRes override val resourceId: Int, override val teamfood: Boolean = false ) : ResourceFlag<Boolean> data class SysPropBooleanFlag constructor( data class SysPropBooleanFlag @JvmOverloads constructor( override val id: Int, override val name: String, override val default: Boolean = false ) : SysPropFlag<Boolean> ) : SysPropFlag<Boolean> { // TODO(b/223379190): Teamfood not supported for sysprop flags yet. override val teamfood: Boolean = false } data class StringFlag @JvmOverloads constructor( override val id: Int, override val default: String = "" override val default: String = "", override val teamfood: Boolean = false ) : ParcelableFlag<String> { companion object { @JvmField Loading @@ -100,14 +107,16 @@ data class StringFlag @JvmOverloads constructor( } } data class ResourceStringFlag constructor( data class ResourceStringFlag @JvmOverloads constructor( override val id: Int, @StringRes override val resourceId: Int @StringRes override val resourceId: Int, override val teamfood: Boolean = false ) : ResourceFlag<String> data class IntFlag @JvmOverloads constructor( override val id: Int, override val default: Int = 0 override val default: Int = 0, override val teamfood: Boolean = false ) : ParcelableFlag<Int> { companion object { Loading @@ -129,14 +138,16 @@ data class IntFlag @JvmOverloads constructor( } } data class ResourceIntFlag constructor( data class ResourceIntFlag @JvmOverloads constructor( override val id: Int, @IntegerRes override val resourceId: Int @IntegerRes override val resourceId: Int, override val teamfood: Boolean = false ) : ResourceFlag<Int> data class LongFlag @JvmOverloads constructor( override val id: Int, override val default: Long = 0 override val default: Long = 0, override val teamfood: Boolean = false ) : ParcelableFlag<Long> { companion object { Loading @@ -160,7 +171,8 @@ data class LongFlag @JvmOverloads constructor( data class FloatFlag @JvmOverloads constructor( override val id: Int, override val default: Float = 0f override val default: Float = 0f, override val teamfood: Boolean = false ) : ParcelableFlag<Float> { companion object { Loading @@ -182,14 +194,16 @@ data class FloatFlag @JvmOverloads constructor( } } data class ResourceFloatFlag constructor( data class ResourceFloatFlag @JvmOverloads constructor( override val id: Int, override val resourceId: Int override val resourceId: Int, override val teamfood: Boolean = false ) : ResourceFlag<Int> data class DoubleFlag @JvmOverloads constructor( override val id: Int, override val default: Double = 0.0 override val default: Double = 0.0, override val teamfood: Boolean = false ) : ParcelableFlag<Double> { companion object { Loading
packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt +2 −2 Original line number Diff line number Diff line Loading @@ -64,7 +64,7 @@ class FlagManager constructor( intent.setPackage(RECEIVING_PACKAGE) return CallbackToFutureAdapter.getFuture { completer: CallbackToFutureAdapter.Completer<Any?> -> completer: CallbackToFutureAdapter.Completer<Collection<Flag<*>>> -> context.sendOrderedBroadcast(intent, null, object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { Loading @@ -79,7 +79,7 @@ class FlagManager constructor( } }, null, Activity.RESULT_OK, "extra data", null) "QueryingFlags" } as ListenableFuture<Collection<Flag<*>>> } } /** Loading
packages/SystemUI/src-debug/com/android/systemui/flags/FlagsModule.kt +4 −2 Original line number Diff line number Diff line Loading @@ -19,11 +19,12 @@ package com.android.systemui.flags import android.content.Context import android.os.Handler import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.flags.FeatureFlagsDebug.ALL_FLAGS import com.android.systemui.util.settings.SettingsUtilModule import dagger.Binds import dagger.Module import dagger.Provides import java.util.function.Supplier import javax.inject.Named @Module(includes = [ SettingsUtilModule::class Loading @@ -42,6 +43,7 @@ abstract class FlagsModule { @JvmStatic @Provides fun providesFlagCollector(): Supplier<Map<Int, Flag<*>>>? = null @Named(ALL_FLAGS) fun providesAllFlags(): Map<Int, Flag<*>> = Flags.collectFlags() } } No newline at end of file
packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java +35 −16 Original line number Diff line number Diff line Loading @@ -50,9 +50,9 @@ import java.util.Map; import java.util.Objects; import java.util.TreeMap; import java.util.function.Consumer; import java.util.function.Supplier; import javax.inject.Inject; import javax.inject.Named; /** * Concrete implementation of the a Flag manager that returns default values for debug builds Loading @@ -66,12 +66,13 @@ import javax.inject.Inject; @SysUISingleton public class FeatureFlagsDebug implements FeatureFlags, Dumpable { private static final String TAG = "SysUIFlags"; static final String ALL_FLAGS = "all_flags"; private final FlagManager mFlagManager; private final SecureSettings mSecureSettings; private final Resources mResources; private final SystemPropertiesHelper mSystemProperties; private final Supplier<Map<Integer, Flag<?>>> mFlagsCollector; private final Map<Integer, Flag<?>> mAllFlags; private final Map<Integer, Boolean> mBooleanFlagCache = new TreeMap<>(); private final Map<Integer, String> mStringFlagCache = new TreeMap<>(); private final IStatusBarService mBarService; Loading @@ -84,13 +85,13 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { SystemPropertiesHelper systemProperties, @Main Resources resources, DumpManager dumpManager, @Nullable Supplier<Map<Integer, Flag<?>>> flagsCollector, @Named(ALL_FLAGS) Map<Integer, Flag<?>> allFlags, IStatusBarService barService) { mFlagManager = flagManager; mSecureSettings = secureSettings; mResources = resources; mSystemProperties = systemProperties; mFlagsCollector = flagsCollector != null ? flagsCollector : Flags::collectFlags; mAllFlags = allFlags; IntentFilter filter = new IntentFilter(); filter.addAction(ACTION_SET_FLAG); filter.addAction(ACTION_GET_FLAGS); Loading @@ -107,7 +108,7 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { int id = flag.getId(); if (!mBooleanFlagCache.containsKey(id)) { mBooleanFlagCache.put(id, readFlagValue(id, flag.getDefault(), BooleanFlagSerializer.INSTANCE)); readFlagValue(id, flag.getDefault())); } return mBooleanFlagCache.get(id); Loading @@ -118,8 +119,7 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { int id = flag.getId(); if (!mBooleanFlagCache.containsKey(id)) { mBooleanFlagCache.put(id, readFlagValue(id, mResources.getBoolean(flag.getResourceId()), BooleanFlagSerializer.INSTANCE)); readFlagValue(id, mResources.getBoolean(flag.getResourceId()))); } return mBooleanFlagCache.get(id); Loading @@ -129,8 +129,13 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { public boolean isEnabled(@NonNull SysPropBooleanFlag flag) { int id = flag.getId(); if (!mBooleanFlagCache.containsKey(id)) { // Use #readFlagValue to get the default. That will allow it to fall through to // teamfood if need be. mBooleanFlagCache.put( id, mSystemProperties.getBoolean(flag.getName(), flag.getDefault())); id, mSystemProperties.getBoolean( flag.getName(), readFlagValue(id, flag.getDefault()))); } return mBooleanFlagCache.get(id); Loading Loading @@ -161,6 +166,19 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { return mStringFlagCache.get(id); } /** Specific override for Boolean flags that checks against the teamfood list.*/ private boolean readFlagValue(int id, boolean defaultValue) { Boolean result = readFlagValueInternal(id, BooleanFlagSerializer.INSTANCE); // Only check for teamfood if the default is false. if (!defaultValue && result == null && id != Flags.TEAMFOOD.getId()) { if (mAllFlags.containsKey(id) && mAllFlags.get(id).getTeamfood()) { return isEnabled(Flags.TEAMFOOD); } } return result == null ? defaultValue : result; } @NonNull private <T> T readFlagValue(int id, @NonNull T defaultValue, FlagSerializer<T> serializer) { requireNonNull(defaultValue, "defaultValue"); Loading Loading @@ -266,8 +284,7 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { if (ACTION_SET_FLAG.equals(action)) { handleSetFlag(intent.getExtras()); } else if (ACTION_GET_FLAGS.equals(action)) { Map<Integer, Flag<?>> knownFlagMap = mFlagsCollector.get(); ArrayList<Flag<?>> flags = new ArrayList<>(knownFlagMap.values()); ArrayList<Flag<?>> flags = new ArrayList<>(mAllFlags.values()); // Convert all flags to parcelable flags. ArrayList<ParcelableFlag<?>> pFlags = new ArrayList<>(); Loading Loading @@ -296,12 +313,11 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { return; } Map<Integer, Flag<?>> flagMap = mFlagsCollector.get(); if (!flagMap.containsKey(id)) { if (!mAllFlags.containsKey(id)) { Log.w(TAG, "Tried to set unknown id: " + id); return; } Flag<?> flag = flagMap.get(id); Flag<?> flag = mAllFlags.get(id); if (!extras.containsKey(EXTRA_VALUE)) { eraseFlag(flag); Loading Loading @@ -338,13 +354,16 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { @Nullable private ParcelableFlag<?> toParcelableFlag(Flag<?> f) { if (f instanceof BooleanFlag) { return new BooleanFlag(f.getId(), isEnabled((BooleanFlag) f)); return new BooleanFlag(f.getId(), isEnabled((BooleanFlag) f), f.getTeamfood()); } if (f instanceof ResourceBooleanFlag) { return new BooleanFlag(f.getId(), isEnabled((ResourceBooleanFlag) f)); return new BooleanFlag( f.getId(), isEnabled((ResourceBooleanFlag) f), f.getTeamfood()); } if (f instanceof SysPropBooleanFlag) { return new BooleanFlag(f.getId(), isEnabled((SysPropBooleanFlag) f)); // TODO(b/223379190): Teamfood not supported for sysprop flags yet. return new BooleanFlag( f.getId(), isEnabled((SysPropBooleanFlag) f), false); } // TODO: add support for other flag types. Loading
packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt +45 −2 Original line number Diff line number Diff line Loading @@ -67,9 +67,14 @@ class FeatureFlagsDebugTest : SysuiTestCase() { private lateinit var mBroadcastReceiver: BroadcastReceiver private lateinit var mClearCacheAction: Consumer<Int> private val teamfoodableFlagA = BooleanFlag(500, false, true) private val teamfoodableFlagB = BooleanFlag(501, true, true) @Before fun setup() { MockitoAnnotations.initMocks(this) mFlagMap.put(teamfoodableFlagA.id, teamfoodableFlagA) mFlagMap.put(teamfoodableFlagB.id, teamfoodableFlagB) mFeatureFlagsDebug = FeatureFlagsDebug( mFlagManager, mMockContext, Loading @@ -77,7 +82,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { mSystemProperties, mResources, mDumpManager, { mFlagMap }, mFlagMap, mBarService ) verify(mFlagManager).onSettingsChangedAction = any() Loading @@ -93,12 +98,50 @@ class FeatureFlagsDebugTest : SysuiTestCase() { @Test fun testReadBooleanFlag() { // Remember that the TEAMFOOD flag is id#1 and has special behavior. whenever(mFlagManager.readFlagValue<Boolean>(eq(3), any())).thenReturn(true) whenever(mFlagManager.readFlagValue<Boolean>(eq(4), any())).thenReturn(false) assertThat(mFeatureFlagsDebug.isEnabled(BooleanFlag(1, false))).isFalse() assertThat(mFeatureFlagsDebug.isEnabled(BooleanFlag(2, true))).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(BooleanFlag(3, false))).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(BooleanFlag(4, true))).isFalse() assertThat(mFeatureFlagsDebug.isEnabled(BooleanFlag(5, false))).isFalse() } @Test fun testTeamFoodFlag_False() { whenever(mFlagManager.readFlagValue<Boolean>(eq(1), any())).thenReturn(false) assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isFalse() assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue() // Regular boolean flags should still test the same. // Only our teamfoodableFlag should change. testReadBooleanFlag() } @Test fun testTeamFoodFlag_True() { whenever(mFlagManager.readFlagValue<Boolean>(eq(1), any())).thenReturn(true) assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue() // Regular boolean flags should still test the same. // Only our teamfoodableFlag should change. testReadBooleanFlag() } @Test fun testTeamFoodFlag_Overridden() { whenever(mFlagManager.readFlagValue<Boolean>(eq(teamfoodableFlagA.id), any())) .thenReturn(true) whenever(mFlagManager.readFlagValue<Boolean>(eq(teamfoodableFlagB.id), any())) .thenReturn(false) whenever(mFlagManager.readFlagValue<Boolean>(eq(1), any())).thenReturn(true) assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isFalse() // Regular boolean flags should still test the same. // Only our teamfoodableFlag should change. testReadBooleanFlag() } @Test Loading