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

Commit bae2e74f authored by Dave Mankoff's avatar Dave Mankoff Committed by Automerger Merge Worker
Browse files

Add server flag support to flags. am: 96c315ea

parents 1b35ab5a 96c315ea
Loading
Loading
Loading
Loading
+40 −8
Original line number Diff line number Diff line
@@ -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> {

+0 −3
Original line number Diff line number Diff line
@@ -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

+27 −40
Original line number Diff line number Diff line
@@ -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,7 +213,7 @@ 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));
        }

@@ -236,19 +221,23 @@ public class FeatureFlagsDebug implements FeatureFlags {
    }

    /** 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);
    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()) {
        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);
            }
        }
    };
+1 −13
Original line number Diff line number Diff line
@@ -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());
+3 −4
Original line number Diff line number Diff line
@@ -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
        )

Loading