Add server flag support to flags.
Bug: 249121873 Test: atest SystemUITests Change-Id: I7fe0bd122cbcc3365abe7f4071a76a04783ff3d0
This commit is contained in:
@@ -22,9 +22,19 @@ import android.annotation.StringRes
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
|
||||
/**
|
||||
* Base interface for flags that can change value on a running device.
|
||||
* @property id unique id to help identify this flag. Must be unique. This will be removed soon.
|
||||
* @property teamfood Set to true to include this flag as part of the teamfood flag. This will
|
||||
* be removed soon.
|
||||
* @property name Used for server-side flagging where appropriate. Also used for display. No spaces.
|
||||
* @property namespace The server-side namespace that this flag lives under.
|
||||
*/
|
||||
interface Flag<T> {
|
||||
val id: Int
|
||||
val teamfood: Boolean
|
||||
val name: String
|
||||
val namespace: String
|
||||
}
|
||||
|
||||
interface ParcelableFlag<T> : Flag<T>, Parcelable {
|
||||
@@ -38,13 +48,10 @@ interface ResourceFlag<T> : Flag<T> {
|
||||
}
|
||||
|
||||
interface DeviceConfigFlag<T> : Flag<T> {
|
||||
val name: String
|
||||
val namespace: String
|
||||
val default: T
|
||||
}
|
||||
|
||||
interface SysPropFlag<T> : Flag<T> {
|
||||
val name: String
|
||||
val default: T
|
||||
}
|
||||
|
||||
@@ -57,6 +64,8 @@ interface SysPropFlag<T> : Flag<T> {
|
||||
abstract class BooleanFlag constructor(
|
||||
override val id: Int,
|
||||
override val default: Boolean = false,
|
||||
override val name: String = "",
|
||||
override val namespace: String = "",
|
||||
override val teamfood: Boolean = false,
|
||||
override val overridden: Boolean = false
|
||||
) : ParcelableFlag<Boolean> {
|
||||
@@ -91,20 +100,24 @@ abstract class BooleanFlag constructor(
|
||||
*/
|
||||
data class UnreleasedFlag constructor(
|
||||
override val id: Int,
|
||||
override val name: String = "",
|
||||
override val namespace: String = "",
|
||||
override val teamfood: Boolean = false,
|
||||
override val overridden: Boolean = false
|
||||
) : BooleanFlag(id, false, teamfood, overridden)
|
||||
) : BooleanFlag(id, false, name, namespace, teamfood, overridden)
|
||||
|
||||
/**
|
||||
* A Flag that is is true by default.
|
||||
* A Flag that is true by default.
|
||||
*
|
||||
* It can be changed or overridden in any build, meaning it can be turned off if needed.
|
||||
*/
|
||||
data class ReleasedFlag constructor(
|
||||
override val id: Int,
|
||||
override val name: String = "",
|
||||
override val namespace: String = "",
|
||||
override val teamfood: Boolean = false,
|
||||
override val overridden: Boolean = false
|
||||
) : BooleanFlag(id, true, teamfood, overridden)
|
||||
) : BooleanFlag(id, true, name, namespace, teamfood, overridden)
|
||||
|
||||
/**
|
||||
* A Flag that reads its default values from a resource overlay instead of code.
|
||||
@@ -114,6 +127,8 @@ data class ReleasedFlag constructor(
|
||||
data class ResourceBooleanFlag constructor(
|
||||
override val id: Int,
|
||||
@BoolRes override val resourceId: Int,
|
||||
override val name: String = "",
|
||||
override val namespace: String = "",
|
||||
override val teamfood: Boolean = false
|
||||
) : ResourceFlag<Boolean>
|
||||
|
||||
@@ -142,7 +157,8 @@ data class DeviceConfigBooleanFlag constructor(
|
||||
data class SysPropBooleanFlag constructor(
|
||||
override val id: Int,
|
||||
override val name: String,
|
||||
override val default: Boolean = false
|
||||
override val default: Boolean = false,
|
||||
override val namespace: String = ""
|
||||
) : SysPropFlag<Boolean> {
|
||||
// TODO(b/223379190): Teamfood not supported for sysprop flags yet.
|
||||
override val teamfood: Boolean = false
|
||||
@@ -151,6 +167,8 @@ data class SysPropBooleanFlag constructor(
|
||||
data class StringFlag constructor(
|
||||
override val id: Int,
|
||||
override val default: String = "",
|
||||
override val name: String = "",
|
||||
override val namespace: String = "",
|
||||
override val teamfood: Boolean = false,
|
||||
override val overridden: Boolean = false
|
||||
) : ParcelableFlag<String> {
|
||||
@@ -176,12 +194,16 @@ data class StringFlag constructor(
|
||||
data class ResourceStringFlag constructor(
|
||||
override val id: Int,
|
||||
@StringRes override val resourceId: Int,
|
||||
override val name: String = "",
|
||||
override val namespace: String = "",
|
||||
override val teamfood: Boolean = false
|
||||
) : ResourceFlag<String>
|
||||
|
||||
data class IntFlag constructor(
|
||||
override val id: Int,
|
||||
override val default: Int = 0,
|
||||
override val name: String = "",
|
||||
override val namespace: String = "",
|
||||
override val teamfood: Boolean = false,
|
||||
override val overridden: Boolean = false
|
||||
) : ParcelableFlag<Int> {
|
||||
@@ -208,6 +230,8 @@ data class IntFlag constructor(
|
||||
data class ResourceIntFlag constructor(
|
||||
override val id: Int,
|
||||
@IntegerRes override val resourceId: Int,
|
||||
override val name: String = "",
|
||||
override val namespace: String = "",
|
||||
override val teamfood: Boolean = false
|
||||
) : ResourceFlag<Int>
|
||||
|
||||
@@ -215,6 +239,8 @@ data class LongFlag constructor(
|
||||
override val id: Int,
|
||||
override val default: Long = 0,
|
||||
override val teamfood: Boolean = false,
|
||||
override val name: String = "",
|
||||
override val namespace: String = "",
|
||||
override val overridden: Boolean = false
|
||||
) : ParcelableFlag<Long> {
|
||||
|
||||
@@ -240,6 +266,8 @@ data class LongFlag constructor(
|
||||
data class FloatFlag constructor(
|
||||
override val id: Int,
|
||||
override val default: Float = 0f,
|
||||
override val name: String = "",
|
||||
override val namespace: String = "",
|
||||
override val teamfood: Boolean = false,
|
||||
override val overridden: Boolean = false
|
||||
) : ParcelableFlag<Float> {
|
||||
@@ -266,13 +294,17 @@ data class FloatFlag constructor(
|
||||
data class ResourceFloatFlag constructor(
|
||||
override val id: Int,
|
||||
override val resourceId: Int,
|
||||
override val teamfood: Boolean = false
|
||||
override val name: String = "",
|
||||
override val namespace: String = "",
|
||||
override val teamfood: Boolean = false,
|
||||
) : ResourceFlag<Int>
|
||||
|
||||
data class DoubleFlag constructor(
|
||||
override val id: Int,
|
||||
override val default: Double = 0.0,
|
||||
override val teamfood: Boolean = false,
|
||||
override val name: String = "",
|
||||
override val namespace: String = "",
|
||||
override val overridden: Boolean = false
|
||||
) : ParcelableFlag<Double> {
|
||||
|
||||
|
||||
@@ -33,9 +33,6 @@ interface FeatureFlags : FlagListenable, Dumpable {
|
||||
/** Returns a boolean value for the given flag. */
|
||||
fun isEnabled(flag: ResourceBooleanFlag): Boolean
|
||||
|
||||
/** Returns a boolean value for the given flag. */
|
||||
fun isEnabled(flag: DeviceConfigBooleanFlag): Boolean
|
||||
|
||||
/** Returns a boolean value for the given flag. */
|
||||
fun isEnabled(flag: SysPropBooleanFlag): Boolean
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@ import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.util.DeviceConfigProxy;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -76,7 +75,6 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
||||
private final SecureSettings mSecureSettings;
|
||||
private final Resources mResources;
|
||||
private final SystemPropertiesHelper mSystemProperties;
|
||||
private final DeviceConfigProxy mDeviceConfigProxy;
|
||||
private final ServerFlagReader mServerFlagReader;
|
||||
private final Map<Integer, Flag<?>> mAllFlags;
|
||||
private final Map<Integer, Boolean> mBooleanFlagCache = new TreeMap<>();
|
||||
@@ -99,7 +97,6 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
||||
SecureSettings secureSettings,
|
||||
SystemPropertiesHelper systemProperties,
|
||||
@Main Resources resources,
|
||||
DeviceConfigProxy deviceConfigProxy,
|
||||
ServerFlagReader serverFlagReader,
|
||||
@Named(ALL_FLAGS) Map<Integer, Flag<?>> allFlags,
|
||||
Restarter restarter) {
|
||||
@@ -108,7 +105,6 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
||||
mSecureSettings = secureSettings;
|
||||
mResources = resources;
|
||||
mSystemProperties = systemProperties;
|
||||
mDeviceConfigProxy = deviceConfigProxy;
|
||||
mServerFlagReader = serverFlagReader;
|
||||
mAllFlags = allFlags;
|
||||
mRestarter = restarter;
|
||||
@@ -140,7 +136,7 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
||||
int id = flag.getId();
|
||||
if (!mBooleanFlagCache.containsKey(id)) {
|
||||
mBooleanFlagCache.put(id,
|
||||
readFlagValue(id, flag.getDefault()));
|
||||
readBooleanFlagInternal(flag, flag.getDefault()));
|
||||
}
|
||||
|
||||
return mBooleanFlagCache.get(id);
|
||||
@@ -151,19 +147,7 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
||||
int id = flag.getId();
|
||||
if (!mBooleanFlagCache.containsKey(id)) {
|
||||
mBooleanFlagCache.put(id,
|
||||
readFlagValue(id, mResources.getBoolean(flag.getResourceId())));
|
||||
}
|
||||
|
||||
return mBooleanFlagCache.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(@NonNull DeviceConfigBooleanFlag flag) {
|
||||
int id = flag.getId();
|
||||
if (!mBooleanFlagCache.containsKey(id)) {
|
||||
boolean deviceConfigValue = mDeviceConfigProxy.getBoolean(flag.getNamespace(),
|
||||
flag.getName(), flag.getDefault());
|
||||
mBooleanFlagCache.put(id, readFlagValue(id, deviceConfigValue));
|
||||
readBooleanFlagInternal(flag, mResources.getBoolean(flag.getResourceId())));
|
||||
}
|
||||
|
||||
return mBooleanFlagCache.get(id);
|
||||
@@ -179,7 +163,7 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
||||
id,
|
||||
mSystemProperties.getBoolean(
|
||||
flag.getName(),
|
||||
readFlagValue(id, flag.getDefault())));
|
||||
readBooleanFlagInternal(flag, flag.getDefault())));
|
||||
}
|
||||
|
||||
return mBooleanFlagCache.get(id);
|
||||
@@ -191,7 +175,7 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
||||
int id = flag.getId();
|
||||
if (!mStringFlagCache.containsKey(id)) {
|
||||
mStringFlagCache.put(id,
|
||||
readFlagValue(id, flag.getDefault(), StringFlagSerializer.INSTANCE));
|
||||
readFlagValueInternal(id, flag.getDefault(), StringFlagSerializer.INSTANCE));
|
||||
}
|
||||
|
||||
return mStringFlagCache.get(id);
|
||||
@@ -203,20 +187,21 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
||||
int id = flag.getId();
|
||||
if (!mStringFlagCache.containsKey(id)) {
|
||||
mStringFlagCache.put(id,
|
||||
readFlagValue(id, mResources.getString(flag.getResourceId()),
|
||||
readFlagValueInternal(id, mResources.getString(flag.getResourceId()),
|
||||
StringFlagSerializer.INSTANCE));
|
||||
}
|
||||
|
||||
return mStringFlagCache.get(id);
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public int getInt(@NonNull IntFlag flag) {
|
||||
int id = flag.getId();
|
||||
if (!mIntFlagCache.containsKey(id)) {
|
||||
mIntFlagCache.put(id,
|
||||
readFlagValue(id, flag.getDefault(), IntFlagSerializer.INSTANCE));
|
||||
readFlagValueInternal(id, flag.getDefault(), IntFlagSerializer.INSTANCE));
|
||||
}
|
||||
|
||||
return mIntFlagCache.get(id);
|
||||
@@ -228,27 +213,31 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
||||
int id = flag.getId();
|
||||
if (!mIntFlagCache.containsKey(id)) {
|
||||
mIntFlagCache.put(id,
|
||||
readFlagValue(id, mResources.getInteger(flag.getResourceId()),
|
||||
readFlagValueInternal(id, mResources.getInteger(flag.getResourceId()),
|
||||
IntFlagSerializer.INSTANCE));
|
||||
}
|
||||
|
||||
return mIntFlagCache.get(id);
|
||||
}
|
||||
|
||||
/** Specific override for Boolean flags that checks against the teamfood list. */
|
||||
private boolean readFlagValue(int id, boolean defaultValue) {
|
||||
Boolean result = readBooleanFlagOverride(id);
|
||||
boolean hasServerOverride = mServerFlagReader.hasOverride(id);
|
||||
/** Specific override for Boolean flags that checks against the teamfood list.*/
|
||||
private boolean readBooleanFlagInternal(Flag<Boolean> flag, boolean defaultValue) {
|
||||
Boolean result = readBooleanFlagOverride(flag.getId());
|
||||
boolean hasServerOverride = mServerFlagReader.hasOverride(
|
||||
flag.getNamespace(), flag.getName());
|
||||
|
||||
// Only check for teamfood if the default is false
|
||||
// and there is no server override.
|
||||
if (!hasServerOverride && !defaultValue && result == null && id != Flags.TEAMFOOD.getId()) {
|
||||
if (mAllFlags.containsKey(id) && mAllFlags.get(id).getTeamfood()) {
|
||||
return isEnabled(Flags.TEAMFOOD);
|
||||
}
|
||||
if (!hasServerOverride
|
||||
&& !defaultValue
|
||||
&& result == null
|
||||
&& flag.getId() != Flags.TEAMFOOD.getId()
|
||||
&& flag.getTeamfood()) {
|
||||
return isEnabled(Flags.TEAMFOOD);
|
||||
}
|
||||
|
||||
return result == null ? mServerFlagReader.readServerOverride(id, defaultValue) : result;
|
||||
return result == null ? mServerFlagReader.readServerOverride(
|
||||
flag.getNamespace(), flag.getName(), defaultValue) : result;
|
||||
}
|
||||
|
||||
private Boolean readBooleanFlagOverride(int id) {
|
||||
@@ -256,7 +245,8 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private <T> T readFlagValue(int id, @NonNull T defaultValue, FlagSerializer<T> serializer) {
|
||||
private <T> T readFlagValueInternal(
|
||||
int id, @NonNull T defaultValue, FlagSerializer<T> serializer) {
|
||||
requireNonNull(defaultValue, "defaultValue");
|
||||
T result = readFlagValueInternal(id, serializer);
|
||||
return result == null ? defaultValue : result;
|
||||
@@ -355,8 +345,6 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
||||
setFlagValue(flag.getId(), value, BooleanFlagSerializer.INSTANCE);
|
||||
} else if (flag instanceof ResourceBooleanFlag) {
|
||||
setFlagValue(flag.getId(), value, BooleanFlagSerializer.INSTANCE);
|
||||
} else if (flag instanceof DeviceConfigBooleanFlag) {
|
||||
setFlagValue(flag.getId(), value, BooleanFlagSerializer.INSTANCE);
|
||||
} else if (flag instanceof SysPropBooleanFlag) {
|
||||
// Store SysProp flags in SystemProperties where they can read by outside parties.
|
||||
mSystemProperties.setBoolean(((SysPropBooleanFlag) flag).getName(), value);
|
||||
@@ -474,9 +462,6 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
||||
} else if (f instanceof ResourceBooleanFlag) {
|
||||
enabled = isEnabled((ResourceBooleanFlag) f);
|
||||
overridden = readBooleanFlagOverride(f.getId()) != null;
|
||||
} else if (f instanceof DeviceConfigBooleanFlag) {
|
||||
enabled = isEnabled((DeviceConfigBooleanFlag) f);
|
||||
overridden = false;
|
||||
} else if (f instanceof SysPropBooleanFlag) {
|
||||
// TODO(b/223379190): Teamfood not supported for sysprop flags yet.
|
||||
enabled = isEnabled((SysPropBooleanFlag) f);
|
||||
@@ -489,9 +474,11 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
return new ReleasedFlag(f.getId(), teamfood, overridden);
|
||||
return new ReleasedFlag(
|
||||
f.getId(), f.getName(), f.getNamespace(), teamfood, overridden);
|
||||
} else {
|
||||
return new UnreleasedFlag(f.getId(), teamfood, overridden);
|
||||
return new UnreleasedFlag(
|
||||
f.getId(), f.getName(), f.getNamespace(), teamfood, overridden);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -101,7 +101,7 @@ public class FeatureFlagsRelease implements FeatureFlags {
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(@NotNull ReleasedFlag flag) {
|
||||
return mServerFlagReader.readServerOverride(flag.getId(), true);
|
||||
return mServerFlagReader.readServerOverride(flag.getNamespace(), flag.getName(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -114,18 +114,6 @@ public class FeatureFlagsRelease implements FeatureFlags {
|
||||
return mBooleanCache.valueAt(cacheIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(@NonNull DeviceConfigBooleanFlag flag) {
|
||||
int cacheIndex = mBooleanCache.indexOfKey(flag.getId());
|
||||
if (cacheIndex < 0) {
|
||||
boolean deviceConfigValue = mDeviceConfigProxy.getBoolean(flag.getNamespace(),
|
||||
flag.getName(), flag.getDefault());
|
||||
return isEnabled(flag.getId(), deviceConfigValue);
|
||||
}
|
||||
|
||||
return mBooleanCache.valueAt(cacheIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(SysPropBooleanFlag flag) {
|
||||
int cacheIndex = mBooleanCache.indexOfKey(flag.getId());
|
||||
|
||||
@@ -264,11 +264,10 @@ object Flags {
|
||||
@Keep
|
||||
@JvmField
|
||||
val WM_ENABLE_PARTIAL_SCREEN_SHARING =
|
||||
DeviceConfigBooleanFlag(
|
||||
UnreleasedFlag(
|
||||
1102,
|
||||
"record_task_content",
|
||||
DeviceConfig.NAMESPACE_WINDOW_MANAGER,
|
||||
false,
|
||||
name = "record_task_content",
|
||||
namespace = DeviceConfig.NAMESPACE_WINDOW_MANAGER,
|
||||
teamfood = true
|
||||
)
|
||||
|
||||
|
||||
@@ -27,11 +27,10 @@ import javax.inject.Inject
|
||||
|
||||
interface ServerFlagReader {
|
||||
/** Returns true if there is a server-side setting stored. */
|
||||
fun hasOverride(flagId: Int): Boolean
|
||||
fun hasOverride(namespace: String, name: String): Boolean
|
||||
|
||||
/** Returns any stored server-side setting or the default if not set. */
|
||||
fun readServerOverride(flagId: Int, default: Boolean): Boolean
|
||||
|
||||
fun readServerOverride(namespace: String, name: String, default: Boolean): Boolean
|
||||
/** Register a listener for changes to any of the passed in flags. */
|
||||
fun listenForChanges(values: Collection<Flag<*>>, listener: ChangeListener)
|
||||
|
||||
@@ -68,19 +67,19 @@ class ServerFlagReaderImpl @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun hasOverride(flagId: Int): Boolean =
|
||||
deviceConfig.getProperty(
|
||||
override fun hasOverride(namespace: String, name: String): Boolean =
|
||||
!namespace.isBlank() && !name.isBlank() && deviceConfig.getProperty(
|
||||
namespace,
|
||||
getServerOverrideName(flagId)
|
||||
name
|
||||
) != null
|
||||
|
||||
override fun readServerOverride(flagId: Int, default: Boolean): Boolean {
|
||||
return deviceConfig.getBoolean(
|
||||
|
||||
override fun readServerOverride(namespace: String, name: String, default: Boolean): Boolean =
|
||||
!namespace.isBlank() && !name.isBlank() && deviceConfig.getBoolean(
|
||||
namespace,
|
||||
getServerOverrideName(flagId),
|
||||
name,
|
||||
default
|
||||
)
|
||||
}
|
||||
|
||||
override fun listenForChanges(
|
||||
flags: Collection<Flag<*>>,
|
||||
@@ -121,24 +120,24 @@ interface ServerFlagReaderModule {
|
||||
}
|
||||
|
||||
class ServerFlagReaderFake : ServerFlagReader {
|
||||
private val flagMap: MutableMap<Int, Boolean> = mutableMapOf()
|
||||
private val flagMap: MutableMap<String, Boolean> = mutableMapOf()
|
||||
private val listeners =
|
||||
mutableListOf<Pair<ServerFlagReader.ChangeListener, Collection<Flag<*>>>>()
|
||||
|
||||
override fun hasOverride(flagId: Int): Boolean {
|
||||
return flagMap.containsKey(flagId)
|
||||
override fun hasOverride(namespace: String, name: String): Boolean {
|
||||
return flagMap.containsKey(name)
|
||||
}
|
||||
|
||||
override fun readServerOverride(flagId: Int, default: Boolean): Boolean {
|
||||
return flagMap.getOrDefault(flagId, default)
|
||||
override fun readServerOverride(namespace: String, name: String, default: Boolean): Boolean {
|
||||
return flagMap.getOrDefault(name, default)
|
||||
}
|
||||
|
||||
fun setFlagValue(flagId: Int, value: Boolean) {
|
||||
flagMap.put(flagId, value)
|
||||
fun setFlagValue(namespace: String, name: String, value: Boolean) {
|
||||
flagMap.put(name, value)
|
||||
|
||||
for ((listener, flags) in listeners) {
|
||||
flagLoop@ for (flag in flags) {
|
||||
if (flagId == flag.id) {
|
||||
if (name == flag.name) {
|
||||
listener.onChange()
|
||||
break@flagLoop
|
||||
}
|
||||
@@ -146,8 +145,8 @@ class ServerFlagReaderFake : ServerFlagReader {
|
||||
}
|
||||
}
|
||||
|
||||
fun eraseFlag(flagId: Int) {
|
||||
flagMap.remove(flagId)
|
||||
fun eraseFlag(namespace: String, name: String) {
|
||||
flagMap.remove(name)
|
||||
}
|
||||
|
||||
override fun listenForChanges(
|
||||
|
||||
@@ -31,10 +31,6 @@ import com.android.systemui.util.mockito.nullable
|
||||
import com.android.systemui.util.mockito.withArgCaptor
|
||||
import com.android.systemui.util.settings.SecureSettings
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import java.io.PrintWriter
|
||||
import java.io.Serializable
|
||||
import java.io.StringWriter
|
||||
import java.util.function.Consumer
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
@@ -46,8 +42,12 @@ import org.mockito.Mockito.inOrder
|
||||
import org.mockito.Mockito.times
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.verifyNoMoreInteractions
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.MockitoAnnotations
|
||||
import java.io.PrintWriter
|
||||
import java.io.Serializable
|
||||
import java.io.StringWriter
|
||||
import java.util.function.Consumer
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
|
||||
/**
|
||||
* NOTE: This test is for the version of FeatureFlagManager in src-debug, which allows overriding
|
||||
@@ -70,8 +70,8 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
||||
private val serverFlagReader = ServerFlagReaderFake()
|
||||
|
||||
private val deviceConfig = DeviceConfigProxyFake()
|
||||
private val teamfoodableFlagA = UnreleasedFlag(500, true)
|
||||
private val teamfoodableFlagB = ReleasedFlag(501, true)
|
||||
private val teamfoodableFlagA = UnreleasedFlag(500, teamfood = true)
|
||||
private val teamfoodableFlagB = ReleasedFlag(501, teamfood = true)
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
@@ -84,7 +84,6 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
||||
secureSettings,
|
||||
systemProperties,
|
||||
resources,
|
||||
deviceConfig,
|
||||
serverFlagReader,
|
||||
flagMap,
|
||||
restarter
|
||||
@@ -191,21 +190,6 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
||||
assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(5, "e"))).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun readDeviceConfigBooleanFlag() {
|
||||
val namespace = "test_namespace"
|
||||
deviceConfig.setProperty(namespace, "a", "true", false)
|
||||
deviceConfig.setProperty(namespace, "b", "false", false)
|
||||
deviceConfig.setProperty(namespace, "c", null, false)
|
||||
|
||||
assertThat(mFeatureFlagsDebug.isEnabled(DeviceConfigBooleanFlag(1, "a", namespace)))
|
||||
.isTrue()
|
||||
assertThat(mFeatureFlagsDebug.isEnabled(DeviceConfigBooleanFlag(2, "b", namespace)))
|
||||
.isFalse()
|
||||
assertThat(mFeatureFlagsDebug.isEnabled(DeviceConfigBooleanFlag(3, "c", namespace)))
|
||||
.isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun readStringFlag() {
|
||||
whenever(flagManager.readFlagValue<String>(eq(3), any())).thenReturn("foo")
|
||||
@@ -379,7 +363,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
||||
fun serverSide_Overrides_MakesFalse() {
|
||||
val flag = ReleasedFlag(100)
|
||||
|
||||
serverFlagReader.setFlagValue(flag.id, false)
|
||||
serverFlagReader.setFlagValue(flag.namespace, flag.name, false)
|
||||
|
||||
assertThat(mFeatureFlagsDebug.isEnabled(flag)).isFalse()
|
||||
}
|
||||
@@ -388,7 +372,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
||||
fun serverSide_Overrides_MakesTrue() {
|
||||
val flag = UnreleasedFlag(100)
|
||||
|
||||
serverFlagReader.setFlagValue(flag.id, true)
|
||||
serverFlagReader.setFlagValue(flag.namespace, flag.name, true)
|
||||
|
||||
assertThat(mFeatureFlagsDebug.isEnabled(flag)).isTrue()
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ import org.junit.Assert.assertThrows
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
|
||||
/**
|
||||
* NOTE: This test is for the version of FeatureFlagManager in src-release, which should not allow
|
||||
@@ -82,21 +82,6 @@ class FeatureFlagsReleaseTest : SysuiTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testReadDeviceConfigBooleanFlag() {
|
||||
val namespace = "test_namespace"
|
||||
deviceConfig.setProperty(namespace, "a", "true", false)
|
||||
deviceConfig.setProperty(namespace, "b", "false", false)
|
||||
deviceConfig.setProperty(namespace, "c", null, false)
|
||||
|
||||
assertThat(mFeatureFlagsRelease.isEnabled(DeviceConfigBooleanFlag(1, "a", namespace)))
|
||||
.isTrue()
|
||||
assertThat(mFeatureFlagsRelease.isEnabled(DeviceConfigBooleanFlag(2, "b", namespace)))
|
||||
.isFalse()
|
||||
assertThat(mFeatureFlagsRelease.isEnabled(DeviceConfigBooleanFlag(3, "c", namespace)))
|
||||
.isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSysPropBooleanFlag() {
|
||||
val flagId = 213
|
||||
@@ -112,7 +97,7 @@ class FeatureFlagsReleaseTest : SysuiTestCase() {
|
||||
fun serverSide_OverridesReleased_MakesFalse() {
|
||||
val flag = ReleasedFlag(100)
|
||||
|
||||
serverFlagReader.setFlagValue(flag.id, false)
|
||||
serverFlagReader.setFlagValue(flag.namespace, flag.name, false)
|
||||
|
||||
assertThat(mFeatureFlagsRelease.isEnabled(flag)).isFalse()
|
||||
}
|
||||
@@ -121,7 +106,7 @@ class FeatureFlagsReleaseTest : SysuiTestCase() {
|
||||
fun serverSide_OverridesUnreleased_Ignored() {
|
||||
val flag = UnreleasedFlag(100)
|
||||
|
||||
serverFlagReader.setFlagValue(flag.id, true)
|
||||
serverFlagReader.setFlagValue(flag.namespace, flag.name, true)
|
||||
|
||||
assertThat(mFeatureFlagsRelease.isEnabled(flag)).isFalse()
|
||||
}
|
||||
|
||||
@@ -87,8 +87,6 @@ class FakeFeatureFlags : FeatureFlags {
|
||||
|
||||
override fun isEnabled(flag: ResourceBooleanFlag): Boolean = requireBooleanValue(flag.id)
|
||||
|
||||
override fun isEnabled(flag: DeviceConfigBooleanFlag): Boolean = requireBooleanValue(flag.id)
|
||||
|
||||
override fun isEnabled(flag: SysPropBooleanFlag): Boolean = requireBooleanValue(flag.id)
|
||||
|
||||
override fun getString(flag: StringFlag): String = requireStringValue(flag.id)
|
||||
|
||||
Reference in New Issue
Block a user