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

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

Merge "Step 1 of Removing Ids from Flags." into tm-qpr-dev

parents 796e1c4c cd1af6a4
Loading
Loading
Loading
Loading
+12 −31
Original line number Diff line number Diff line
@@ -47,10 +47,6 @@ interface ResourceFlag<T> : Flag<T> {
    val resourceId: Int
}

interface DeviceConfigFlag<T> : Flag<T> {
    val default: T
}

interface SysPropFlag<T> : Flag<T> {
    val default: T
}
@@ -80,8 +76,8 @@ abstract class BooleanFlag constructor(

    private constructor(parcel: Parcel) : this(
        id = parcel.readInt(),
        name = parcel.readString(),
        namespace = parcel.readString(),
        name = parcel.readString() ?: "",
        namespace = parcel.readString() ?: "",
        default = parcel.readBoolean(),
        teamfood = parcel.readBoolean(),
        overridden = parcel.readBoolean()
@@ -136,21 +132,6 @@ data class ResourceBooleanFlag constructor(
    override val teamfood: Boolean = false
) : ResourceFlag<Boolean>

/**
 * A Flag that can reads its overrides from DeviceConfig.
 *
 * This is generally useful for flags that come from or are used _outside_ of SystemUI.
 *
 * Prefer [UnreleasedFlag] and [ReleasedFlag].
 */
data class DeviceConfigBooleanFlag constructor(
    override val id: Int,
    override val name: String,
    override val namespace: String,
    override val default: Boolean = false,
    override val teamfood: Boolean = false
) : DeviceConfigFlag<Boolean>

/**
 * A Flag that can reads its overrides from System Properties.
 *
@@ -186,8 +167,8 @@ data class StringFlag constructor(

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

@@ -226,8 +207,8 @@ data class IntFlag constructor(

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

@@ -266,8 +247,8 @@ data class LongFlag constructor(

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

@@ -298,8 +279,8 @@ data class FloatFlag constructor(

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

@@ -338,8 +319,8 @@ data class DoubleFlag constructor(

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

+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ interface FlagListenable {
    /** An event representing the change */
    interface FlagEvent {
        /** the id of the flag which changed */
        val flagId: Int
        val flagName: String
        /** if all listeners alerted invoke this method, the restart will be skipped */
        fun requestNoRestart()
    }
+30 −23
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ class FlagManager constructor(
        const val ACTION_GET_FLAGS = "com.android.systemui.action.GET_FLAGS"
        const val FLAGS_PERMISSION = "com.android.systemui.permission.FLAGS"
        const val ACTION_SYSUI_STARTED = "com.android.systemui.STARTED"
        const val EXTRA_ID = "id"
        const val EXTRA_NAME = "name"
        const val EXTRA_VALUE = "value"
        const val EXTRA_FLAGS = "flags"
        private const val SETTINGS_PREFIX = "systemui/flags"
@@ -56,7 +56,7 @@ class FlagManager constructor(
     * that the restart be suppressed
     */
    var onSettingsChangedAction: Consumer<Boolean>? = null
    var clearCacheAction: Consumer<Int>? = null
    var clearCacheAction: Consumer<String>? = null
    private val listeners: MutableSet<PerFlagListener> = mutableSetOf()
    private val settingsObserver: ContentObserver = SettingsObserver()

@@ -96,35 +96,42 @@ class FlagManager constructor(
     * Returns the stored value or null if not set.
     * This API is used by TheFlippinApp.
     */
    fun isEnabled(id: Int): Boolean? = readFlagValue(id, BooleanFlagSerializer)
    fun isEnabled(name: String): Boolean? = readFlagValue(name, BooleanFlagSerializer)

    /**
     * Sets the value of a boolean flag.
     * This API is used by TheFlippinApp.
     */
    fun setFlagValue(id: Int, enabled: Boolean) {
        val intent = createIntent(id)
    fun setFlagValue(name: String, enabled: Boolean) {
        val intent = createIntent(name)
        intent.putExtra(EXTRA_VALUE, enabled)

        context.sendBroadcast(intent)
    }

    fun eraseFlag(id: Int) {
        val intent = createIntent(id)
    fun eraseFlag(name: String) {
        val intent = createIntent(name)

        context.sendBroadcast(intent)
    }

    /** Returns the stored value or null if not set.  */
    // TODO(b/265188950): Remove method this once ids are fully deprecated.
    fun <T> readFlagValue(id: Int, serializer: FlagSerializer<T>): T? {
        val data = settings.getString(idToSettingsKey(id))
        val data = settings.getStringFromSecure(idToSettingsKey(id))
        return serializer.fromSettingsData(data)
    }

    /** Returns the stored value or null if not set.  */
    fun <T> readFlagValue(name: String, serializer: FlagSerializer<T>): T? {
        val data = settings.getString(nameToSettingsKey(name))
        return serializer.fromSettingsData(data)
    }

    override fun addListener(flag: Flag<*>, listener: FlagListenable.Listener) {
        synchronized(listeners) {
            val registerNeeded = listeners.isEmpty()
            listeners.add(PerFlagListener(flag.id, listener))
            listeners.add(PerFlagListener(flag.name, listener))
            if (registerNeeded) {
                settings.registerContentObserver(SETTINGS_PREFIX, true, settingsObserver)
            }
@@ -143,38 +150,38 @@ class FlagManager constructor(
        }
    }

    private fun createIntent(id: Int): Intent {
    private fun createIntent(name: String): Intent {
        val intent = Intent(ACTION_SET_FLAG)
        intent.setPackage(RECEIVING_PACKAGE)
        intent.putExtra(EXTRA_ID, id)
        intent.putExtra(EXTRA_NAME, name)

        return intent
    }

    // TODO(b/265188950): Remove method this once ids are fully deprecated.
    fun idToSettingsKey(id: Int): String {
        return "$SETTINGS_PREFIX/$id"
    }

    fun nameToSettingsKey(name: String): String {
        return "$SETTINGS_PREFIX/$name"
    }

    inner class SettingsObserver : ContentObserver(handler) {
        override fun onChange(selfChange: Boolean, uri: Uri?) {
            if (uri == null) {
                return
            }
            val parts = uri.pathSegments
            val idStr = parts[parts.size - 1]
            val id = try {
                idStr.toInt()
            } catch (e: NumberFormatException) {
                return
            }
            clearCacheAction?.accept(id)
            dispatchListenersAndMaybeRestart(id, onSettingsChangedAction)
            val name = parts[parts.size - 1]
            clearCacheAction?.accept(name)
            dispatchListenersAndMaybeRestart(name, onSettingsChangedAction)
        }
    }

    fun dispatchListenersAndMaybeRestart(id: Int, restartAction: Consumer<Boolean>?) {
    fun dispatchListenersAndMaybeRestart(name: String, restartAction: Consumer<Boolean>?) {
        val filteredListeners: List<FlagListenable.Listener> = synchronized(listeners) {
            listeners.mapNotNull { if (it.id == id) it.listener else null }
            listeners.mapNotNull { if (it.name == name) it.listener else null }
        }
        // If there are no listeners, there's nothing to dispatch to, and nothing to suppress it.
        if (filteredListeners.isEmpty()) {
@@ -185,7 +192,7 @@ class FlagManager constructor(
        val suppressRestartList: List<Boolean> = filteredListeners.map { listener ->
            var didRequestNoRestart = false
            val event = object : FlagListenable.FlagEvent {
                override val flagId = id
                override val flagName = name
                override fun requestNoRestart() {
                    didRequestNoRestart = true
                }
@@ -198,7 +205,7 @@ class FlagManager constructor(
        restartAction?.accept(suppressRestart)
    }

    private data class PerFlagListener(val id: Int, val listener: FlagListenable.Listener)
    private data class PerFlagListener(val name: String, val listener: FlagListenable.Listener)
}

class NoFlagResultsException : Exception(
+4 −1
Original line number Diff line number Diff line
@@ -22,7 +22,10 @@ import android.provider.Settings

class FlagSettingsHelper(private val contentResolver: ContentResolver) {

    fun getString(key: String): String? = Settings.Secure.getString(contentResolver, key)
    // TODO(b/265188950): Remove method this once ids are fully deprecated.
    fun getStringFromSecure(key: String): String? = Settings.Secure.getString(contentResolver, key)

    fun getString(key: String): String? = Settings.Global.getString(contentResolver, key)

    fun registerContentObserver(
        name: String,
+5 −10
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ object FlagsFactory {
        teamfood: Boolean = false
    ): UnreleasedFlag {
        val flag = UnreleasedFlag(id = id, name = name, namespace = namespace, teamfood = teamfood)
        FlagsFactory.checkForDupesAndAdd(flag)
        checkForDupesAndAdd(flag)
        return flag
    }

@@ -46,7 +46,7 @@ object FlagsFactory {
        teamfood: Boolean = false
    ): ReleasedFlag {
        val flag = ReleasedFlag(id = id, name = name, namespace = namespace, teamfood = teamfood)
        FlagsFactory.checkForDupesAndAdd(flag)
        checkForDupesAndAdd(flag)
        return flag
    }

@@ -65,7 +65,7 @@ object FlagsFactory {
                resourceId = resourceId,
                teamfood = teamfood
            )
        FlagsFactory.checkForDupesAndAdd(flag)
        checkForDupesAndAdd(flag)
        return flag
    }

@@ -77,18 +77,13 @@ object FlagsFactory {
    ): SysPropBooleanFlag {
        val flag =
            SysPropBooleanFlag(id = id, name = name, namespace = "systemui", default = default)
        FlagsFactory.checkForDupesAndAdd(flag)
        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")
            }
            throw IllegalArgumentException("Name {$flag.name} is already registered")
        }
        flagMap[flag.name] = flag
    }
Loading