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

Commit 2dcc550c authored by Dave Mankoff's avatar Dave Mankoff Committed by Android (Google) Code Review
Browse files

Merge changes I29bf2065,Ic858826c,I7fe0bd12 into tm-qpr-dev

* changes:
  Define server flag names for all existing flags.
  RESTRICT AUTOMERGE Resynchronize QPR flags with Main
  Add server flag support to flags.
parents 2bb38bf2 57d1b2af
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -116,7 +116,6 @@ android_library {
        "androidx.exifinterface_exifinterface",
        "androidx.test.ext.junit",
        "com.google.android.material_material",
        "kotlin-reflect",
        "kotlinx_coroutines_android",
        "kotlinx_coroutines",
        "iconloader_base",
+64 −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
}

@@ -56,6 +63,8 @@ interface SysPropFlag<T> : Flag<T> {
// Consider using the "parcelize" kotlin library.
abstract class BooleanFlag constructor(
    override val id: Int,
    override val name: String,
    override val namespace: String,
    override val default: Boolean = false,
    override val teamfood: Boolean = false,
    override val overridden: Boolean = false
@@ -71,6 +80,8 @@ abstract class BooleanFlag constructor(

    private constructor(parcel: Parcel) : this(
        id = parcel.readInt(),
        name = parcel.readString(),
        namespace = parcel.readString(),
        default = parcel.readBoolean(),
        teamfood = parcel.readBoolean(),
        overridden = parcel.readBoolean()
@@ -78,6 +89,8 @@ abstract class BooleanFlag constructor(

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeInt(id)
        parcel.writeString(name)
        parcel.writeString(namespace)
        parcel.writeBoolean(default)
        parcel.writeBoolean(teamfood)
        parcel.writeBoolean(overridden)
@@ -91,20 +104,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, name, namespace, false, 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, name, namespace, true, teamfood, overridden)

/**
 * A Flag that reads its default values from a resource overlay instead of code.
@@ -113,6 +130,8 @@ data class ReleasedFlag constructor(
 */
data class ResourceBooleanFlag constructor(
    override val id: Int,
    override val name: String,
    override val namespace: String,
    @BoolRes override val resourceId: Int,
    override val teamfood: Boolean = false
) : ResourceFlag<Boolean>
@@ -142,7 +161,8 @@ data class DeviceConfigBooleanFlag constructor(
data class SysPropBooleanFlag constructor(
    override val id: Int,
    override val name: String,
    override val default: Boolean = false
    override val namespace: String,
    override val default: Boolean = false,
) : SysPropFlag<Boolean> {
    // TODO(b/223379190): Teamfood not supported for sysprop flags yet.
    override val teamfood: Boolean = false
@@ -150,6 +170,8 @@ data class SysPropBooleanFlag constructor(

data class StringFlag constructor(
    override val id: Int,
    override val name: String,
    override val namespace: String,
    override val default: String = "",
    override val teamfood: Boolean = false,
    override val overridden: Boolean = false
@@ -164,23 +186,31 @@ data class StringFlag constructor(

    private constructor(parcel: Parcel) : this(
        id = parcel.readInt(),
        name = parcel.readString(),
        namespace = parcel.readString(),
        default = parcel.readString() ?: ""
    )

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeInt(id)
        parcel.writeString(name)
        parcel.writeString(namespace)
        parcel.writeString(default)
    }
}

data class ResourceStringFlag constructor(
    override val id: Int,
    override val name: String,
    override val namespace: String,
    @StringRes override val resourceId: Int,
    override val teamfood: Boolean = false
) : ResourceFlag<String>

data class IntFlag constructor(
    override val id: Int,
    override val name: String,
    override val namespace: String,
    override val default: Int = 0,
    override val teamfood: Boolean = false,
    override val overridden: Boolean = false
@@ -196,17 +226,23 @@ data class IntFlag constructor(

    private constructor(parcel: Parcel) : this(
        id = parcel.readInt(),
        name = parcel.readString(),
        namespace = parcel.readString(),
        default = parcel.readInt()
    )

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeInt(id)
        parcel.writeString(name)
        parcel.writeString(namespace)
        parcel.writeInt(default)
    }
}

data class ResourceIntFlag constructor(
    override val id: Int,
    override val name: String,
    override val namespace: String,
    @IntegerRes override val resourceId: Int,
    override val teamfood: Boolean = false
) : ResourceFlag<Int>
@@ -215,6 +251,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> {

@@ -228,17 +266,23 @@ data class LongFlag constructor(

    private constructor(parcel: Parcel) : this(
        id = parcel.readInt(),
        name = parcel.readString(),
        namespace = parcel.readString(),
        default = parcel.readLong()
    )

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeInt(id)
        parcel.writeString(name)
        parcel.writeString(namespace)
        parcel.writeLong(default)
    }
}

data class FloatFlag constructor(
    override val id: Int,
    override val name: String,
    override val namespace: String,
    override val default: Float = 0f,
    override val teamfood: Boolean = false,
    override val overridden: Boolean = false
@@ -254,23 +298,31 @@ data class FloatFlag constructor(

    private constructor(parcel: Parcel) : this(
        id = parcel.readInt(),
        name = parcel.readString(),
        namespace = parcel.readString(),
        default = parcel.readFloat()
    )

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeInt(id)
        parcel.writeString(name)
        parcel.writeString(namespace)
        parcel.writeFloat(default)
    }
}

data class ResourceFloatFlag constructor(
    override val id: Int,
    override val name: String,
    override val namespace: String,
    override val resourceId: Int,
    override val teamfood: Boolean = false
    override val teamfood: Boolean = false,
) : ResourceFlag<Int>

data class DoubleFlag constructor(
    override val id: Int,
    override val name: String,
    override val namespace: String,
    override val default: Double = 0.0,
    override val teamfood: Boolean = false,
    override val overridden: Boolean = false
@@ -286,11 +338,15 @@ data class DoubleFlag constructor(

    private constructor(parcel: Parcel) : this(
        id = parcel.readInt(),
        name = parcel.readString(),
        namespace = parcel.readString(),
        default = parcel.readDouble()
    )

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

package com.android.systemui.flags

import android.annotation.BoolRes

object FlagsFactory {
    private val flagMap = mutableMapOf<String, Flag<*>>()

    val knownFlags: Map<String, Flag<*>>
        get() = flagMap

    fun unreleasedFlag(
        id: Int,
        name: String,
        namespace: String = "systemui",
        teamfood: Boolean = false
    ): UnreleasedFlag {
        val flag = UnreleasedFlag(id = id, name = name, namespace = namespace, teamfood = teamfood)
        FlagsFactory.checkForDupesAndAdd(flag)
        return flag
    }

    fun releasedFlag(
        id: Int,
        name: String,
        namespace: String = "systemui",
        teamfood: Boolean = false
    ): ReleasedFlag {
        val flag = ReleasedFlag(id = id, name = name, namespace = namespace, teamfood = teamfood)
        FlagsFactory.checkForDupesAndAdd(flag)
        return flag
    }

    fun resourceBooleanFlag(
        id: Int,
        @BoolRes resourceId: Int,
        name: String,
        namespace: String = "systemui",
        teamfood: Boolean = false
    ): ResourceBooleanFlag {
        val flag =
            ResourceBooleanFlag(
                id = id,
                name = name,
                namespace = namespace,
                resourceId = resourceId,
                teamfood = teamfood
            )
        FlagsFactory.checkForDupesAndAdd(flag)
        return flag
    }

    fun sysPropBooleanFlag(
        id: Int,
        name: String,
        namespace: String = "systemui",
        default: Boolean = false
    ): SysPropBooleanFlag {
        val flag =
            SysPropBooleanFlag(id = id, name = name, namespace = "systemui", default = default)
        FlagsFactory.checkForDupesAndAdd(flag)
        return flag
    }

    private fun checkForDupesAndAdd(flag: Flag<*>) {
        if (flagMap.containsKey(flag.name)) {
            throw IllegalArgumentException("Name {flag.name} is already registered")
        }
        flagMap.forEach {
            if (it.value.id == flag.id) {
                throw IllegalArgumentException("Name {flag.id} is already registered")
            }
        }
        flagMap[flag.name] = flag
    }
}
+79 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.flags

import android.annotation.BoolRes

object FlagsFactory {
    private val flagMap = mutableMapOf<String, Flag<*>>()

    val knownFlags: Map<String, Flag<*>>
        get() = flagMap

    fun unreleasedFlag(
        id: Int,
        name: String,
        namespace: String = "systemui",
        teamfood: Boolean = false
    ): UnreleasedFlag {
        // Unreleased flags are always false in this build.
        val flag = UnreleasedFlag(id = id, name = "", namespace = "", teamfood = false)
        return flag
    }

    fun releasedFlag(
        id: Int,
        name: String,
        namespace: String = "systemui",
        teamfood: Boolean = false
    ): ReleasedFlag {
        val flag = ReleasedFlag(id = id, name = name, namespace = namespace, teamfood = teamfood)
        flagMap[name] = flag
        return flag
    }

    fun resourceBooleanFlag(
        id: Int,
        @BoolRes resourceId: Int,
        name: String,
        namespace: String = "systemui",
        teamfood: Boolean = false
    ): ResourceBooleanFlag {
        val flag =
            ResourceBooleanFlag(
                id = id,
                name = name,
                namespace = namespace,
                resourceId = resourceId,
                teamfood = teamfood
            )
        flagMap[name] = flag
        return flag
    }

    fun sysPropBooleanFlag(
        id: Int,
        name: String,
        namespace: String = "systemui",
        default: Boolean = false
    ): SysPropBooleanFlag {
        val flag =
            SysPropBooleanFlag(id = id, name = name, namespace = namespace, default = default)
        flagMap[name] = flag
        return flag
    }
}
+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

Loading