Loading packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java +28 −3 Original line number Diff line number Diff line Loading @@ -85,9 +85,34 @@ public class FeatureFlagsDebug implements FeatureFlags { private final ServerFlagReader.ChangeListener mOnPropertiesChanged = new ServerFlagReader.ChangeListener() { @Override public void onChange(Flag<?> flag) { public void onChange(Flag<?> flag, String value) { boolean shouldRestart = false; if (mBooleanFlagCache.containsKey(flag.getName())) { boolean newValue = value == null ? false : Boolean.parseBoolean(value); if (mBooleanFlagCache.get(flag.getName()) != newValue) { shouldRestart = true; } } else if (mStringFlagCache.containsKey(flag.getName())) { String newValue = value == null ? "" : value; if (mStringFlagCache.get(flag.getName()) != value) { shouldRestart = true; } } else if (mIntFlagCache.containsKey(flag.getName())) { int newValue = 0; try { newValue = value == null ? 0 : Integer.parseInt(value); } catch (NumberFormatException e) { } if (mIntFlagCache.get(flag.getName()) != newValue) { shouldRestart = true; } } if (shouldRestart) { mRestarter.restartSystemUI( "Server flag change: " + flag.getNamespace() + "." + flag.getName()); "Server flag change: " + flag.getNamespace() + "." + flag.getName()); } } }; Loading packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java +84 −30 Original line number Diff line number Diff line Loading @@ -53,13 +53,38 @@ public class FeatureFlagsRelease implements FeatureFlags { private final Map<String, Flag<?>> mAllFlags; private final Map<String, Boolean> mBooleanCache = new HashMap<>(); private final Map<String, String> mStringCache = new HashMap<>(); private final Map<String, Integer> mIntCache = new HashMap<>(); private final ServerFlagReader.ChangeListener mOnPropertiesChanged = new ServerFlagReader.ChangeListener() { @Override public void onChange(Flag<?> flag) { public void onChange(Flag<?> flag, String value) { boolean shouldRestart = false; if (mBooleanCache.containsKey(flag.getName())) { boolean newValue = value == null ? false : Boolean.parseBoolean(value); if (mBooleanCache.get(flag.getName()) != newValue) { shouldRestart = true; } } else if (mStringCache.containsKey(flag.getName())) { String newValue = value == null ? "" : value; if (mStringCache.get(flag.getName()) != newValue) { shouldRestart = true; } } else if (mIntCache.containsKey(flag.getName())) { int newValue = 0; try { newValue = value == null ? 0 : Integer.parseInt(value); } catch (NumberFormatException e) { } if (mIntCache.get(flag.getName()) != newValue) { shouldRestart = true; } } if (shouldRestart) { mRestarter.restartSystemUI( "Server flag change: " + flag.getNamespace() + "." + flag.getName()); "Server flag change: " + flag.getNamespace() + "." + flag.getName()); } } }; Loading Loading @@ -97,68 +122,97 @@ public class FeatureFlagsRelease implements FeatureFlags { @Override public boolean isEnabled(@NotNull ReleasedFlag flag) { return mServerFlagReader.readServerOverride(flag.getNamespace(), flag.getName(), true); // Fill the cache. return isEnabledInternal(flag.getName(), mServerFlagReader.readServerOverride(flag.getNamespace(), flag.getName(), true)); } @Override public boolean isEnabled(ResourceBooleanFlag flag) { if (!mBooleanCache.containsKey(flag.getName())) { return isEnabled(flag.getName(), mResources.getBoolean(flag.getResourceId())); } return mBooleanCache.get(flag.getName()); // Fill the cache. return isEnabledInternal(flag.getName(), mResources.getBoolean(flag.getResourceId())); } @Override public boolean isEnabled(SysPropBooleanFlag flag) { if (!mBooleanCache.containsKey(flag.getName())) { return isEnabled( // Fill the cache. return isEnabledInternal( flag.getName(), mSystemProperties.getBoolean(flag.getName(), flag.getDefault())); } return mBooleanCache.get(flag.getName()); /** * Checks and fills the boolean cache. This is important, Always call through to this method! * * We use the cache as a way to decide if we need to restart the process when server-side * changes occur. */ private boolean isEnabledInternal(String name, boolean defaultValue) { // Fill the cache. if (!mBooleanCache.containsKey(name)) { mBooleanCache.put(name, defaultValue); } private boolean isEnabled(String name, boolean defaultValue) { mBooleanCache.put(name, defaultValue); return defaultValue; return mBooleanCache.get(name); } @NonNull @Override public String getString(@NonNull StringFlag flag) { return getString(flag.getName(), flag.getDefault()); // Fill the cache. return getStringInternal(flag.getName(), flag.getDefault()); } @NonNull @Override public String getString(@NonNull ResourceStringFlag flag) { if (!mStringCache.containsKey(flag.getName())) { return getString(flag.getName(), // Fill the cache. return getStringInternal(flag.getName(), requireNonNull(mResources.getString(flag.getResourceId()))); } return mStringCache.get(flag.getName()); /** * Checks and fills the String cache. This is important, Always call through to this method! * * We use the cache as a way to decide if we need to restart the process when server-side * changes occur. */ private String getStringInternal(String name, String defaultValue) { if (!mStringCache.containsKey(name)) { mStringCache.put(name, defaultValue); } private String getString(String name, String defaultValue) { mStringCache.put(name, defaultValue); return defaultValue; return mStringCache.get(name); } @NonNull @Override public int getInt(@NonNull IntFlag flag) { return flag.getDefault(); // Fill the cache. return getIntInternal(flag.getName(), flag.getDefault()); } @NonNull @Override public int getInt(@NonNull ResourceIntFlag flag) { // Fill the cache. return mResources.getInteger(flag.getResourceId()); } /** * Checks and fills the integer cache. This is important, Always call through to this method! * * We use the cache as a way to decide if we need to restart the process when server-side * changes occur. */ private int getIntInternal(String name, int defaultValue) { if (!mIntCache.containsKey(name)) { mIntCache.put(name, defaultValue); } return mIntCache.get(name); } @Override public void dump(@NonNull PrintWriter pw, @NonNull String[] args) { pw.println("can override: false"); Loading packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt +4 −3 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ interface ServerFlagReader { fun listenForChanges(values: Collection<Flag<*>>, listener: ChangeListener) interface ChangeListener { fun onChange(flag: Flag<*>) fun onChange(flag: Flag<*>, value: String?) } } Loading Loading @@ -67,7 +67,7 @@ class ServerFlagReaderImpl @Inject constructor( propLoop@ for (propName in properties.keyset) { for (flag in flags) { if (propName == flag.name) { listener.onChange(flag) listener.onChange(flag, properties.getString(propName, null)) break@propLoop } } Loading Loading @@ -144,7 +144,7 @@ class ServerFlagReaderFake : ServerFlagReader { for ((listener, flags) in listeners) { flagLoop@ for (flag in flags) { if (name == flag.name) { listener.onChange(flag) listener.onChange(flag, if (value) "true" else "false") break@flagLoop } } Loading @@ -159,5 +159,6 @@ class ServerFlagReaderFake : ServerFlagReader { flags: Collection<Flag<*>>, listener: ServerFlagReader.ChangeListener ) { listeners.add(Pair(listener, flags)) } } packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt +82 −55 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import org.mockito.Mock import org.mockito.Mockito.anyBoolean import org.mockito.Mockito.anyString import org.mockito.Mockito.inOrder import org.mockito.Mockito.never import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions Loading @@ -53,7 +54,7 @@ import org.mockito.Mockito.`when` as whenever */ @SmallTest class FeatureFlagsDebugTest : SysuiTestCase() { private lateinit var mFeatureFlagsDebug: FeatureFlagsDebug private lateinit var featureFlagsDebug: FeatureFlagsDebug @Mock private lateinit var flagManager: FlagManager Loading Loading @@ -85,7 +86,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { flagMap.put(Flags.TEAMFOOD.name, Flags.TEAMFOOD) flagMap.put(teamfoodableFlagA.name, teamfoodableFlagA) flagMap.put(teamfoodableFlagB.name, teamfoodableFlagB) mFeatureFlagsDebug = FeatureFlagsDebug( featureFlagsDebug = FeatureFlagsDebug( flagManager, mockContext, globalSettings, Loading @@ -95,7 +96,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { flagMap, restarter ) mFeatureFlagsDebug.init() featureFlagsDebug.init() verify(flagManager).onSettingsChangedAction = any() broadcastReceiver = withArgCaptor { verify(mockContext).registerReceiver( Loading @@ -116,7 +117,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { whenever(flagManager.readFlagValue<Boolean>(eq("4"), any())).thenReturn(false) assertThat( mFeatureFlagsDebug.isEnabled( featureFlagsDebug.isEnabled( ReleasedFlag( 2, name = "2", Loading @@ -125,7 +126,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { ) ).isTrue() assertThat( mFeatureFlagsDebug.isEnabled( featureFlagsDebug.isEnabled( UnreleasedFlag( 3, name = "3", Loading @@ -134,7 +135,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { ) ).isTrue() assertThat( mFeatureFlagsDebug.isEnabled( featureFlagsDebug.isEnabled( ReleasedFlag( 4, name = "4", Loading @@ -143,7 +144,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { ) ).isFalse() assertThat( mFeatureFlagsDebug.isEnabled( featureFlagsDebug.isEnabled( UnreleasedFlag( 5, name = "5", Loading @@ -157,8 +158,8 @@ class FeatureFlagsDebugTest : SysuiTestCase() { fun teamFoodFlag_False() { whenever(flagManager.readFlagValue<Boolean>( eq(Flags.TEAMFOOD.name), any())).thenReturn(false) assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isFalse() assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue() assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagA)).isFalse() assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue() // Regular boolean flags should still test the same. // Only our teamfoodableFlag should change. Loading @@ -169,8 +170,8 @@ class FeatureFlagsDebugTest : SysuiTestCase() { fun teamFoodFlag_True() { whenever(flagManager.readFlagValue<Boolean>( eq(Flags.TEAMFOOD.name), any())).thenReturn(true) assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue() assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue() assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue() // Regular boolean flags should still test the same. // Only our teamfoodableFlag should change. Loading @@ -185,8 +186,8 @@ class FeatureFlagsDebugTest : SysuiTestCase() { .thenReturn(false) whenever(flagManager.readFlagValue<Boolean>( eq(Flags.TEAMFOOD.name), any())).thenReturn(true) assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isFalse() assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue() assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagB)).isFalse() // Regular boolean flags should still test the same. // Only our teamfoodableFlag should change. Loading @@ -205,7 +206,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { whenever(flagManager.readFlagValue<Boolean>(eq("5"), any())).thenReturn(false) assertThat( mFeatureFlagsDebug.isEnabled( featureFlagsDebug.isEnabled( ResourceBooleanFlag( 1, "1", Loading @@ -214,16 +215,16 @@ class FeatureFlagsDebugTest : SysuiTestCase() { ) ) ).isFalse() assertThat(mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(2, "2", "test", 1002))).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(3, "3", "test", 1003))).isTrue() assertThat(featureFlagsDebug.isEnabled(ResourceBooleanFlag(2, "2", "test", 1002))).isTrue() assertThat(featureFlagsDebug.isEnabled(ResourceBooleanFlag(3, "3", "test", 1003))).isTrue() Assert.assertThrows(NameNotFoundException::class.java) { mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(4, "4", "test", 1004)) featureFlagsDebug.isEnabled(ResourceBooleanFlag(4, "4", "test", 1004)) } // Test that resource is loaded (and validated) even when the setting is set. // This prevents developers from not noticing when they reference an invalid resource. Assert.assertThrows(NameNotFoundException::class.java) { mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(5, "5", "test", 1005)) featureFlagsDebug.isEnabled(ResourceBooleanFlag(5, "5", "test", 1005)) } } Loading @@ -236,11 +237,11 @@ class FeatureFlagsDebugTest : SysuiTestCase() { return@thenAnswer it.getArgument(1) } assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(1, "a", "test"))).isFalse() assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(2, "b", "test"))).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(3, "c", "test", true))).isTrue() assertThat(featureFlagsDebug.isEnabled(SysPropBooleanFlag(1, "a", "test"))).isFalse() assertThat(featureFlagsDebug.isEnabled(SysPropBooleanFlag(2, "b", "test"))).isTrue() assertThat(featureFlagsDebug.isEnabled(SysPropBooleanFlag(3, "c", "test", true))).isTrue() assertThat( mFeatureFlagsDebug.isEnabled( featureFlagsDebug.isEnabled( SysPropBooleanFlag( 4, "d", Loading @@ -249,17 +250,17 @@ class FeatureFlagsDebugTest : SysuiTestCase() { ) ) ).isFalse() assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(5, "e", "test"))).isFalse() assertThat(featureFlagsDebug.isEnabled(SysPropBooleanFlag(5, "e", "test"))).isFalse() } @Test fun readStringFlag() { whenever(flagManager.readFlagValue<String>(eq("3"), any())).thenReturn("foo") whenever(flagManager.readFlagValue<String>(eq("4"), any())).thenReturn("bar") assertThat(mFeatureFlagsDebug.getString(StringFlag(1, "1", "test", "biz"))).isEqualTo("biz") assertThat(mFeatureFlagsDebug.getString(StringFlag(2, "2", "test", "baz"))).isEqualTo("baz") assertThat(mFeatureFlagsDebug.getString(StringFlag(3, "3", "test", "buz"))).isEqualTo("foo") assertThat(mFeatureFlagsDebug.getString(StringFlag(4, "4", "test", "buz"))).isEqualTo("bar") assertThat(featureFlagsDebug.getString(StringFlag(1, "1", "test", "biz"))).isEqualTo("biz") assertThat(featureFlagsDebug.getString(StringFlag(2, "2", "test", "baz"))).isEqualTo("baz") assertThat(featureFlagsDebug.getString(StringFlag(3, "3", "test", "buz"))).isEqualTo("foo") assertThat(featureFlagsDebug.getString(StringFlag(4, "4", "test", "buz"))).isEqualTo("bar") } @Test Loading @@ -276,7 +277,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { whenever(flagManager.readFlagValue<String>(eq("6"), any())).thenReturn("override6") assertThat( mFeatureFlagsDebug.getString( featureFlagsDebug.getString( ResourceStringFlag( 1, "1", Loading @@ -286,7 +287,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { ) ).isEqualTo("") assertThat( mFeatureFlagsDebug.getString( featureFlagsDebug.getString( ResourceStringFlag( 2, "2", Loading @@ -296,7 +297,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { ) ).isEqualTo("resource2") assertThat( mFeatureFlagsDebug.getString( featureFlagsDebug.getString( ResourceStringFlag( 3, "3", Loading @@ -307,15 +308,15 @@ class FeatureFlagsDebugTest : SysuiTestCase() { ).isEqualTo("override3") Assert.assertThrows(NullPointerException::class.java) { mFeatureFlagsDebug.getString(ResourceStringFlag(4, "4", "test", 1004)) featureFlagsDebug.getString(ResourceStringFlag(4, "4", "test", 1004)) } Assert.assertThrows(NameNotFoundException::class.java) { mFeatureFlagsDebug.getString(ResourceStringFlag(5, "5", "test", 1005)) featureFlagsDebug.getString(ResourceStringFlag(5, "5", "test", 1005)) } // Test that resource is loaded (and validated) even when the setting is set. // This prevents developers from not noticing when they reference an invalid resource. Assert.assertThrows(NameNotFoundException::class.java) { mFeatureFlagsDebug.getString(ResourceStringFlag(6, "6", "test", 1005)) featureFlagsDebug.getString(ResourceStringFlag(6, "6", "test", 1005)) } } Loading @@ -323,10 +324,10 @@ class FeatureFlagsDebugTest : SysuiTestCase() { fun readIntFlag() { whenever(flagManager.readFlagValue<Int>(eq("3"), any())).thenReturn(22) whenever(flagManager.readFlagValue<Int>(eq("4"), any())).thenReturn(48) assertThat(mFeatureFlagsDebug.getInt(IntFlag(1, "1", "test", 12))).isEqualTo(12) assertThat(mFeatureFlagsDebug.getInt(IntFlag(2, "2", "test", 93))).isEqualTo(93) assertThat(mFeatureFlagsDebug.getInt(IntFlag(3, "3", "test", 8))).isEqualTo(22) assertThat(mFeatureFlagsDebug.getInt(IntFlag(4, "4", "test", 234))).isEqualTo(48) assertThat(featureFlagsDebug.getInt(IntFlag(1, "1", "test", 12))).isEqualTo(12) assertThat(featureFlagsDebug.getInt(IntFlag(2, "2", "test", 93))).isEqualTo(93) assertThat(featureFlagsDebug.getInt(IntFlag(3, "3", "test", 8))).isEqualTo(22) assertThat(featureFlagsDebug.getInt(IntFlag(4, "4", "test", 234))).isEqualTo(48) } @Test Loading @@ -342,17 +343,17 @@ class FeatureFlagsDebugTest : SysuiTestCase() { whenever(flagManager.readFlagValue<Int>(eq(4), any())).thenReturn(500) whenever(flagManager.readFlagValue<Int>(eq(5), any())).thenReturn(9519) assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(1, "1", "test", 1001))).isEqualTo(88) assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(2, "2", "test", 1002))).isEqualTo(61) assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(3, "3", "test", 1003))).isEqualTo(20) assertThat(featureFlagsDebug.getInt(ResourceIntFlag(1, "1", "test", 1001))).isEqualTo(88) assertThat(featureFlagsDebug.getInt(ResourceIntFlag(2, "2", "test", 1002))).isEqualTo(61) assertThat(featureFlagsDebug.getInt(ResourceIntFlag(3, "3", "test", 1003))).isEqualTo(20) Assert.assertThrows(NotFoundException::class.java) { mFeatureFlagsDebug.getInt(ResourceIntFlag(4, "4", "test", 1004)) featureFlagsDebug.getInt(ResourceIntFlag(4, "4", "test", 1004)) } // Test that resource is loaded (and validated) even when the setting is set. // This prevents developers from not noticing when they reference an invalid resource. Assert.assertThrows(NotFoundException::class.java) { mFeatureFlagsDebug.getInt(ResourceIntFlag(5, "5", "test", 1005)) featureFlagsDebug.getInt(ResourceIntFlag(5, "5", "test", 1005)) } } Loading Loading @@ -432,11 +433,11 @@ class FeatureFlagsDebugTest : SysuiTestCase() { whenever(flagManager.readFlagValue<String>(eq("1"), any())).thenReturn("original") // gets the flag & cache it assertThat(mFeatureFlagsDebug.getString(flag1)).isEqualTo("original") assertThat(featureFlagsDebug.getString(flag1)).isEqualTo("original") verify(flagManager, times(1)).readFlagValue(eq("1"), eq(StringFlagSerializer)) // hit the cache assertThat(mFeatureFlagsDebug.getString(flag1)).isEqualTo("original") assertThat(featureFlagsDebug.getString(flag1)).isEqualTo("original") verifyNoMoreInteractions(flagManager) // set the flag Loading @@ -444,7 +445,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { verifyPutData("1", "{\"type\":\"string\",\"value\":\"new\"}", numReads = 2) whenever(flagManager.readFlagValue<String>(eq("1"), any())).thenReturn("new") assertThat(mFeatureFlagsDebug.getString(flag1)).isEqualTo("new") assertThat(featureFlagsDebug.getString(flag1)).isEqualTo("new") verify(flagManager, times(3)).readFlagValue(eq("1"), eq(StringFlagSerializer)) } Loading @@ -454,7 +455,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { serverFlagReader.setFlagValue(flag.namespace, flag.name, false) assertThat(mFeatureFlagsDebug.isEnabled(flag)).isFalse() assertThat(featureFlagsDebug.isEnabled(flag)).isFalse() } @Test Loading @@ -462,7 +463,33 @@ class FeatureFlagsDebugTest : SysuiTestCase() { val flag = UnreleasedFlag(100, name = "100", namespace = "test") serverFlagReader.setFlagValue(flag.namespace, flag.name, true) assertThat(mFeatureFlagsDebug.isEnabled(flag)).isTrue() assertThat(featureFlagsDebug.isEnabled(flag)).isTrue() } @Test fun serverSide_OverrideUncached_NoRestart() { // No one has read the flag, so it's not in the cache. serverFlagReader.setFlagValue( teamfoodableFlagA.namespace, teamfoodableFlagA.name, !teamfoodableFlagA.default) verify(restarter, never()).restartSystemUI(anyString()) } @Test fun serverSide_Override_Restarts() { // Read it to put it in the cache. featureFlagsDebug.isEnabled(teamfoodableFlagA) serverFlagReader.setFlagValue( teamfoodableFlagA.namespace, teamfoodableFlagA.name, !teamfoodableFlagA.default) verify(restarter).restartSystemUI(anyString()) } @Test fun serverSide_RedundantOverride_NoRestart() { // Read it to put it in the cache. featureFlagsDebug.isEnabled(teamfoodableFlagA) serverFlagReader.setFlagValue( teamfoodableFlagA.namespace, teamfoodableFlagA.name, teamfoodableFlagA.default) verify(restarter, never()).restartSystemUI(anyString()) } @Test Loading @@ -482,13 +509,13 @@ class FeatureFlagsDebugTest : SysuiTestCase() { .thenReturn("override7") // WHEN the flags have been accessed assertThat(mFeatureFlagsDebug.isEnabled(flag1)).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(flag2)).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(flag3)).isFalse() assertThat(mFeatureFlagsDebug.getString(flag4)).isEmpty() assertThat(mFeatureFlagsDebug.getString(flag5)).isEqualTo("flag5default") assertThat(mFeatureFlagsDebug.getString(flag6)).isEqualTo("resource1006") assertThat(mFeatureFlagsDebug.getString(flag7)).isEqualTo("override7") assertThat(featureFlagsDebug.isEnabled(flag1)).isTrue() assertThat(featureFlagsDebug.isEnabled(flag2)).isTrue() assertThat(featureFlagsDebug.isEnabled(flag3)).isFalse() assertThat(featureFlagsDebug.getString(flag4)).isEmpty() assertThat(featureFlagsDebug.getString(flag5)).isEqualTo("flag5default") assertThat(featureFlagsDebug.getString(flag6)).isEqualTo("resource1006") assertThat(featureFlagsDebug.getString(flag7)).isEqualTo("override7") // THEN the dump contains the flags and the default values val dump = dumpToString() Loading Loading @@ -527,7 +554,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { private fun dumpToString(): String { val sw = StringWriter() val pw = PrintWriter(sw) mFeatureFlagsDebug.dump(pw, emptyArray<String>()) featureFlagsDebug.dump(pw, emptyArray<String>()) pw.flush() return sw.toString() } Loading packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt +44 −10 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java +28 −3 Original line number Diff line number Diff line Loading @@ -85,9 +85,34 @@ public class FeatureFlagsDebug implements FeatureFlags { private final ServerFlagReader.ChangeListener mOnPropertiesChanged = new ServerFlagReader.ChangeListener() { @Override public void onChange(Flag<?> flag) { public void onChange(Flag<?> flag, String value) { boolean shouldRestart = false; if (mBooleanFlagCache.containsKey(flag.getName())) { boolean newValue = value == null ? false : Boolean.parseBoolean(value); if (mBooleanFlagCache.get(flag.getName()) != newValue) { shouldRestart = true; } } else if (mStringFlagCache.containsKey(flag.getName())) { String newValue = value == null ? "" : value; if (mStringFlagCache.get(flag.getName()) != value) { shouldRestart = true; } } else if (mIntFlagCache.containsKey(flag.getName())) { int newValue = 0; try { newValue = value == null ? 0 : Integer.parseInt(value); } catch (NumberFormatException e) { } if (mIntFlagCache.get(flag.getName()) != newValue) { shouldRestart = true; } } if (shouldRestart) { mRestarter.restartSystemUI( "Server flag change: " + flag.getNamespace() + "." + flag.getName()); "Server flag change: " + flag.getNamespace() + "." + flag.getName()); } } }; Loading
packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java +84 −30 Original line number Diff line number Diff line Loading @@ -53,13 +53,38 @@ public class FeatureFlagsRelease implements FeatureFlags { private final Map<String, Flag<?>> mAllFlags; private final Map<String, Boolean> mBooleanCache = new HashMap<>(); private final Map<String, String> mStringCache = new HashMap<>(); private final Map<String, Integer> mIntCache = new HashMap<>(); private final ServerFlagReader.ChangeListener mOnPropertiesChanged = new ServerFlagReader.ChangeListener() { @Override public void onChange(Flag<?> flag) { public void onChange(Flag<?> flag, String value) { boolean shouldRestart = false; if (mBooleanCache.containsKey(flag.getName())) { boolean newValue = value == null ? false : Boolean.parseBoolean(value); if (mBooleanCache.get(flag.getName()) != newValue) { shouldRestart = true; } } else if (mStringCache.containsKey(flag.getName())) { String newValue = value == null ? "" : value; if (mStringCache.get(flag.getName()) != newValue) { shouldRestart = true; } } else if (mIntCache.containsKey(flag.getName())) { int newValue = 0; try { newValue = value == null ? 0 : Integer.parseInt(value); } catch (NumberFormatException e) { } if (mIntCache.get(flag.getName()) != newValue) { shouldRestart = true; } } if (shouldRestart) { mRestarter.restartSystemUI( "Server flag change: " + flag.getNamespace() + "." + flag.getName()); "Server flag change: " + flag.getNamespace() + "." + flag.getName()); } } }; Loading Loading @@ -97,68 +122,97 @@ public class FeatureFlagsRelease implements FeatureFlags { @Override public boolean isEnabled(@NotNull ReleasedFlag flag) { return mServerFlagReader.readServerOverride(flag.getNamespace(), flag.getName(), true); // Fill the cache. return isEnabledInternal(flag.getName(), mServerFlagReader.readServerOverride(flag.getNamespace(), flag.getName(), true)); } @Override public boolean isEnabled(ResourceBooleanFlag flag) { if (!mBooleanCache.containsKey(flag.getName())) { return isEnabled(flag.getName(), mResources.getBoolean(flag.getResourceId())); } return mBooleanCache.get(flag.getName()); // Fill the cache. return isEnabledInternal(flag.getName(), mResources.getBoolean(flag.getResourceId())); } @Override public boolean isEnabled(SysPropBooleanFlag flag) { if (!mBooleanCache.containsKey(flag.getName())) { return isEnabled( // Fill the cache. return isEnabledInternal( flag.getName(), mSystemProperties.getBoolean(flag.getName(), flag.getDefault())); } return mBooleanCache.get(flag.getName()); /** * Checks and fills the boolean cache. This is important, Always call through to this method! * * We use the cache as a way to decide if we need to restart the process when server-side * changes occur. */ private boolean isEnabledInternal(String name, boolean defaultValue) { // Fill the cache. if (!mBooleanCache.containsKey(name)) { mBooleanCache.put(name, defaultValue); } private boolean isEnabled(String name, boolean defaultValue) { mBooleanCache.put(name, defaultValue); return defaultValue; return mBooleanCache.get(name); } @NonNull @Override public String getString(@NonNull StringFlag flag) { return getString(flag.getName(), flag.getDefault()); // Fill the cache. return getStringInternal(flag.getName(), flag.getDefault()); } @NonNull @Override public String getString(@NonNull ResourceStringFlag flag) { if (!mStringCache.containsKey(flag.getName())) { return getString(flag.getName(), // Fill the cache. return getStringInternal(flag.getName(), requireNonNull(mResources.getString(flag.getResourceId()))); } return mStringCache.get(flag.getName()); /** * Checks and fills the String cache. This is important, Always call through to this method! * * We use the cache as a way to decide if we need to restart the process when server-side * changes occur. */ private String getStringInternal(String name, String defaultValue) { if (!mStringCache.containsKey(name)) { mStringCache.put(name, defaultValue); } private String getString(String name, String defaultValue) { mStringCache.put(name, defaultValue); return defaultValue; return mStringCache.get(name); } @NonNull @Override public int getInt(@NonNull IntFlag flag) { return flag.getDefault(); // Fill the cache. return getIntInternal(flag.getName(), flag.getDefault()); } @NonNull @Override public int getInt(@NonNull ResourceIntFlag flag) { // Fill the cache. return mResources.getInteger(flag.getResourceId()); } /** * Checks and fills the integer cache. This is important, Always call through to this method! * * We use the cache as a way to decide if we need to restart the process when server-side * changes occur. */ private int getIntInternal(String name, int defaultValue) { if (!mIntCache.containsKey(name)) { mIntCache.put(name, defaultValue); } return mIntCache.get(name); } @Override public void dump(@NonNull PrintWriter pw, @NonNull String[] args) { pw.println("can override: false"); Loading
packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt +4 −3 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ interface ServerFlagReader { fun listenForChanges(values: Collection<Flag<*>>, listener: ChangeListener) interface ChangeListener { fun onChange(flag: Flag<*>) fun onChange(flag: Flag<*>, value: String?) } } Loading Loading @@ -67,7 +67,7 @@ class ServerFlagReaderImpl @Inject constructor( propLoop@ for (propName in properties.keyset) { for (flag in flags) { if (propName == flag.name) { listener.onChange(flag) listener.onChange(flag, properties.getString(propName, null)) break@propLoop } } Loading Loading @@ -144,7 +144,7 @@ class ServerFlagReaderFake : ServerFlagReader { for ((listener, flags) in listeners) { flagLoop@ for (flag in flags) { if (name == flag.name) { listener.onChange(flag) listener.onChange(flag, if (value) "true" else "false") break@flagLoop } } Loading @@ -159,5 +159,6 @@ class ServerFlagReaderFake : ServerFlagReader { flags: Collection<Flag<*>>, listener: ServerFlagReader.ChangeListener ) { listeners.add(Pair(listener, flags)) } }
packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt +82 −55 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import org.mockito.Mock import org.mockito.Mockito.anyBoolean import org.mockito.Mockito.anyString import org.mockito.Mockito.inOrder import org.mockito.Mockito.never import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions Loading @@ -53,7 +54,7 @@ import org.mockito.Mockito.`when` as whenever */ @SmallTest class FeatureFlagsDebugTest : SysuiTestCase() { private lateinit var mFeatureFlagsDebug: FeatureFlagsDebug private lateinit var featureFlagsDebug: FeatureFlagsDebug @Mock private lateinit var flagManager: FlagManager Loading Loading @@ -85,7 +86,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { flagMap.put(Flags.TEAMFOOD.name, Flags.TEAMFOOD) flagMap.put(teamfoodableFlagA.name, teamfoodableFlagA) flagMap.put(teamfoodableFlagB.name, teamfoodableFlagB) mFeatureFlagsDebug = FeatureFlagsDebug( featureFlagsDebug = FeatureFlagsDebug( flagManager, mockContext, globalSettings, Loading @@ -95,7 +96,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { flagMap, restarter ) mFeatureFlagsDebug.init() featureFlagsDebug.init() verify(flagManager).onSettingsChangedAction = any() broadcastReceiver = withArgCaptor { verify(mockContext).registerReceiver( Loading @@ -116,7 +117,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { whenever(flagManager.readFlagValue<Boolean>(eq("4"), any())).thenReturn(false) assertThat( mFeatureFlagsDebug.isEnabled( featureFlagsDebug.isEnabled( ReleasedFlag( 2, name = "2", Loading @@ -125,7 +126,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { ) ).isTrue() assertThat( mFeatureFlagsDebug.isEnabled( featureFlagsDebug.isEnabled( UnreleasedFlag( 3, name = "3", Loading @@ -134,7 +135,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { ) ).isTrue() assertThat( mFeatureFlagsDebug.isEnabled( featureFlagsDebug.isEnabled( ReleasedFlag( 4, name = "4", Loading @@ -143,7 +144,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { ) ).isFalse() assertThat( mFeatureFlagsDebug.isEnabled( featureFlagsDebug.isEnabled( UnreleasedFlag( 5, name = "5", Loading @@ -157,8 +158,8 @@ class FeatureFlagsDebugTest : SysuiTestCase() { fun teamFoodFlag_False() { whenever(flagManager.readFlagValue<Boolean>( eq(Flags.TEAMFOOD.name), any())).thenReturn(false) assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isFalse() assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue() assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagA)).isFalse() assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue() // Regular boolean flags should still test the same. // Only our teamfoodableFlag should change. Loading @@ -169,8 +170,8 @@ class FeatureFlagsDebugTest : SysuiTestCase() { fun teamFoodFlag_True() { whenever(flagManager.readFlagValue<Boolean>( eq(Flags.TEAMFOOD.name), any())).thenReturn(true) assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue() assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue() assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue() // Regular boolean flags should still test the same. // Only our teamfoodableFlag should change. Loading @@ -185,8 +186,8 @@ class FeatureFlagsDebugTest : SysuiTestCase() { .thenReturn(false) whenever(flagManager.readFlagValue<Boolean>( eq(Flags.TEAMFOOD.name), any())).thenReturn(true) assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isFalse() assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue() assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagB)).isFalse() // Regular boolean flags should still test the same. // Only our teamfoodableFlag should change. Loading @@ -205,7 +206,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { whenever(flagManager.readFlagValue<Boolean>(eq("5"), any())).thenReturn(false) assertThat( mFeatureFlagsDebug.isEnabled( featureFlagsDebug.isEnabled( ResourceBooleanFlag( 1, "1", Loading @@ -214,16 +215,16 @@ class FeatureFlagsDebugTest : SysuiTestCase() { ) ) ).isFalse() assertThat(mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(2, "2", "test", 1002))).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(3, "3", "test", 1003))).isTrue() assertThat(featureFlagsDebug.isEnabled(ResourceBooleanFlag(2, "2", "test", 1002))).isTrue() assertThat(featureFlagsDebug.isEnabled(ResourceBooleanFlag(3, "3", "test", 1003))).isTrue() Assert.assertThrows(NameNotFoundException::class.java) { mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(4, "4", "test", 1004)) featureFlagsDebug.isEnabled(ResourceBooleanFlag(4, "4", "test", 1004)) } // Test that resource is loaded (and validated) even when the setting is set. // This prevents developers from not noticing when they reference an invalid resource. Assert.assertThrows(NameNotFoundException::class.java) { mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(5, "5", "test", 1005)) featureFlagsDebug.isEnabled(ResourceBooleanFlag(5, "5", "test", 1005)) } } Loading @@ -236,11 +237,11 @@ class FeatureFlagsDebugTest : SysuiTestCase() { return@thenAnswer it.getArgument(1) } assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(1, "a", "test"))).isFalse() assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(2, "b", "test"))).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(3, "c", "test", true))).isTrue() assertThat(featureFlagsDebug.isEnabled(SysPropBooleanFlag(1, "a", "test"))).isFalse() assertThat(featureFlagsDebug.isEnabled(SysPropBooleanFlag(2, "b", "test"))).isTrue() assertThat(featureFlagsDebug.isEnabled(SysPropBooleanFlag(3, "c", "test", true))).isTrue() assertThat( mFeatureFlagsDebug.isEnabled( featureFlagsDebug.isEnabled( SysPropBooleanFlag( 4, "d", Loading @@ -249,17 +250,17 @@ class FeatureFlagsDebugTest : SysuiTestCase() { ) ) ).isFalse() assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(5, "e", "test"))).isFalse() assertThat(featureFlagsDebug.isEnabled(SysPropBooleanFlag(5, "e", "test"))).isFalse() } @Test fun readStringFlag() { whenever(flagManager.readFlagValue<String>(eq("3"), any())).thenReturn("foo") whenever(flagManager.readFlagValue<String>(eq("4"), any())).thenReturn("bar") assertThat(mFeatureFlagsDebug.getString(StringFlag(1, "1", "test", "biz"))).isEqualTo("biz") assertThat(mFeatureFlagsDebug.getString(StringFlag(2, "2", "test", "baz"))).isEqualTo("baz") assertThat(mFeatureFlagsDebug.getString(StringFlag(3, "3", "test", "buz"))).isEqualTo("foo") assertThat(mFeatureFlagsDebug.getString(StringFlag(4, "4", "test", "buz"))).isEqualTo("bar") assertThat(featureFlagsDebug.getString(StringFlag(1, "1", "test", "biz"))).isEqualTo("biz") assertThat(featureFlagsDebug.getString(StringFlag(2, "2", "test", "baz"))).isEqualTo("baz") assertThat(featureFlagsDebug.getString(StringFlag(3, "3", "test", "buz"))).isEqualTo("foo") assertThat(featureFlagsDebug.getString(StringFlag(4, "4", "test", "buz"))).isEqualTo("bar") } @Test Loading @@ -276,7 +277,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { whenever(flagManager.readFlagValue<String>(eq("6"), any())).thenReturn("override6") assertThat( mFeatureFlagsDebug.getString( featureFlagsDebug.getString( ResourceStringFlag( 1, "1", Loading @@ -286,7 +287,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { ) ).isEqualTo("") assertThat( mFeatureFlagsDebug.getString( featureFlagsDebug.getString( ResourceStringFlag( 2, "2", Loading @@ -296,7 +297,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { ) ).isEqualTo("resource2") assertThat( mFeatureFlagsDebug.getString( featureFlagsDebug.getString( ResourceStringFlag( 3, "3", Loading @@ -307,15 +308,15 @@ class FeatureFlagsDebugTest : SysuiTestCase() { ).isEqualTo("override3") Assert.assertThrows(NullPointerException::class.java) { mFeatureFlagsDebug.getString(ResourceStringFlag(4, "4", "test", 1004)) featureFlagsDebug.getString(ResourceStringFlag(4, "4", "test", 1004)) } Assert.assertThrows(NameNotFoundException::class.java) { mFeatureFlagsDebug.getString(ResourceStringFlag(5, "5", "test", 1005)) featureFlagsDebug.getString(ResourceStringFlag(5, "5", "test", 1005)) } // Test that resource is loaded (and validated) even when the setting is set. // This prevents developers from not noticing when they reference an invalid resource. Assert.assertThrows(NameNotFoundException::class.java) { mFeatureFlagsDebug.getString(ResourceStringFlag(6, "6", "test", 1005)) featureFlagsDebug.getString(ResourceStringFlag(6, "6", "test", 1005)) } } Loading @@ -323,10 +324,10 @@ class FeatureFlagsDebugTest : SysuiTestCase() { fun readIntFlag() { whenever(flagManager.readFlagValue<Int>(eq("3"), any())).thenReturn(22) whenever(flagManager.readFlagValue<Int>(eq("4"), any())).thenReturn(48) assertThat(mFeatureFlagsDebug.getInt(IntFlag(1, "1", "test", 12))).isEqualTo(12) assertThat(mFeatureFlagsDebug.getInt(IntFlag(2, "2", "test", 93))).isEqualTo(93) assertThat(mFeatureFlagsDebug.getInt(IntFlag(3, "3", "test", 8))).isEqualTo(22) assertThat(mFeatureFlagsDebug.getInt(IntFlag(4, "4", "test", 234))).isEqualTo(48) assertThat(featureFlagsDebug.getInt(IntFlag(1, "1", "test", 12))).isEqualTo(12) assertThat(featureFlagsDebug.getInt(IntFlag(2, "2", "test", 93))).isEqualTo(93) assertThat(featureFlagsDebug.getInt(IntFlag(3, "3", "test", 8))).isEqualTo(22) assertThat(featureFlagsDebug.getInt(IntFlag(4, "4", "test", 234))).isEqualTo(48) } @Test Loading @@ -342,17 +343,17 @@ class FeatureFlagsDebugTest : SysuiTestCase() { whenever(flagManager.readFlagValue<Int>(eq(4), any())).thenReturn(500) whenever(flagManager.readFlagValue<Int>(eq(5), any())).thenReturn(9519) assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(1, "1", "test", 1001))).isEqualTo(88) assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(2, "2", "test", 1002))).isEqualTo(61) assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(3, "3", "test", 1003))).isEqualTo(20) assertThat(featureFlagsDebug.getInt(ResourceIntFlag(1, "1", "test", 1001))).isEqualTo(88) assertThat(featureFlagsDebug.getInt(ResourceIntFlag(2, "2", "test", 1002))).isEqualTo(61) assertThat(featureFlagsDebug.getInt(ResourceIntFlag(3, "3", "test", 1003))).isEqualTo(20) Assert.assertThrows(NotFoundException::class.java) { mFeatureFlagsDebug.getInt(ResourceIntFlag(4, "4", "test", 1004)) featureFlagsDebug.getInt(ResourceIntFlag(4, "4", "test", 1004)) } // Test that resource is loaded (and validated) even when the setting is set. // This prevents developers from not noticing when they reference an invalid resource. Assert.assertThrows(NotFoundException::class.java) { mFeatureFlagsDebug.getInt(ResourceIntFlag(5, "5", "test", 1005)) featureFlagsDebug.getInt(ResourceIntFlag(5, "5", "test", 1005)) } } Loading Loading @@ -432,11 +433,11 @@ class FeatureFlagsDebugTest : SysuiTestCase() { whenever(flagManager.readFlagValue<String>(eq("1"), any())).thenReturn("original") // gets the flag & cache it assertThat(mFeatureFlagsDebug.getString(flag1)).isEqualTo("original") assertThat(featureFlagsDebug.getString(flag1)).isEqualTo("original") verify(flagManager, times(1)).readFlagValue(eq("1"), eq(StringFlagSerializer)) // hit the cache assertThat(mFeatureFlagsDebug.getString(flag1)).isEqualTo("original") assertThat(featureFlagsDebug.getString(flag1)).isEqualTo("original") verifyNoMoreInteractions(flagManager) // set the flag Loading @@ -444,7 +445,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { verifyPutData("1", "{\"type\":\"string\",\"value\":\"new\"}", numReads = 2) whenever(flagManager.readFlagValue<String>(eq("1"), any())).thenReturn("new") assertThat(mFeatureFlagsDebug.getString(flag1)).isEqualTo("new") assertThat(featureFlagsDebug.getString(flag1)).isEqualTo("new") verify(flagManager, times(3)).readFlagValue(eq("1"), eq(StringFlagSerializer)) } Loading @@ -454,7 +455,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { serverFlagReader.setFlagValue(flag.namespace, flag.name, false) assertThat(mFeatureFlagsDebug.isEnabled(flag)).isFalse() assertThat(featureFlagsDebug.isEnabled(flag)).isFalse() } @Test Loading @@ -462,7 +463,33 @@ class FeatureFlagsDebugTest : SysuiTestCase() { val flag = UnreleasedFlag(100, name = "100", namespace = "test") serverFlagReader.setFlagValue(flag.namespace, flag.name, true) assertThat(mFeatureFlagsDebug.isEnabled(flag)).isTrue() assertThat(featureFlagsDebug.isEnabled(flag)).isTrue() } @Test fun serverSide_OverrideUncached_NoRestart() { // No one has read the flag, so it's not in the cache. serverFlagReader.setFlagValue( teamfoodableFlagA.namespace, teamfoodableFlagA.name, !teamfoodableFlagA.default) verify(restarter, never()).restartSystemUI(anyString()) } @Test fun serverSide_Override_Restarts() { // Read it to put it in the cache. featureFlagsDebug.isEnabled(teamfoodableFlagA) serverFlagReader.setFlagValue( teamfoodableFlagA.namespace, teamfoodableFlagA.name, !teamfoodableFlagA.default) verify(restarter).restartSystemUI(anyString()) } @Test fun serverSide_RedundantOverride_NoRestart() { // Read it to put it in the cache. featureFlagsDebug.isEnabled(teamfoodableFlagA) serverFlagReader.setFlagValue( teamfoodableFlagA.namespace, teamfoodableFlagA.name, teamfoodableFlagA.default) verify(restarter, never()).restartSystemUI(anyString()) } @Test Loading @@ -482,13 +509,13 @@ class FeatureFlagsDebugTest : SysuiTestCase() { .thenReturn("override7") // WHEN the flags have been accessed assertThat(mFeatureFlagsDebug.isEnabled(flag1)).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(flag2)).isTrue() assertThat(mFeatureFlagsDebug.isEnabled(flag3)).isFalse() assertThat(mFeatureFlagsDebug.getString(flag4)).isEmpty() assertThat(mFeatureFlagsDebug.getString(flag5)).isEqualTo("flag5default") assertThat(mFeatureFlagsDebug.getString(flag6)).isEqualTo("resource1006") assertThat(mFeatureFlagsDebug.getString(flag7)).isEqualTo("override7") assertThat(featureFlagsDebug.isEnabled(flag1)).isTrue() assertThat(featureFlagsDebug.isEnabled(flag2)).isTrue() assertThat(featureFlagsDebug.isEnabled(flag3)).isFalse() assertThat(featureFlagsDebug.getString(flag4)).isEmpty() assertThat(featureFlagsDebug.getString(flag5)).isEqualTo("flag5default") assertThat(featureFlagsDebug.getString(flag6)).isEqualTo("resource1006") assertThat(featureFlagsDebug.getString(flag7)).isEqualTo("override7") // THEN the dump contains the flags and the default values val dump = dumpToString() Loading Loading @@ -527,7 +554,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() { private fun dumpToString(): String { val sw = StringWriter() val pw = PrintWriter(sw) mFeatureFlagsDebug.dump(pw, emptyArray<String>()) featureFlagsDebug.dump(pw, emptyArray<String>()) pw.flush() return sw.toString() } Loading
packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt +44 −10 File changed.Preview size limit exceeded, changes collapsed. Show changes