Loading packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt +12 −31 Original line number Diff line number Diff line Loading @@ -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 } Loading Loading @@ -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() Loading Loading @@ -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. * Loading Loading @@ -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() ?: "" ) Loading Loading @@ -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() ) Loading Loading @@ -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() ) Loading Loading @@ -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() ) Loading Loading @@ -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() ) Loading packages/SystemUI/shared/src/com/android/systemui/flags/FlagListenable.kt +1 −1 Original line number Diff line number Diff line Loading @@ -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() } Loading packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt +30 −23 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -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() Loading Loading @@ -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) } Loading @@ -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()) { Loading @@ -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 } Loading @@ -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( Loading packages/SystemUI/shared/src/com/android/systemui/flags/FlagSettingsHelper.kt +4 −1 Original line number Diff line number Diff line Loading @@ -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, Loading packages/SystemUI/src-debug/com/android/systemui/flags/FlagsFactory.kt +5 −10 Original line number Diff line number Diff line Loading @@ -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 } Loading @@ -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 } Loading @@ -65,7 +65,7 @@ object FlagsFactory { resourceId = resourceId, teamfood = teamfood ) FlagsFactory.checkForDupesAndAdd(flag) checkForDupesAndAdd(flag) return flag } Loading @@ -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 Loading
packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt +12 −31 Original line number Diff line number Diff line Loading @@ -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 } Loading Loading @@ -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() Loading Loading @@ -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. * Loading Loading @@ -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() ?: "" ) Loading Loading @@ -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() ) Loading Loading @@ -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() ) Loading Loading @@ -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() ) Loading Loading @@ -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() ) Loading
packages/SystemUI/shared/src/com/android/systemui/flags/FlagListenable.kt +1 −1 Original line number Diff line number Diff line Loading @@ -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() } Loading
packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt +30 −23 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -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() Loading Loading @@ -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) } Loading @@ -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()) { Loading @@ -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 } Loading @@ -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( Loading
packages/SystemUI/shared/src/com/android/systemui/flags/FlagSettingsHelper.kt +4 −1 Original line number Diff line number Diff line Loading @@ -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, Loading
packages/SystemUI/src-debug/com/android/systemui/flags/FlagsFactory.kt +5 −10 Original line number Diff line number Diff line Loading @@ -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 } Loading @@ -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 } Loading @@ -65,7 +65,7 @@ object FlagsFactory { resourceId = resourceId, teamfood = teamfood ) FlagsFactory.checkForDupesAndAdd(flag) checkForDupesAndAdd(flag) return flag } Loading @@ -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