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.
This commit is contained in:
@@ -116,7 +116,6 @@ android_library {
|
|||||||
"androidx.exifinterface_exifinterface",
|
"androidx.exifinterface_exifinterface",
|
||||||
"androidx.test.ext.junit",
|
"androidx.test.ext.junit",
|
||||||
"com.google.android.material_material",
|
"com.google.android.material_material",
|
||||||
"kotlin-reflect",
|
|
||||||
"kotlinx_coroutines_android",
|
"kotlinx_coroutines_android",
|
||||||
"kotlinx_coroutines",
|
"kotlinx_coroutines",
|
||||||
"iconloader_base",
|
"iconloader_base",
|
||||||
|
|||||||
@@ -22,9 +22,19 @@ import android.annotation.StringRes
|
|||||||
import android.os.Parcel
|
import android.os.Parcel
|
||||||
import android.os.Parcelable
|
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> {
|
interface Flag<T> {
|
||||||
val id: Int
|
val id: Int
|
||||||
val teamfood: Boolean
|
val teamfood: Boolean
|
||||||
|
val name: String
|
||||||
|
val namespace: String
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ParcelableFlag<T> : Flag<T>, Parcelable {
|
interface ParcelableFlag<T> : Flag<T>, Parcelable {
|
||||||
@@ -38,13 +48,10 @@ interface ResourceFlag<T> : Flag<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface DeviceConfigFlag<T> : Flag<T> {
|
interface DeviceConfigFlag<T> : Flag<T> {
|
||||||
val name: String
|
|
||||||
val namespace: String
|
|
||||||
val default: T
|
val default: T
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SysPropFlag<T> : Flag<T> {
|
interface SysPropFlag<T> : Flag<T> {
|
||||||
val name: String
|
|
||||||
val default: T
|
val default: T
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,6 +63,8 @@ interface SysPropFlag<T> : Flag<T> {
|
|||||||
// Consider using the "parcelize" kotlin library.
|
// Consider using the "parcelize" kotlin library.
|
||||||
abstract class BooleanFlag constructor(
|
abstract class BooleanFlag constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
|
override val name: String,
|
||||||
|
override val namespace: String,
|
||||||
override val default: Boolean = false,
|
override val default: Boolean = false,
|
||||||
override val teamfood: Boolean = false,
|
override val teamfood: Boolean = false,
|
||||||
override val overridden: Boolean = false
|
override val overridden: Boolean = false
|
||||||
@@ -71,6 +80,8 @@ abstract class BooleanFlag constructor(
|
|||||||
|
|
||||||
private constructor(parcel: Parcel) : this(
|
private constructor(parcel: Parcel) : this(
|
||||||
id = parcel.readInt(),
|
id = parcel.readInt(),
|
||||||
|
name = parcel.readString(),
|
||||||
|
namespace = parcel.readString(),
|
||||||
default = parcel.readBoolean(),
|
default = parcel.readBoolean(),
|
||||||
teamfood = parcel.readBoolean(),
|
teamfood = parcel.readBoolean(),
|
||||||
overridden = parcel.readBoolean()
|
overridden = parcel.readBoolean()
|
||||||
@@ -78,6 +89,8 @@ abstract class BooleanFlag constructor(
|
|||||||
|
|
||||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||||
parcel.writeInt(id)
|
parcel.writeInt(id)
|
||||||
|
parcel.writeString(name)
|
||||||
|
parcel.writeString(namespace)
|
||||||
parcel.writeBoolean(default)
|
parcel.writeBoolean(default)
|
||||||
parcel.writeBoolean(teamfood)
|
parcel.writeBoolean(teamfood)
|
||||||
parcel.writeBoolean(overridden)
|
parcel.writeBoolean(overridden)
|
||||||
@@ -91,20 +104,24 @@ abstract class BooleanFlag constructor(
|
|||||||
*/
|
*/
|
||||||
data class UnreleasedFlag constructor(
|
data class UnreleasedFlag constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
|
override val name: String,
|
||||||
|
override val namespace: String,
|
||||||
override val teamfood: Boolean = false,
|
override val teamfood: Boolean = false,
|
||||||
override val overridden: 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.
|
* It can be changed or overridden in any build, meaning it can be turned off if needed.
|
||||||
*/
|
*/
|
||||||
data class ReleasedFlag constructor(
|
data class ReleasedFlag constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
|
override val name: String,
|
||||||
|
override val namespace: String,
|
||||||
override val teamfood: Boolean = false,
|
override val teamfood: Boolean = false,
|
||||||
override val overridden: 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.
|
* 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(
|
data class ResourceBooleanFlag constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
|
override val name: String,
|
||||||
|
override val namespace: String,
|
||||||
@BoolRes override val resourceId: Int,
|
@BoolRes override val resourceId: Int,
|
||||||
override val teamfood: Boolean = false
|
override val teamfood: Boolean = false
|
||||||
) : ResourceFlag<Boolean>
|
) : ResourceFlag<Boolean>
|
||||||
@@ -142,7 +161,8 @@ data class DeviceConfigBooleanFlag constructor(
|
|||||||
data class SysPropBooleanFlag constructor(
|
data class SysPropBooleanFlag constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
override val name: String,
|
override val name: String,
|
||||||
override val default: Boolean = false
|
override val namespace: String,
|
||||||
|
override val default: Boolean = false,
|
||||||
) : SysPropFlag<Boolean> {
|
) : SysPropFlag<Boolean> {
|
||||||
// TODO(b/223379190): Teamfood not supported for sysprop flags yet.
|
// TODO(b/223379190): Teamfood not supported for sysprop flags yet.
|
||||||
override val teamfood: Boolean = false
|
override val teamfood: Boolean = false
|
||||||
@@ -150,6 +170,8 @@ data class SysPropBooleanFlag constructor(
|
|||||||
|
|
||||||
data class StringFlag constructor(
|
data class StringFlag constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
|
override val name: String,
|
||||||
|
override val namespace: String,
|
||||||
override val default: String = "",
|
override val default: String = "",
|
||||||
override val teamfood: Boolean = false,
|
override val teamfood: Boolean = false,
|
||||||
override val overridden: Boolean = false
|
override val overridden: Boolean = false
|
||||||
@@ -164,23 +186,31 @@ data class StringFlag constructor(
|
|||||||
|
|
||||||
private constructor(parcel: Parcel) : this(
|
private constructor(parcel: Parcel) : this(
|
||||||
id = parcel.readInt(),
|
id = parcel.readInt(),
|
||||||
|
name = parcel.readString(),
|
||||||
|
namespace = parcel.readString(),
|
||||||
default = parcel.readString() ?: ""
|
default = parcel.readString() ?: ""
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||||
parcel.writeInt(id)
|
parcel.writeInt(id)
|
||||||
|
parcel.writeString(name)
|
||||||
|
parcel.writeString(namespace)
|
||||||
parcel.writeString(default)
|
parcel.writeString(default)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ResourceStringFlag constructor(
|
data class ResourceStringFlag constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
|
override val name: String,
|
||||||
|
override val namespace: String,
|
||||||
@StringRes override val resourceId: Int,
|
@StringRes override val resourceId: Int,
|
||||||
override val teamfood: Boolean = false
|
override val teamfood: Boolean = false
|
||||||
) : ResourceFlag<String>
|
) : ResourceFlag<String>
|
||||||
|
|
||||||
data class IntFlag constructor(
|
data class IntFlag constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
|
override val name: String,
|
||||||
|
override val namespace: String,
|
||||||
override val default: Int = 0,
|
override val default: Int = 0,
|
||||||
override val teamfood: Boolean = false,
|
override val teamfood: Boolean = false,
|
||||||
override val overridden: Boolean = false
|
override val overridden: Boolean = false
|
||||||
@@ -196,17 +226,23 @@ data class IntFlag constructor(
|
|||||||
|
|
||||||
private constructor(parcel: Parcel) : this(
|
private constructor(parcel: Parcel) : this(
|
||||||
id = parcel.readInt(),
|
id = parcel.readInt(),
|
||||||
|
name = parcel.readString(),
|
||||||
|
namespace = parcel.readString(),
|
||||||
default = parcel.readInt()
|
default = parcel.readInt()
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||||
parcel.writeInt(id)
|
parcel.writeInt(id)
|
||||||
|
parcel.writeString(name)
|
||||||
|
parcel.writeString(namespace)
|
||||||
parcel.writeInt(default)
|
parcel.writeInt(default)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ResourceIntFlag constructor(
|
data class ResourceIntFlag constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
|
override val name: String,
|
||||||
|
override val namespace: String,
|
||||||
@IntegerRes override val resourceId: Int,
|
@IntegerRes override val resourceId: Int,
|
||||||
override val teamfood: Boolean = false
|
override val teamfood: Boolean = false
|
||||||
) : ResourceFlag<Int>
|
) : ResourceFlag<Int>
|
||||||
@@ -215,6 +251,8 @@ data class LongFlag constructor(
|
|||||||
override val id: Int,
|
override val id: Int,
|
||||||
override val default: Long = 0,
|
override val default: Long = 0,
|
||||||
override val teamfood: Boolean = false,
|
override val teamfood: Boolean = false,
|
||||||
|
override val name: String,
|
||||||
|
override val namespace: String,
|
||||||
override val overridden: Boolean = false
|
override val overridden: Boolean = false
|
||||||
) : ParcelableFlag<Long> {
|
) : ParcelableFlag<Long> {
|
||||||
|
|
||||||
@@ -228,17 +266,23 @@ data class LongFlag constructor(
|
|||||||
|
|
||||||
private constructor(parcel: Parcel) : this(
|
private constructor(parcel: Parcel) : this(
|
||||||
id = parcel.readInt(),
|
id = parcel.readInt(),
|
||||||
|
name = parcel.readString(),
|
||||||
|
namespace = parcel.readString(),
|
||||||
default = parcel.readLong()
|
default = parcel.readLong()
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||||
parcel.writeInt(id)
|
parcel.writeInt(id)
|
||||||
|
parcel.writeString(name)
|
||||||
|
parcel.writeString(namespace)
|
||||||
parcel.writeLong(default)
|
parcel.writeLong(default)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class FloatFlag constructor(
|
data class FloatFlag constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
|
override val name: String,
|
||||||
|
override val namespace: String,
|
||||||
override val default: Float = 0f,
|
override val default: Float = 0f,
|
||||||
override val teamfood: Boolean = false,
|
override val teamfood: Boolean = false,
|
||||||
override val overridden: Boolean = false
|
override val overridden: Boolean = false
|
||||||
@@ -254,23 +298,31 @@ data class FloatFlag constructor(
|
|||||||
|
|
||||||
private constructor(parcel: Parcel) : this(
|
private constructor(parcel: Parcel) : this(
|
||||||
id = parcel.readInt(),
|
id = parcel.readInt(),
|
||||||
|
name = parcel.readString(),
|
||||||
|
namespace = parcel.readString(),
|
||||||
default = parcel.readFloat()
|
default = parcel.readFloat()
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||||
parcel.writeInt(id)
|
parcel.writeInt(id)
|
||||||
|
parcel.writeString(name)
|
||||||
|
parcel.writeString(namespace)
|
||||||
parcel.writeFloat(default)
|
parcel.writeFloat(default)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ResourceFloatFlag constructor(
|
data class ResourceFloatFlag constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
|
override val name: String,
|
||||||
|
override val namespace: String,
|
||||||
override val resourceId: Int,
|
override val resourceId: Int,
|
||||||
override val teamfood: Boolean = false
|
override val teamfood: Boolean = false,
|
||||||
) : ResourceFlag<Int>
|
) : ResourceFlag<Int>
|
||||||
|
|
||||||
data class DoubleFlag constructor(
|
data class DoubleFlag constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
|
override val name: String,
|
||||||
|
override val namespace: String,
|
||||||
override val default: Double = 0.0,
|
override val default: Double = 0.0,
|
||||||
override val teamfood: Boolean = false,
|
override val teamfood: Boolean = false,
|
||||||
override val overridden: Boolean = false
|
override val overridden: Boolean = false
|
||||||
@@ -286,11 +338,15 @@ data class DoubleFlag constructor(
|
|||||||
|
|
||||||
private constructor(parcel: Parcel) : this(
|
private constructor(parcel: Parcel) : this(
|
||||||
id = parcel.readInt(),
|
id = parcel.readInt(),
|
||||||
|
name = parcel.readString(),
|
||||||
|
namespace = parcel.readString(),
|
||||||
default = parcel.readDouble()
|
default = parcel.readDouble()
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||||
parcel.writeInt(id)
|
parcel.writeInt(id)
|
||||||
|
parcel.writeString(name)
|
||||||
|
parcel.writeString(namespace)
|
||||||
parcel.writeDouble(default)
|
parcel.writeDouble(default)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,9 +33,6 @@ interface FeatureFlags : FlagListenable, Dumpable {
|
|||||||
/** Returns a boolean value for the given flag. */
|
/** Returns a boolean value for the given flag. */
|
||||||
fun isEnabled(flag: ResourceBooleanFlag): Boolean
|
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. */
|
/** Returns a boolean value for the given flag. */
|
||||||
fun isEnabled(flag: SysPropBooleanFlag): Boolean
|
fun isEnabled(flag: SysPropBooleanFlag): Boolean
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ import androidx.annotation.Nullable;
|
|||||||
|
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
import com.android.systemui.dagger.SysUISingleton;
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
import com.android.systemui.util.DeviceConfigProxy;
|
|
||||||
import com.android.systemui.util.settings.SecureSettings;
|
import com.android.systemui.util.settings.SecureSettings;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -76,7 +75,6 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
|||||||
private final SecureSettings mSecureSettings;
|
private final SecureSettings mSecureSettings;
|
||||||
private final Resources mResources;
|
private final Resources mResources;
|
||||||
private final SystemPropertiesHelper mSystemProperties;
|
private final SystemPropertiesHelper mSystemProperties;
|
||||||
private final DeviceConfigProxy mDeviceConfigProxy;
|
|
||||||
private final ServerFlagReader mServerFlagReader;
|
private final ServerFlagReader mServerFlagReader;
|
||||||
private final Map<Integer, Flag<?>> mAllFlags;
|
private final Map<Integer, Flag<?>> mAllFlags;
|
||||||
private final Map<Integer, Boolean> mBooleanFlagCache = new TreeMap<>();
|
private final Map<Integer, Boolean> mBooleanFlagCache = new TreeMap<>();
|
||||||
@@ -99,7 +97,6 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
|||||||
SecureSettings secureSettings,
|
SecureSettings secureSettings,
|
||||||
SystemPropertiesHelper systemProperties,
|
SystemPropertiesHelper systemProperties,
|
||||||
@Main Resources resources,
|
@Main Resources resources,
|
||||||
DeviceConfigProxy deviceConfigProxy,
|
|
||||||
ServerFlagReader serverFlagReader,
|
ServerFlagReader serverFlagReader,
|
||||||
@Named(ALL_FLAGS) Map<Integer, Flag<?>> allFlags,
|
@Named(ALL_FLAGS) Map<Integer, Flag<?>> allFlags,
|
||||||
Restarter restarter) {
|
Restarter restarter) {
|
||||||
@@ -108,7 +105,6 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
|||||||
mSecureSettings = secureSettings;
|
mSecureSettings = secureSettings;
|
||||||
mResources = resources;
|
mResources = resources;
|
||||||
mSystemProperties = systemProperties;
|
mSystemProperties = systemProperties;
|
||||||
mDeviceConfigProxy = deviceConfigProxy;
|
|
||||||
mServerFlagReader = serverFlagReader;
|
mServerFlagReader = serverFlagReader;
|
||||||
mAllFlags = allFlags;
|
mAllFlags = allFlags;
|
||||||
mRestarter = restarter;
|
mRestarter = restarter;
|
||||||
@@ -140,7 +136,7 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
|||||||
int id = flag.getId();
|
int id = flag.getId();
|
||||||
if (!mBooleanFlagCache.containsKey(id)) {
|
if (!mBooleanFlagCache.containsKey(id)) {
|
||||||
mBooleanFlagCache.put(id,
|
mBooleanFlagCache.put(id,
|
||||||
readFlagValue(id, flag.getDefault()));
|
readBooleanFlagInternal(flag, flag.getDefault()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mBooleanFlagCache.get(id);
|
return mBooleanFlagCache.get(id);
|
||||||
@@ -151,19 +147,7 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
|||||||
int id = flag.getId();
|
int id = flag.getId();
|
||||||
if (!mBooleanFlagCache.containsKey(id)) {
|
if (!mBooleanFlagCache.containsKey(id)) {
|
||||||
mBooleanFlagCache.put(id,
|
mBooleanFlagCache.put(id,
|
||||||
readFlagValue(id, mResources.getBoolean(flag.getResourceId())));
|
readBooleanFlagInternal(flag, 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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mBooleanFlagCache.get(id);
|
return mBooleanFlagCache.get(id);
|
||||||
@@ -179,7 +163,7 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
|||||||
id,
|
id,
|
||||||
mSystemProperties.getBoolean(
|
mSystemProperties.getBoolean(
|
||||||
flag.getName(),
|
flag.getName(),
|
||||||
readFlagValue(id, flag.getDefault())));
|
readBooleanFlagInternal(flag, flag.getDefault())));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mBooleanFlagCache.get(id);
|
return mBooleanFlagCache.get(id);
|
||||||
@@ -191,7 +175,7 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
|||||||
int id = flag.getId();
|
int id = flag.getId();
|
||||||
if (!mStringFlagCache.containsKey(id)) {
|
if (!mStringFlagCache.containsKey(id)) {
|
||||||
mStringFlagCache.put(id,
|
mStringFlagCache.put(id,
|
||||||
readFlagValue(id, flag.getDefault(), StringFlagSerializer.INSTANCE));
|
readFlagValueInternal(id, flag.getDefault(), StringFlagSerializer.INSTANCE));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mStringFlagCache.get(id);
|
return mStringFlagCache.get(id);
|
||||||
@@ -203,20 +187,21 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
|||||||
int id = flag.getId();
|
int id = flag.getId();
|
||||||
if (!mStringFlagCache.containsKey(id)) {
|
if (!mStringFlagCache.containsKey(id)) {
|
||||||
mStringFlagCache.put(id,
|
mStringFlagCache.put(id,
|
||||||
readFlagValue(id, mResources.getString(flag.getResourceId()),
|
readFlagValueInternal(id, mResources.getString(flag.getResourceId()),
|
||||||
StringFlagSerializer.INSTANCE));
|
StringFlagSerializer.INSTANCE));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mStringFlagCache.get(id);
|
return mStringFlagCache.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public int getInt(@NonNull IntFlag flag) {
|
public int getInt(@NonNull IntFlag flag) {
|
||||||
int id = flag.getId();
|
int id = flag.getId();
|
||||||
if (!mIntFlagCache.containsKey(id)) {
|
if (!mIntFlagCache.containsKey(id)) {
|
||||||
mIntFlagCache.put(id,
|
mIntFlagCache.put(id,
|
||||||
readFlagValue(id, flag.getDefault(), IntFlagSerializer.INSTANCE));
|
readFlagValueInternal(id, flag.getDefault(), IntFlagSerializer.INSTANCE));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mIntFlagCache.get(id);
|
return mIntFlagCache.get(id);
|
||||||
@@ -228,27 +213,31 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
|||||||
int id = flag.getId();
|
int id = flag.getId();
|
||||||
if (!mIntFlagCache.containsKey(id)) {
|
if (!mIntFlagCache.containsKey(id)) {
|
||||||
mIntFlagCache.put(id,
|
mIntFlagCache.put(id,
|
||||||
readFlagValue(id, mResources.getInteger(flag.getResourceId()),
|
readFlagValueInternal(id, mResources.getInteger(flag.getResourceId()),
|
||||||
IntFlagSerializer.INSTANCE));
|
IntFlagSerializer.INSTANCE));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mIntFlagCache.get(id);
|
return mIntFlagCache.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Specific override for Boolean flags that checks against the teamfood list. */
|
/** Specific override for Boolean flags that checks against the teamfood list.*/
|
||||||
private boolean readFlagValue(int id, boolean defaultValue) {
|
private boolean readBooleanFlagInternal(Flag<Boolean> flag, boolean defaultValue) {
|
||||||
Boolean result = readBooleanFlagOverride(id);
|
Boolean result = readBooleanFlagOverride(flag.getId());
|
||||||
boolean hasServerOverride = mServerFlagReader.hasOverride(id);
|
boolean hasServerOverride = mServerFlagReader.hasOverride(
|
||||||
|
flag.getNamespace(), flag.getName());
|
||||||
|
|
||||||
// Only check for teamfood if the default is false
|
// Only check for teamfood if the default is false
|
||||||
// and there is no server override.
|
// and there is no server override.
|
||||||
if (!hasServerOverride && !defaultValue && result == null && id != Flags.TEAMFOOD.getId()) {
|
if (!hasServerOverride
|
||||||
if (mAllFlags.containsKey(id) && mAllFlags.get(id).getTeamfood()) {
|
&& !defaultValue
|
||||||
return isEnabled(Flags.TEAMFOOD);
|
&& 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) {
|
private Boolean readBooleanFlagOverride(int id) {
|
||||||
@@ -256,7 +245,8 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@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");
|
requireNonNull(defaultValue, "defaultValue");
|
||||||
T result = readFlagValueInternal(id, serializer);
|
T result = readFlagValueInternal(id, serializer);
|
||||||
return result == null ? defaultValue : result;
|
return result == null ? defaultValue : result;
|
||||||
@@ -355,8 +345,6 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
|||||||
setFlagValue(flag.getId(), value, BooleanFlagSerializer.INSTANCE);
|
setFlagValue(flag.getId(), value, BooleanFlagSerializer.INSTANCE);
|
||||||
} else if (flag instanceof ResourceBooleanFlag) {
|
} else if (flag instanceof ResourceBooleanFlag) {
|
||||||
setFlagValue(flag.getId(), value, BooleanFlagSerializer.INSTANCE);
|
setFlagValue(flag.getId(), value, BooleanFlagSerializer.INSTANCE);
|
||||||
} else if (flag instanceof DeviceConfigBooleanFlag) {
|
|
||||||
setFlagValue(flag.getId(), value, BooleanFlagSerializer.INSTANCE);
|
|
||||||
} else if (flag instanceof SysPropBooleanFlag) {
|
} else if (flag instanceof SysPropBooleanFlag) {
|
||||||
// Store SysProp flags in SystemProperties where they can read by outside parties.
|
// Store SysProp flags in SystemProperties where they can read by outside parties.
|
||||||
mSystemProperties.setBoolean(((SysPropBooleanFlag) flag).getName(), value);
|
mSystemProperties.setBoolean(((SysPropBooleanFlag) flag).getName(), value);
|
||||||
@@ -474,9 +462,6 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
|||||||
} else if (f instanceof ResourceBooleanFlag) {
|
} else if (f instanceof ResourceBooleanFlag) {
|
||||||
enabled = isEnabled((ResourceBooleanFlag) f);
|
enabled = isEnabled((ResourceBooleanFlag) f);
|
||||||
overridden = readBooleanFlagOverride(f.getId()) != null;
|
overridden = readBooleanFlagOverride(f.getId()) != null;
|
||||||
} else if (f instanceof DeviceConfigBooleanFlag) {
|
|
||||||
enabled = isEnabled((DeviceConfigBooleanFlag) f);
|
|
||||||
overridden = false;
|
|
||||||
} else if (f instanceof SysPropBooleanFlag) {
|
} else if (f instanceof SysPropBooleanFlag) {
|
||||||
// TODO(b/223379190): Teamfood not supported for sysprop flags yet.
|
// TODO(b/223379190): Teamfood not supported for sysprop flags yet.
|
||||||
enabled = isEnabled((SysPropBooleanFlag) f);
|
enabled = isEnabled((SysPropBooleanFlag) f);
|
||||||
@@ -489,9 +474,11 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
return new ReleasedFlag(f.getId(), teamfood, overridden);
|
return new ReleasedFlag(
|
||||||
|
f.getId(), f.getName(), f.getNamespace(), teamfood, overridden);
|
||||||
} else {
|
} 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
|
@Override
|
||||||
public boolean isEnabled(@NotNull ReleasedFlag flag) {
|
public boolean isEnabled(@NotNull ReleasedFlag flag) {
|
||||||
return mServerFlagReader.readServerOverride(flag.getId(), true);
|
return mServerFlagReader.readServerOverride(flag.getNamespace(), flag.getName(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -114,18 +114,6 @@ public class FeatureFlagsRelease implements FeatureFlags {
|
|||||||
return mBooleanCache.valueAt(cacheIndex);
|
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
|
@Override
|
||||||
public boolean isEnabled(SysPropBooleanFlag flag) {
|
public boolean isEnabled(SysPropBooleanFlag flag) {
|
||||||
int cacheIndex = mBooleanCache.indexOfKey(flag.getId());
|
int cacheIndex = mBooleanCache.indexOfKey(flag.getId());
|
||||||
@@ -180,10 +168,10 @@ public class FeatureFlagsRelease implements FeatureFlags {
|
|||||||
@Override
|
@Override
|
||||||
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
|
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
|
||||||
pw.println("can override: false");
|
pw.println("can override: false");
|
||||||
Map<Integer, Flag<?>> knownFlags = Flags.collectFlags();
|
Map<String, Flag<?>> knownFlags = FlagsFactory.INSTANCE.getKnownFlags();
|
||||||
for (Map.Entry<Integer, Flag<?>> idToFlag : knownFlags.entrySet()) {
|
for (Map.Entry<String, Flag<?>> nameToFlag : knownFlags.entrySet()) {
|
||||||
int id = idToFlag.getKey();
|
Flag<?> flag = nameToFlag.getValue();
|
||||||
Flag<?> flag = idToFlag.getValue();
|
int id = flag.getId();
|
||||||
boolean def = false;
|
boolean def = false;
|
||||||
if (mBooleanCache.indexOfKey(flag.getId()) < 0) {
|
if (mBooleanCache.indexOfKey(flag.getId()) < 0) {
|
||||||
if (flag instanceof SysPropBooleanFlag) {
|
if (flag instanceof SysPropBooleanFlag) {
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ public class FlagCommand implements Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int flagNameToId(String flagName) {
|
private int flagNameToId(String flagName) {
|
||||||
Map<String, Flag<?>> flagFields = Flags.getFlagFields();
|
Map<String, Flag<?>> flagFields = FlagsFactory.INSTANCE.getKnownFlags();
|
||||||
for (String fieldName : flagFields.keySet()) {
|
for (String fieldName : flagFields.keySet()) {
|
||||||
if (flagName.equals(fieldName)) {
|
if (flagName.equals(fieldName)) {
|
||||||
return flagFields.get(fieldName).getId();
|
return flagFields.get(fieldName).getId();
|
||||||
@@ -240,7 +240,7 @@ public class FlagCommand implements Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void printKnownFlags(PrintWriter pw) {
|
private void printKnownFlags(PrintWriter pw) {
|
||||||
Map<String, Flag<?>> fields = Flags.getFlagFields();
|
Map<String, Flag<?>> fields = FlagsFactory.INSTANCE.getKnownFlags();
|
||||||
|
|
||||||
int longestFieldName = 0;
|
int longestFieldName = 0;
|
||||||
for (String fieldName : fields.keySet()) {
|
for (String fieldName : fields.keySet()) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2021 The Android Open Source Project
|
* Copyright (C) 2022 The Android Open Source Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -17,12 +17,11 @@ package com.android.systemui.flags
|
|||||||
|
|
||||||
import android.provider.DeviceConfig
|
import android.provider.DeviceConfig
|
||||||
import com.android.internal.annotations.Keep
|
import com.android.internal.annotations.Keep
|
||||||
import com.android.internal.annotations.VisibleForTesting
|
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
import kotlin.reflect.KClass
|
import com.android.systemui.flags.FlagsFactory.releasedFlag
|
||||||
import kotlin.reflect.full.declaredMembers
|
import com.android.systemui.flags.FlagsFactory.resourceBooleanFlag
|
||||||
import kotlin.reflect.full.isSubclassOf
|
import com.android.systemui.flags.FlagsFactory.sysPropBooleanFlag
|
||||||
import kotlin.reflect.full.staticProperties
|
import com.android.systemui.flags.FlagsFactory.unreleasedFlag
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of [Flag] objects for use in SystemUI.
|
* List of [Flag] objects for use in SystemUI.
|
||||||
@@ -37,41 +36,51 @@ import kotlin.reflect.full.staticProperties
|
|||||||
* See [FeatureFlagsDebug] for instructions on flipping the flags via adb.
|
* See [FeatureFlagsDebug] for instructions on flipping the flags via adb.
|
||||||
*/
|
*/
|
||||||
object Flags {
|
object Flags {
|
||||||
@JvmField val TEAMFOOD = UnreleasedFlag(1)
|
@JvmField val TEAMFOOD = unreleasedFlag(1, "teamfood")
|
||||||
|
|
||||||
// 100 - notification
|
// 100 - notification
|
||||||
// TODO(b/254512751): Tracking Bug
|
// TODO(b/254512751): Tracking Bug
|
||||||
val NOTIFICATION_PIPELINE_DEVELOPER_LOGGING = UnreleasedFlag(103)
|
val NOTIFICATION_PIPELINE_DEVELOPER_LOGGING =
|
||||||
|
unreleasedFlag(103, "notification_pipeline_developer_logging")
|
||||||
|
|
||||||
// TODO(b/254512732): Tracking Bug
|
// TODO(b/254512732): Tracking Bug
|
||||||
@JvmField val NSSL_DEBUG_LINES = UnreleasedFlag(105)
|
@JvmField val NSSL_DEBUG_LINES = unreleasedFlag(105, "nssl_debug_lines")
|
||||||
|
|
||||||
// TODO(b/254512505): Tracking Bug
|
// TODO(b/254512505): Tracking Bug
|
||||||
@JvmField val NSSL_DEBUG_REMOVE_ANIMATION = UnreleasedFlag(106)
|
@JvmField val NSSL_DEBUG_REMOVE_ANIMATION = unreleasedFlag(106, "nssl_debug_remove_animation")
|
||||||
|
|
||||||
// TODO(b/254512624): Tracking Bug
|
// TODO(b/254512624): Tracking Bug
|
||||||
@JvmField
|
@JvmField
|
||||||
val NOTIFICATION_DRAG_TO_CONTENTS =
|
val NOTIFICATION_DRAG_TO_CONTENTS =
|
||||||
ResourceBooleanFlag(108, R.bool.config_notificationToContents)
|
resourceBooleanFlag(
|
||||||
|
108,
|
||||||
|
R.bool.config_notificationToContents,
|
||||||
|
"notification_drag_to_contents"
|
||||||
|
)
|
||||||
|
|
||||||
// TODO(b/254512517): Tracking Bug
|
// TODO(b/254512517): Tracking Bug
|
||||||
val FSI_REQUIRES_KEYGUARD = UnreleasedFlag(110, teamfood = true)
|
val FSI_REQUIRES_KEYGUARD = unreleasedFlag(110, "fsi_requires_keyguard", teamfood = true)
|
||||||
|
|
||||||
// TODO(b/254512538): Tracking Bug
|
// TODO(b/254512538): Tracking Bug
|
||||||
val INSTANT_VOICE_REPLY = UnreleasedFlag(111, teamfood = true)
|
val INSTANT_VOICE_REPLY = unreleasedFlag(111, "instant_voice_reply", teamfood = true)
|
||||||
|
|
||||||
// TODO(b/254512425): Tracking Bug
|
// TODO(b/254512425): Tracking Bug
|
||||||
val NOTIFICATION_MEMORY_MONITOR_ENABLED = ReleasedFlag(112)
|
val NOTIFICATION_MEMORY_MONITOR_ENABLED =
|
||||||
|
releasedFlag(112, "notification_memory_monitor_enabled")
|
||||||
|
|
||||||
// TODO(b/254512731): Tracking Bug
|
// TODO(b/254512731): Tracking Bug
|
||||||
@JvmField val NOTIFICATION_DISMISSAL_FADE = UnreleasedFlag(113, teamfood = true)
|
@JvmField
|
||||||
val STABILITY_INDEX_FIX = UnreleasedFlag(114, teamfood = true)
|
val NOTIFICATION_DISMISSAL_FADE =
|
||||||
val SEMI_STABLE_SORT = UnreleasedFlag(115, teamfood = true)
|
unreleasedFlag(113, "notification_dismissal_fade", teamfood = true)
|
||||||
|
val STABILITY_INDEX_FIX = unreleasedFlag(114, "stability_index_fix", teamfood = true)
|
||||||
|
val SEMI_STABLE_SORT = unreleasedFlag(115, "semi_stable_sort", teamfood = true)
|
||||||
|
|
||||||
@JvmField val NOTIFICATION_GROUP_CORNER = UnreleasedFlag(116, teamfood = true)
|
@JvmField
|
||||||
|
val NOTIFICATION_GROUP_CORNER =
|
||||||
|
unreleasedFlag(116, "notification_group_corner", teamfood = true)
|
||||||
|
|
||||||
// TODO(b/257506350): Tracking Bug
|
// TODO(b/257506350): Tracking Bug
|
||||||
val FSI_CHROME = UnreleasedFlag(117)
|
val FSI_CHROME = unreleasedFlag(117, "fsi_chrome")
|
||||||
|
|
||||||
// next id: 118
|
// next id: 118
|
||||||
|
|
||||||
@@ -80,25 +89,27 @@ object Flags {
|
|||||||
// public static final BooleanFlag KEYGUARD_LAYOUT =
|
// public static final BooleanFlag KEYGUARD_LAYOUT =
|
||||||
// new BooleanFlag(200, true);
|
// new BooleanFlag(200, true);
|
||||||
// TODO(b/254512713): Tracking Bug
|
// TODO(b/254512713): Tracking Bug
|
||||||
@JvmField val LOCKSCREEN_ANIMATIONS = ReleasedFlag(201)
|
@JvmField val LOCKSCREEN_ANIMATIONS = releasedFlag(201, "lockscreen_animations")
|
||||||
|
|
||||||
// TODO(b/254512750): Tracking Bug
|
// TODO(b/254512750): Tracking Bug
|
||||||
val NEW_UNLOCK_SWIPE_ANIMATION = ReleasedFlag(202)
|
val NEW_UNLOCK_SWIPE_ANIMATION = releasedFlag(202, "new_unlock_swipe_animation")
|
||||||
val CHARGING_RIPPLE = ResourceBooleanFlag(203, R.bool.flag_charging_ripple)
|
val CHARGING_RIPPLE = resourceBooleanFlag(203, R.bool.flag_charging_ripple, "charging_ripple")
|
||||||
|
|
||||||
// TODO(b/254512281): Tracking Bug
|
// TODO(b/254512281): Tracking Bug
|
||||||
@JvmField
|
@JvmField
|
||||||
val BOUNCER_USER_SWITCHER = ResourceBooleanFlag(204, R.bool.config_enableBouncerUserSwitcher)
|
val BOUNCER_USER_SWITCHER =
|
||||||
|
resourceBooleanFlag(204, R.bool.config_enableBouncerUserSwitcher, "bouncer_user_switcher")
|
||||||
|
|
||||||
// TODO(b/254512676): Tracking Bug
|
// TODO(b/254512676): Tracking Bug
|
||||||
@JvmField val LOCKSCREEN_CUSTOM_CLOCKS = UnreleasedFlag(207, teamfood = true)
|
@JvmField
|
||||||
|
val LOCKSCREEN_CUSTOM_CLOCKS = unreleasedFlag(207, "lockscreen_custom_clocks", teamfood = true)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag to enable the usage of the new bouncer data source. This is a refactor of and eventual
|
* Flag to enable the usage of the new bouncer data source. This is a refactor of and eventual
|
||||||
* replacement of KeyguardBouncer.java.
|
* replacement of KeyguardBouncer.java.
|
||||||
*/
|
*/
|
||||||
// TODO(b/254512385): Tracking Bug
|
// TODO(b/254512385): Tracking Bug
|
||||||
@JvmField val MODERN_BOUNCER = ReleasedFlag(208)
|
@JvmField val MODERN_BOUNCER = releasedFlag(208, "modern_bouncer")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the user interactor and repository should use `UserSwitcherController`.
|
* Whether the user interactor and repository should use `UserSwitcherController`.
|
||||||
@@ -107,7 +118,8 @@ object Flags {
|
|||||||
* framework APIs.
|
* framework APIs.
|
||||||
*/
|
*/
|
||||||
// TODO(b/254513286): Tracking Bug
|
// TODO(b/254513286): Tracking Bug
|
||||||
val USER_INTERACTOR_AND_REPO_USE_CONTROLLER = UnreleasedFlag(210)
|
val USER_INTERACTOR_AND_REPO_USE_CONTROLLER =
|
||||||
|
unreleasedFlag(210, "user_interactor_and_repo_use_controller")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether `UserSwitcherController` should use the user interactor.
|
* Whether `UserSwitcherController` should use the user interactor.
|
||||||
@@ -119,20 +131,24 @@ object Flags {
|
|||||||
* would created a cycle between controller -> interactor -> controller.
|
* would created a cycle between controller -> interactor -> controller.
|
||||||
*/
|
*/
|
||||||
// TODO(b/254513102): Tracking Bug
|
// TODO(b/254513102): Tracking Bug
|
||||||
val USER_CONTROLLER_USES_INTERACTOR = ReleasedFlag(211)
|
val USER_CONTROLLER_USES_INTERACTOR = releasedFlag(211, "user_controller_uses_interactor")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the clock on a wide lock screen should use the new "stepping" animation for moving
|
* Whether the clock on a wide lock screen should use the new "stepping" animation for moving
|
||||||
* the digits when the clock moves.
|
* the digits when the clock moves.
|
||||||
*/
|
*/
|
||||||
@JvmField val STEP_CLOCK_ANIMATION = UnreleasedFlag(212)
|
@JvmField val STEP_CLOCK_ANIMATION = unreleasedFlag(212, "step_clock_animation")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migration from the legacy isDozing/dozeAmount paths to the new KeyguardTransitionRepository
|
* Migration from the legacy isDozing/dozeAmount paths to the new KeyguardTransitionRepository
|
||||||
* will occur in stages. This is one stage of many to come.
|
* will occur in stages. This is one stage of many to come.
|
||||||
*/
|
*/
|
||||||
// TODO(b/255607168): Tracking Bug
|
// TODO(b/255607168): Tracking Bug
|
||||||
@JvmField val DOZING_MIGRATION_1 = UnreleasedFlag(213)
|
@JvmField val DOZING_MIGRATION_1 = unreleasedFlag(213, "dozing_migration_1")
|
||||||
|
|
||||||
|
@JvmField val NEW_ELLIPSE_DETECTION = unreleasedFlag(214, "new_ellipse_detection")
|
||||||
|
|
||||||
|
@JvmField val NEW_UDFPS_OVERLAY = unreleasedFlag(215, "new_udfps_overlay")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to enable the code powering customizable lock screen quick affordances.
|
* Whether to enable the code powering customizable lock screen quick affordances.
|
||||||
@@ -140,267 +156,256 @@ object Flags {
|
|||||||
* Note that this flag does not enable individual implementations of quick affordances like the
|
* Note that this flag does not enable individual implementations of quick affordances like the
|
||||||
* new camera quick affordance. Look for individual flags for those.
|
* new camera quick affordance. Look for individual flags for those.
|
||||||
*/
|
*/
|
||||||
@JvmField val CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES = UnreleasedFlag(214, teamfood = false)
|
@JvmField
|
||||||
|
val CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES =
|
||||||
|
unreleasedFlag(216, "customizable_lock_screen_quick_affordances", teamfood = false)
|
||||||
|
|
||||||
// 300 - power menu
|
// 300 - power menu
|
||||||
// TODO(b/254512600): Tracking Bug
|
// TODO(b/254512600): Tracking Bug
|
||||||
@JvmField val POWER_MENU_LITE = ReleasedFlag(300)
|
@JvmField val POWER_MENU_LITE = releasedFlag(300, "power_menu_lite")
|
||||||
|
|
||||||
// 400 - smartspace
|
// 400 - smartspace
|
||||||
|
|
||||||
// TODO(b/254513100): Tracking Bug
|
// TODO(b/254513100): Tracking Bug
|
||||||
val SMARTSPACE_SHARED_ELEMENT_TRANSITION_ENABLED = ReleasedFlag(401)
|
val SMARTSPACE_SHARED_ELEMENT_TRANSITION_ENABLED =
|
||||||
val SMARTSPACE = ResourceBooleanFlag(402, R.bool.flag_smartspace)
|
releasedFlag(401, "smartspace_shared_element_transition_enabled")
|
||||||
|
val SMARTSPACE = resourceBooleanFlag(402, R.bool.flag_smartspace, "smartspace")
|
||||||
|
|
||||||
// 500 - quick settings
|
// 500 - quick settings
|
||||||
|
|
||||||
// TODO(b/254512321): Tracking Bug
|
// TODO(b/254512321): Tracking Bug
|
||||||
@JvmField val COMBINED_QS_HEADERS = ReleasedFlag(501)
|
@JvmField val COMBINED_QS_HEADERS = releasedFlag(501, "combined_qs_headers")
|
||||||
val PEOPLE_TILE = ResourceBooleanFlag(502, R.bool.flag_conversations)
|
val PEOPLE_TILE = resourceBooleanFlag(502, R.bool.flag_conversations, "people_tile")
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val QS_USER_DETAIL_SHORTCUT =
|
val QS_USER_DETAIL_SHORTCUT =
|
||||||
ResourceBooleanFlag(503, R.bool.flag_lockscreen_qs_user_detail_shortcut)
|
resourceBooleanFlag(
|
||||||
|
503,
|
||||||
|
R.bool.flag_lockscreen_qs_user_detail_shortcut,
|
||||||
|
"qs_user_detail_shortcut"
|
||||||
|
)
|
||||||
|
|
||||||
// TODO(b/254512747): Tracking Bug
|
// TODO(b/254512747): Tracking Bug
|
||||||
val NEW_HEADER = ReleasedFlag(505)
|
val NEW_HEADER = releasedFlag(505, "new_header")
|
||||||
|
|
||||||
// TODO(b/254512383): Tracking Bug
|
// TODO(b/254512383): Tracking Bug
|
||||||
@JvmField
|
@JvmField
|
||||||
val FULL_SCREEN_USER_SWITCHER =
|
val FULL_SCREEN_USER_SWITCHER =
|
||||||
ResourceBooleanFlag(506, R.bool.config_enableFullscreenUserSwitcher)
|
resourceBooleanFlag(
|
||||||
|
506,
|
||||||
|
R.bool.config_enableFullscreenUserSwitcher,
|
||||||
|
"full_screen_user_switcher"
|
||||||
|
)
|
||||||
|
|
||||||
// TODO(b/254512678): Tracking Bug
|
// TODO(b/254512678): Tracking Bug
|
||||||
@JvmField val NEW_FOOTER_ACTIONS = ReleasedFlag(507)
|
@JvmField val NEW_FOOTER_ACTIONS = releasedFlag(507, "new_footer_actions")
|
||||||
|
|
||||||
|
// TODO(b/244064524): Tracking Bug
|
||||||
|
@JvmField
|
||||||
|
val QS_SECONDARY_DATA_SUB_INFO =
|
||||||
|
unreleasedFlag(508, "qs_secondary_data_sub_info", teamfood = true)
|
||||||
|
|
||||||
// 600- status bar
|
// 600- status bar
|
||||||
// TODO(b/254513246): Tracking Bug
|
// TODO(b/254513246): Tracking Bug
|
||||||
val STATUS_BAR_USER_SWITCHER = ResourceBooleanFlag(602, R.bool.flag_user_switcher_chip)
|
val STATUS_BAR_USER_SWITCHER =
|
||||||
|
resourceBooleanFlag(602, R.bool.flag_user_switcher_chip, "status_bar_user_switcher")
|
||||||
|
|
||||||
// TODO(b/254512623): Tracking Bug
|
// TODO(b/254512623): Tracking Bug
|
||||||
@Deprecated("Replaced by mobile and wifi specific flags.")
|
@Deprecated("Replaced by mobile and wifi specific flags.")
|
||||||
val NEW_STATUS_BAR_PIPELINE_BACKEND = UnreleasedFlag(604, teamfood = false)
|
val NEW_STATUS_BAR_PIPELINE_BACKEND =
|
||||||
|
unreleasedFlag(604, "new_status_bar_pipeline_backend", teamfood = false)
|
||||||
|
|
||||||
// TODO(b/254512660): Tracking Bug
|
// TODO(b/254512660): Tracking Bug
|
||||||
@Deprecated("Replaced by mobile and wifi specific flags.")
|
@Deprecated("Replaced by mobile and wifi specific flags.")
|
||||||
val NEW_STATUS_BAR_PIPELINE_FRONTEND = UnreleasedFlag(605, teamfood = false)
|
val NEW_STATUS_BAR_PIPELINE_FRONTEND =
|
||||||
|
unreleasedFlag(605, "new_status_bar_pipeline_frontend", teamfood = false)
|
||||||
|
|
||||||
// TODO(b/256614753): Tracking Bug
|
// TODO(b/256614753): Tracking Bug
|
||||||
val NEW_STATUS_BAR_MOBILE_ICONS = UnreleasedFlag(606)
|
val NEW_STATUS_BAR_MOBILE_ICONS = unreleasedFlag(606, "new_status_bar_mobile_icons")
|
||||||
|
|
||||||
// TODO(b/256614210): Tracking Bug
|
// TODO(b/256614210): Tracking Bug
|
||||||
val NEW_STATUS_BAR_WIFI_ICON = UnreleasedFlag(607)
|
val NEW_STATUS_BAR_WIFI_ICON = unreleasedFlag(607, "new_status_bar_wifi_icon")
|
||||||
|
|
||||||
// TODO(b/256614751): Tracking Bug
|
// TODO(b/256614751): Tracking Bug
|
||||||
val NEW_STATUS_BAR_MOBILE_ICONS_BACKEND = UnreleasedFlag(608)
|
val NEW_STATUS_BAR_MOBILE_ICONS_BACKEND =
|
||||||
|
unreleasedFlag(608, "new_status_bar_mobile_icons_backend")
|
||||||
|
|
||||||
// TODO(b/256613548): Tracking Bug
|
// TODO(b/256613548): Tracking Bug
|
||||||
val NEW_STATUS_BAR_WIFI_ICON_BACKEND = UnreleasedFlag(609)
|
val NEW_STATUS_BAR_WIFI_ICON_BACKEND = unreleasedFlag(609, "new_status_bar_wifi_icon_backend")
|
||||||
|
|
||||||
// 700 - dialer/calls
|
// 700 - dialer/calls
|
||||||
// TODO(b/254512734): Tracking Bug
|
// TODO(b/254512734): Tracking Bug
|
||||||
val ONGOING_CALL_STATUS_BAR_CHIP = ReleasedFlag(700)
|
val ONGOING_CALL_STATUS_BAR_CHIP = releasedFlag(700, "ongoing_call_status_bar_chip")
|
||||||
|
|
||||||
// TODO(b/254512681): Tracking Bug
|
// TODO(b/254512681): Tracking Bug
|
||||||
val ONGOING_CALL_IN_IMMERSIVE = ReleasedFlag(701)
|
val ONGOING_CALL_IN_IMMERSIVE = releasedFlag(701, "ongoing_call_in_immersive")
|
||||||
|
|
||||||
// TODO(b/254512753): Tracking Bug
|
// TODO(b/254512753): Tracking Bug
|
||||||
val ONGOING_CALL_IN_IMMERSIVE_CHIP_TAP = ReleasedFlag(702)
|
val ONGOING_CALL_IN_IMMERSIVE_CHIP_TAP = releasedFlag(702, "ongoing_call_in_immersive_chip_tap")
|
||||||
|
|
||||||
// 800 - general visual/theme
|
// 800 - general visual/theme
|
||||||
@JvmField val MONET = ResourceBooleanFlag(800, R.bool.flag_monet)
|
@JvmField val MONET = resourceBooleanFlag(800, R.bool.flag_monet, "monet")
|
||||||
|
|
||||||
// 801 - region sampling
|
// 801 - region sampling
|
||||||
// TODO(b/254512848): Tracking Bug
|
// TODO(b/254512848): Tracking Bug
|
||||||
val REGION_SAMPLING = UnreleasedFlag(801)
|
val REGION_SAMPLING = unreleasedFlag(801, "region_sampling")
|
||||||
|
|
||||||
// 802 - wallpaper rendering
|
// 802 - wallpaper rendering
|
||||||
// TODO(b/254512923): Tracking Bug
|
// TODO(b/254512923): Tracking Bug
|
||||||
@JvmField val USE_CANVAS_RENDERER = ReleasedFlag(802)
|
@JvmField val USE_CANVAS_RENDERER = unreleasedFlag(802, "use_canvas_renderer")
|
||||||
|
|
||||||
// 803 - screen contents translation
|
// 803 - screen contents translation
|
||||||
// TODO(b/254513187): Tracking Bug
|
// TODO(b/254513187): Tracking Bug
|
||||||
val SCREEN_CONTENTS_TRANSLATION = UnreleasedFlag(803)
|
val SCREEN_CONTENTS_TRANSLATION = unreleasedFlag(803, "screen_contents_translation")
|
||||||
|
|
||||||
// 804 - monochromatic themes
|
// 804 - monochromatic themes
|
||||||
@JvmField
|
@JvmField
|
||||||
val MONOCHROMATIC_THEMES = SysPropBooleanFlag(804, "persist.sysui.monochromatic", false)
|
val MONOCHROMATIC_THEMES =
|
||||||
|
sysPropBooleanFlag(804, "persist.sysui.monochromatic", default = false)
|
||||||
|
|
||||||
// 900 - media
|
// 900 - media
|
||||||
// TODO(b/254512697): Tracking Bug
|
// TODO(b/254512697): Tracking Bug
|
||||||
val MEDIA_TAP_TO_TRANSFER = ReleasedFlag(900)
|
val MEDIA_TAP_TO_TRANSFER = releasedFlag(900, "media_tap_to_transfer")
|
||||||
|
|
||||||
// TODO(b/254512502): Tracking Bug
|
// TODO(b/254512502): Tracking Bug
|
||||||
val MEDIA_SESSION_ACTIONS = UnreleasedFlag(901)
|
val MEDIA_SESSION_ACTIONS = unreleasedFlag(901, "media_session_actions")
|
||||||
|
|
||||||
// TODO(b/254512726): Tracking Bug
|
// TODO(b/254512726): Tracking Bug
|
||||||
val MEDIA_NEARBY_DEVICES = ReleasedFlag(903)
|
val MEDIA_NEARBY_DEVICES = releasedFlag(903, "media_nearby_devices")
|
||||||
|
|
||||||
// TODO(b/254512695): Tracking Bug
|
// TODO(b/254512695): Tracking Bug
|
||||||
val MEDIA_MUTE_AWAIT = ReleasedFlag(904)
|
val MEDIA_MUTE_AWAIT = releasedFlag(904, "media_mute_await")
|
||||||
|
|
||||||
// TODO(b/254512654): Tracking Bug
|
// TODO(b/254512654): Tracking Bug
|
||||||
@JvmField val DREAM_MEDIA_COMPLICATION = UnreleasedFlag(905)
|
@JvmField val DREAM_MEDIA_COMPLICATION = unreleasedFlag(905, "dream_media_complication")
|
||||||
|
|
||||||
// TODO(b/254512673): Tracking Bug
|
// TODO(b/254512673): Tracking Bug
|
||||||
@JvmField val DREAM_MEDIA_TAP_TO_OPEN = UnreleasedFlag(906)
|
@JvmField val DREAM_MEDIA_TAP_TO_OPEN = unreleasedFlag(906, "dream_media_tap_to_open")
|
||||||
|
|
||||||
// TODO(b/254513168): Tracking Bug
|
// TODO(b/254513168): Tracking Bug
|
||||||
@JvmField val UMO_SURFACE_RIPPLE = UnreleasedFlag(907)
|
@JvmField val UMO_SURFACE_RIPPLE = unreleasedFlag(907, "umo_surface_ripple")
|
||||||
|
|
||||||
// 1000 - dock
|
// 1000 - dock
|
||||||
val SIMULATE_DOCK_THROUGH_CHARGING = ReleasedFlag(1000)
|
val SIMULATE_DOCK_THROUGH_CHARGING = releasedFlag(1000, "simulate_dock_through_charging")
|
||||||
|
|
||||||
// TODO(b/254512758): Tracking Bug
|
// TODO(b/254512758): Tracking Bug
|
||||||
@JvmField val ROUNDED_BOX_RIPPLE = ReleasedFlag(1002)
|
@JvmField val ROUNDED_BOX_RIPPLE = releasedFlag(1002, "rounded_box_ripple")
|
||||||
|
|
||||||
// 1100 - windowing
|
// 1100 - windowing
|
||||||
@Keep
|
@Keep
|
||||||
@JvmField
|
@JvmField
|
||||||
val WM_ENABLE_SHELL_TRANSITIONS =
|
val WM_ENABLE_SHELL_TRANSITIONS =
|
||||||
SysPropBooleanFlag(1100, "persist.wm.debug.shell_transit", false)
|
sysPropBooleanFlag(1100, "persist.wm.debug.shell_transit", default = false)
|
||||||
|
|
||||||
// TODO(b/254513207): Tracking Bug
|
// TODO(b/254513207): Tracking Bug
|
||||||
@Keep
|
@Keep
|
||||||
@JvmField
|
@JvmField
|
||||||
val WM_ENABLE_PARTIAL_SCREEN_SHARING =
|
val WM_ENABLE_PARTIAL_SCREEN_SHARING =
|
||||||
DeviceConfigBooleanFlag(
|
unreleasedFlag(
|
||||||
1102,
|
1102,
|
||||||
"record_task_content",
|
name = "record_task_content",
|
||||||
DeviceConfig.NAMESPACE_WINDOW_MANAGER,
|
namespace = DeviceConfig.NAMESPACE_WINDOW_MANAGER,
|
||||||
false,
|
|
||||||
teamfood = true
|
teamfood = true
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO(b/254512674): Tracking Bug
|
// TODO(b/254512674): Tracking Bug
|
||||||
@Keep
|
@Keep
|
||||||
@JvmField
|
@JvmField
|
||||||
val HIDE_NAVBAR_WINDOW = SysPropBooleanFlag(1103, "persist.wm.debug.hide_navbar_window", false)
|
val HIDE_NAVBAR_WINDOW =
|
||||||
|
sysPropBooleanFlag(1103, "persist.wm.debug.hide_navbar_window", default = false)
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@JvmField
|
@JvmField
|
||||||
val WM_DESKTOP_WINDOWING = SysPropBooleanFlag(1104, "persist.wm.debug.desktop_mode", false)
|
val WM_DESKTOP_WINDOWING =
|
||||||
|
sysPropBooleanFlag(1104, "persist.wm.debug.desktop_mode", default = false)
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@JvmField
|
@JvmField
|
||||||
val WM_CAPTION_ON_SHELL = SysPropBooleanFlag(1105, "persist.wm.debug.caption_on_shell", false)
|
val WM_CAPTION_ON_SHELL =
|
||||||
|
sysPropBooleanFlag(1105, "persist.wm.debug.caption_on_shell", default = false)
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@JvmField
|
@JvmField
|
||||||
val ENABLE_FLING_TO_DISMISS_BUBBLE =
|
val ENABLE_FLING_TO_DISMISS_BUBBLE =
|
||||||
SysPropBooleanFlag(1108, "persist.wm.debug.fling_to_dismiss_bubble", true)
|
sysPropBooleanFlag(1108, "persist.wm.debug.fling_to_dismiss_bubble", default = true)
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@JvmField
|
@JvmField
|
||||||
val ENABLE_FLING_TO_DISMISS_PIP =
|
val ENABLE_FLING_TO_DISMISS_PIP =
|
||||||
SysPropBooleanFlag(1109, "persist.wm.debug.fling_to_dismiss_pip", true)
|
sysPropBooleanFlag(1109, "persist.wm.debug.fling_to_dismiss_pip", default = true)
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@JvmField
|
@JvmField
|
||||||
val ENABLE_PIP_KEEP_CLEAR_ALGORITHM =
|
val ENABLE_PIP_KEEP_CLEAR_ALGORITHM =
|
||||||
SysPropBooleanFlag(1110, "persist.wm.debug.enable_pip_keep_clear_algorithm", false)
|
sysPropBooleanFlag(
|
||||||
|
1110,
|
||||||
|
"persist.wm.debug.enable_pip_keep_clear_algorithm",
|
||||||
|
default = false
|
||||||
|
)
|
||||||
|
|
||||||
// TODO(b/256873975): Tracking Bug
|
// TODO(b/256873975): Tracking Bug
|
||||||
@JvmField @Keep val WM_BUBBLE_BAR = UnreleasedFlag(1111)
|
@JvmField @Keep val WM_BUBBLE_BAR = unreleasedFlag(1111, "wm_bubble_bar")
|
||||||
|
|
||||||
// 1200 - predictive back
|
// 1200 - predictive back
|
||||||
@Keep
|
@Keep
|
||||||
@JvmField
|
@JvmField
|
||||||
val WM_ENABLE_PREDICTIVE_BACK =
|
val WM_ENABLE_PREDICTIVE_BACK =
|
||||||
SysPropBooleanFlag(1200, "persist.wm.debug.predictive_back", true)
|
sysPropBooleanFlag(1200, "persist.wm.debug.predictive_back", default = true)
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@JvmField
|
@JvmField
|
||||||
val WM_ENABLE_PREDICTIVE_BACK_ANIM =
|
val WM_ENABLE_PREDICTIVE_BACK_ANIM =
|
||||||
SysPropBooleanFlag(1201, "persist.wm.debug.predictive_back_anim", false)
|
sysPropBooleanFlag(1201, "persist.wm.debug.predictive_back_anim", default = false)
|
||||||
|
|
||||||
@Keep
|
@Keep
|
||||||
@JvmField
|
@JvmField
|
||||||
val WM_ALWAYS_ENFORCE_PREDICTIVE_BACK =
|
val WM_ALWAYS_ENFORCE_PREDICTIVE_BACK =
|
||||||
SysPropBooleanFlag(1202, "persist.wm.debug.predictive_back_always_enforce", false)
|
sysPropBooleanFlag(1202, "persist.wm.debug.predictive_back_always_enforce", default = false)
|
||||||
|
|
||||||
// TODO(b/254512728): Tracking Bug
|
// TODO(b/254512728): Tracking Bug
|
||||||
@JvmField val NEW_BACK_AFFORDANCE = UnreleasedFlag(1203, teamfood = false)
|
@JvmField
|
||||||
|
val NEW_BACK_AFFORDANCE = unreleasedFlag(1203, "new_back_affordance", teamfood = false)
|
||||||
|
|
||||||
// 1300 - screenshots
|
// 1300 - screenshots
|
||||||
// TODO(b/254512719): Tracking Bug
|
// TODO(b/254512719): Tracking Bug
|
||||||
@JvmField val SCREENSHOT_REQUEST_PROCESSOR = UnreleasedFlag(1300, teamfood = true)
|
@JvmField
|
||||||
|
val SCREENSHOT_REQUEST_PROCESSOR =
|
||||||
|
unreleasedFlag(1300, "screenshot_request_processor", teamfood = true)
|
||||||
|
|
||||||
// TODO(b/254513155): Tracking Bug
|
// TODO(b/254513155): Tracking Bug
|
||||||
@JvmField val SCREENSHOT_WORK_PROFILE_POLICY = UnreleasedFlag(1301)
|
@JvmField
|
||||||
|
val SCREENSHOT_WORK_PROFILE_POLICY = unreleasedFlag(1301, "screenshot_work_profile_policy")
|
||||||
|
|
||||||
// 1400 - columbus
|
// 1400 - columbus
|
||||||
// TODO(b/254512756): Tracking Bug
|
// TODO(b/254512756): Tracking Bug
|
||||||
val QUICK_TAP_IN_PCC = ReleasedFlag(1400)
|
val QUICK_TAP_IN_PCC = releasedFlag(1400, "quick_tap_in_pcc")
|
||||||
|
|
||||||
// 1500 - chooser
|
// 1500 - chooser
|
||||||
// TODO(b/254512507): Tracking Bug
|
// TODO(b/254512507): Tracking Bug
|
||||||
val CHOOSER_UNBUNDLED = UnreleasedFlag(1500, teamfood = true)
|
val CHOOSER_UNBUNDLED = unreleasedFlag(1500, "chooser_unbundled", teamfood = true)
|
||||||
|
|
||||||
|
// 1600 - accessibility
|
||||||
|
@JvmField
|
||||||
|
val A11Y_FLOATING_MENU_FLING_SPRING_ANIMATIONS =
|
||||||
|
unreleasedFlag(1600, "a11y_floating_menu_fling_spring_animations")
|
||||||
|
|
||||||
// 1700 - clipboard
|
// 1700 - clipboard
|
||||||
@JvmField val CLIPBOARD_OVERLAY_REFACTOR = UnreleasedFlag(1700, teamfood = true)
|
@JvmField
|
||||||
@JvmField val CLIPBOARD_REMOTE_BEHAVIOR = UnreleasedFlag(1701)
|
val CLIPBOARD_OVERLAY_REFACTOR =
|
||||||
|
unreleasedFlag(1700, "clipboard_overlay_refactor", teamfood = true)
|
||||||
|
@JvmField val CLIPBOARD_REMOTE_BEHAVIOR = unreleasedFlag(1701, "clipboard_remote_behavior")
|
||||||
|
|
||||||
// 1800 - shade container
|
// 1800 - shade container
|
||||||
@JvmField val LEAVE_SHADE_OPEN_FOR_BUGREPORT = UnreleasedFlag(1800, teamfood = true)
|
@JvmField
|
||||||
|
val LEAVE_SHADE_OPEN_FOR_BUGREPORT =
|
||||||
|
unreleasedFlag(1800, "leave_shade_open_for_bugreport", teamfood = true)
|
||||||
|
|
||||||
// 1900 - note task
|
// 1900 - note task
|
||||||
@JvmField val NOTE_TASKS = SysPropBooleanFlag(1900, "persist.sysui.debug.note_tasks")
|
@JvmField val NOTE_TASKS = sysPropBooleanFlag(1900, "persist.sysui.debug.note_tasks")
|
||||||
|
|
||||||
// 2000 - device controls
|
// 2000 - device controls
|
||||||
@Keep @JvmField val USE_APP_PANELS = UnreleasedFlag(2000, teamfood = true)
|
@Keep @JvmField val USE_APP_PANELS = unreleasedFlag(2000, "use_app_panels", teamfood = true)
|
||||||
|
|
||||||
// 2100 - Falsing Manager
|
// 2100 - Falsing Manager
|
||||||
@JvmField val FALSING_FOR_LONG_TAPS = ReleasedFlag(2100)
|
@JvmField val FALSING_FOR_LONG_TAPS = releasedFlag(2100, "falsing_for_long_taps")
|
||||||
|
|
||||||
// Pay no attention to the reflection behind the curtain.
|
|
||||||
// ========================== Curtain ==========================
|
|
||||||
// | |
|
|
||||||
// | . . . . . . . . . . . . . . . . . . . |
|
|
||||||
@JvmStatic
|
|
||||||
fun collectFlags(): Map<Int, Flag<*>> {
|
|
||||||
return flagFields.mapKeys { field -> field.value.id }
|
|
||||||
}
|
|
||||||
|
|
||||||
// | . . . . . . . . . . . . . . . . . . . |
|
|
||||||
@JvmStatic
|
|
||||||
val flagFields: Map<String, Flag<*>>
|
|
||||||
get() = collectFlagsInClass(Flags)
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
fun collectFlagsInClass(instance: Any): Map<String, Flag<*>> {
|
|
||||||
val cls = instance::class
|
|
||||||
val javaPropNames = cls.java.fields.map { it.name }
|
|
||||||
val props = cls.declaredMembers
|
|
||||||
val staticProps = cls.staticProperties
|
|
||||||
val staticPropNames = staticProps.map { it.name }
|
|
||||||
return props
|
|
||||||
.mapNotNull { property ->
|
|
||||||
if ((property.returnType.classifier as KClass<*>).isSubclassOf(Flag::class)) {
|
|
||||||
// Fields with @JvmStatic should be accessed via java mechanisms
|
|
||||||
if (javaPropNames.contains(property.name)) {
|
|
||||||
property.name to cls.java.getField(property.name)[null] as Flag<*>
|
|
||||||
// Fields with @Keep but not @JvmField. Don't do this.
|
|
||||||
} else if (staticPropNames.contains(property.name)) {
|
|
||||||
// The below code causes access violation exceptions. I don't know why.
|
|
||||||
// property.name to (property.call() as Flag<*>)
|
|
||||||
// property.name to (staticProps.find { it.name == property.name }!!
|
|
||||||
// .getter.call() as Flag<*>)
|
|
||||||
throw java.lang.RuntimeException(
|
|
||||||
"The {$property.name} flag needs @JvmField"
|
|
||||||
)
|
|
||||||
// Everything else. Skip the `get` prefixed fields that kotlin adds.
|
|
||||||
} else if (property.name.subSequence(0, 3) != "get") {
|
|
||||||
property.name to (property.call(instance) as Flag<*>)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.toMap()
|
|
||||||
}
|
|
||||||
// | |
|
|
||||||
// \_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ interface FlagsCommonModule {
|
|||||||
@Provides
|
@Provides
|
||||||
@Named(ALL_FLAGS)
|
@Named(ALL_FLAGS)
|
||||||
fun providesAllFlags(): Map<Int, Flag<*>> {
|
fun providesAllFlags(): Map<Int, Flag<*>> {
|
||||||
return Flags.collectFlags()
|
return FlagsFactory.knownFlags.map { it.value.id to it.value }.toMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
|||||||
@@ -27,11 +27,10 @@ import javax.inject.Inject
|
|||||||
|
|
||||||
interface ServerFlagReader {
|
interface ServerFlagReader {
|
||||||
/** Returns true if there is a server-side setting stored. */
|
/** 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. */
|
/** 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. */
|
/** Register a listener for changes to any of the passed in flags. */
|
||||||
fun listenForChanges(values: Collection<Flag<*>>, listener: ChangeListener)
|
fun listenForChanges(values: Collection<Flag<*>>, listener: ChangeListener)
|
||||||
|
|
||||||
@@ -68,19 +67,19 @@ class ServerFlagReaderImpl @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hasOverride(flagId: Int): Boolean =
|
override fun hasOverride(namespace: String, name: String): Boolean =
|
||||||
deviceConfig.getProperty(
|
!namespace.isBlank() && !name.isBlank() && deviceConfig.getProperty(
|
||||||
namespace,
|
namespace,
|
||||||
getServerOverrideName(flagId)
|
name
|
||||||
) != null
|
) != 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,
|
namespace,
|
||||||
getServerOverrideName(flagId),
|
name,
|
||||||
default
|
default
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
override fun listenForChanges(
|
override fun listenForChanges(
|
||||||
flags: Collection<Flag<*>>,
|
flags: Collection<Flag<*>>,
|
||||||
@@ -121,24 +120,24 @@ interface ServerFlagReaderModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ServerFlagReaderFake : ServerFlagReader {
|
class ServerFlagReaderFake : ServerFlagReader {
|
||||||
private val flagMap: MutableMap<Int, Boolean> = mutableMapOf()
|
private val flagMap: MutableMap<String, Boolean> = mutableMapOf()
|
||||||
private val listeners =
|
private val listeners =
|
||||||
mutableListOf<Pair<ServerFlagReader.ChangeListener, Collection<Flag<*>>>>()
|
mutableListOf<Pair<ServerFlagReader.ChangeListener, Collection<Flag<*>>>>()
|
||||||
|
|
||||||
override fun hasOverride(flagId: Int): Boolean {
|
override fun hasOverride(namespace: String, name: String): Boolean {
|
||||||
return flagMap.containsKey(flagId)
|
return flagMap.containsKey(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun readServerOverride(flagId: Int, default: Boolean): Boolean {
|
override fun readServerOverride(namespace: String, name: String, default: Boolean): Boolean {
|
||||||
return flagMap.getOrDefault(flagId, default)
|
return flagMap.getOrDefault(name, default)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setFlagValue(flagId: Int, value: Boolean) {
|
fun setFlagValue(namespace: String, name: String, value: Boolean) {
|
||||||
flagMap.put(flagId, value)
|
flagMap.put(name, value)
|
||||||
|
|
||||||
for ((listener, flags) in listeners) {
|
for ((listener, flags) in listeners) {
|
||||||
flagLoop@ for (flag in flags) {
|
flagLoop@ for (flag in flags) {
|
||||||
if (flagId == flag.id) {
|
if (name == flag.name) {
|
||||||
listener.onChange()
|
listener.onChange()
|
||||||
break@flagLoop
|
break@flagLoop
|
||||||
}
|
}
|
||||||
@@ -146,8 +145,8 @@ class ServerFlagReaderFake : ServerFlagReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun eraseFlag(flagId: Int) {
|
fun eraseFlag(namespace: String, name: String) {
|
||||||
flagMap.remove(flagId)
|
flagMap.remove(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun listenForChanges(
|
override fun listenForChanges(
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import android.testing.AndroidTestingRunner
|
|||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import java.lang.IllegalStateException
|
|
||||||
import org.junit.Assert.fail
|
import org.junit.Assert.fail
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
@@ -29,12 +28,12 @@ import org.junit.runner.RunWith
|
|||||||
@RunWith(AndroidTestingRunner::class)
|
@RunWith(AndroidTestingRunner::class)
|
||||||
class FakeFeatureFlagsTest : SysuiTestCase() {
|
class FakeFeatureFlagsTest : SysuiTestCase() {
|
||||||
|
|
||||||
private val unreleasedFlag = UnreleasedFlag(-1000)
|
private val unreleasedFlag = UnreleasedFlag(-1000, "-1000", "test")
|
||||||
private val releasedFlag = ReleasedFlag(-1001)
|
private val releasedFlag = ReleasedFlag(-1001, "-1001", "test")
|
||||||
private val stringFlag = StringFlag(-1002)
|
private val stringFlag = StringFlag(-1002, "-1002", "test")
|
||||||
private val resourceBooleanFlag = ResourceBooleanFlag(-1003, resourceId = -1)
|
private val resourceBooleanFlag = ResourceBooleanFlag(-1003, "-1003", "test", resourceId = -1)
|
||||||
private val resourceStringFlag = ResourceStringFlag(-1004, resourceId = -1)
|
private val resourceStringFlag = ResourceStringFlag(-1004, "-1004", "test", resourceId = -1)
|
||||||
private val sysPropBooleanFlag = SysPropBooleanFlag(-1005, name = "test")
|
private val sysPropBooleanFlag = SysPropBooleanFlag(-1005, "test", "test")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FakeFeatureFlags does not honor any default values. All flags which are accessed must be
|
* FakeFeatureFlags does not honor any default values. All flags which are accessed must be
|
||||||
@@ -47,7 +46,7 @@ class FakeFeatureFlagsTest : SysuiTestCase() {
|
|||||||
assertThat(flags.isEnabled(Flags.TEAMFOOD)).isFalse()
|
assertThat(flags.isEnabled(Flags.TEAMFOOD)).isFalse()
|
||||||
fail("Expected an exception when accessing an unspecified flag.")
|
fail("Expected an exception when accessing an unspecified flag.")
|
||||||
} catch (ex: IllegalStateException) {
|
} catch (ex: IllegalStateException) {
|
||||||
assertThat(ex.message).contains("TEAMFOOD")
|
assertThat(ex.message).contains("id=1")
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
assertThat(flags.isEnabled(unreleasedFlag)).isFalse()
|
assertThat(flags.isEnabled(unreleasedFlag)).isFalse()
|
||||||
|
|||||||
@@ -31,10 +31,6 @@ import com.android.systemui.util.mockito.nullable
|
|||||||
import com.android.systemui.util.mockito.withArgCaptor
|
import com.android.systemui.util.mockito.withArgCaptor
|
||||||
import com.android.systemui.util.settings.SecureSettings
|
import com.android.systemui.util.settings.SecureSettings
|
||||||
import com.google.common.truth.Truth.assertThat
|
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.Assert
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@@ -46,8 +42,12 @@ import org.mockito.Mockito.inOrder
|
|||||||
import org.mockito.Mockito.times
|
import org.mockito.Mockito.times
|
||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
import org.mockito.Mockito.verifyNoMoreInteractions
|
import org.mockito.Mockito.verifyNoMoreInteractions
|
||||||
import org.mockito.Mockito.`when` as whenever
|
|
||||||
import org.mockito.MockitoAnnotations
|
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
|
* NOTE: This test is for the version of FeatureFlagManager in src-debug, which allows overriding
|
||||||
@@ -57,21 +57,32 @@ import org.mockito.MockitoAnnotations
|
|||||||
class FeatureFlagsDebugTest : SysuiTestCase() {
|
class FeatureFlagsDebugTest : SysuiTestCase() {
|
||||||
private lateinit var mFeatureFlagsDebug: FeatureFlagsDebug
|
private lateinit var mFeatureFlagsDebug: FeatureFlagsDebug
|
||||||
|
|
||||||
@Mock private lateinit var flagManager: FlagManager
|
@Mock
|
||||||
@Mock private lateinit var mockContext: Context
|
private lateinit var flagManager: FlagManager
|
||||||
@Mock private lateinit var secureSettings: SecureSettings
|
@Mock
|
||||||
@Mock private lateinit var systemProperties: SystemPropertiesHelper
|
private lateinit var mockContext: Context
|
||||||
@Mock private lateinit var resources: Resources
|
@Mock
|
||||||
@Mock private lateinit var commandRegistry: CommandRegistry
|
private lateinit var secureSettings: SecureSettings
|
||||||
@Mock private lateinit var restarter: Restarter
|
@Mock
|
||||||
|
private lateinit var systemProperties: SystemPropertiesHelper
|
||||||
|
@Mock
|
||||||
|
private lateinit var resources: Resources
|
||||||
|
@Mock
|
||||||
|
private lateinit var commandRegistry: CommandRegistry
|
||||||
|
@Mock
|
||||||
|
private lateinit var restarter: Restarter
|
||||||
private val flagMap = mutableMapOf<Int, Flag<*>>()
|
private val flagMap = mutableMapOf<Int, Flag<*>>()
|
||||||
private lateinit var broadcastReceiver: BroadcastReceiver
|
private lateinit var broadcastReceiver: BroadcastReceiver
|
||||||
private lateinit var clearCacheAction: Consumer<Int>
|
private lateinit var clearCacheAction: Consumer<Int>
|
||||||
private val serverFlagReader = ServerFlagReaderFake()
|
private val serverFlagReader = ServerFlagReaderFake()
|
||||||
|
|
||||||
private val deviceConfig = DeviceConfigProxyFake()
|
private val deviceConfig = DeviceConfigProxyFake()
|
||||||
private val teamfoodableFlagA = UnreleasedFlag(500, true)
|
private val teamfoodableFlagA = UnreleasedFlag(
|
||||||
private val teamfoodableFlagB = ReleasedFlag(501, true)
|
500, name = "a", namespace = "test", teamfood = true
|
||||||
|
)
|
||||||
|
private val teamfoodableFlagB = ReleasedFlag(
|
||||||
|
501, name = "b", namespace = "test", teamfood = true
|
||||||
|
)
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
@@ -84,7 +95,6 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
secureSettings,
|
secureSettings,
|
||||||
systemProperties,
|
systemProperties,
|
||||||
resources,
|
resources,
|
||||||
deviceConfig,
|
|
||||||
serverFlagReader,
|
serverFlagReader,
|
||||||
flagMap,
|
flagMap,
|
||||||
restarter
|
restarter
|
||||||
@@ -92,8 +102,10 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
mFeatureFlagsDebug.init()
|
mFeatureFlagsDebug.init()
|
||||||
verify(flagManager).onSettingsChangedAction = any()
|
verify(flagManager).onSettingsChangedAction = any()
|
||||||
broadcastReceiver = withArgCaptor {
|
broadcastReceiver = withArgCaptor {
|
||||||
verify(mockContext).registerReceiver(capture(), any(), nullable(), nullable(),
|
verify(mockContext).registerReceiver(
|
||||||
any())
|
capture(), any(), nullable(), nullable(),
|
||||||
|
any()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
clearCacheAction = withArgCaptor {
|
clearCacheAction = withArgCaptor {
|
||||||
verify(flagManager).clearCacheAction = capture()
|
verify(flagManager).clearCacheAction = capture()
|
||||||
@@ -107,10 +119,42 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
whenever(flagManager.readFlagValue<Boolean>(eq(3), any())).thenReturn(true)
|
whenever(flagManager.readFlagValue<Boolean>(eq(3), any())).thenReturn(true)
|
||||||
whenever(flagManager.readFlagValue<Boolean>(eq(4), any())).thenReturn(false)
|
whenever(flagManager.readFlagValue<Boolean>(eq(4), any())).thenReturn(false)
|
||||||
|
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(ReleasedFlag(2))).isTrue()
|
assertThat(
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(UnreleasedFlag(3))).isTrue()
|
mFeatureFlagsDebug.isEnabled(
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(ReleasedFlag(4))).isFalse()
|
ReleasedFlag(
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(UnreleasedFlag(5))).isFalse()
|
2,
|
||||||
|
name = "2",
|
||||||
|
namespace = "test"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).isTrue()
|
||||||
|
assertThat(
|
||||||
|
mFeatureFlagsDebug.isEnabled(
|
||||||
|
UnreleasedFlag(
|
||||||
|
3,
|
||||||
|
name = "3",
|
||||||
|
namespace = "test"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).isTrue()
|
||||||
|
assertThat(
|
||||||
|
mFeatureFlagsDebug.isEnabled(
|
||||||
|
ReleasedFlag(
|
||||||
|
4,
|
||||||
|
name = "3",
|
||||||
|
namespace = "test"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).isFalse()
|
||||||
|
assertThat(
|
||||||
|
mFeatureFlagsDebug.isEnabled(
|
||||||
|
UnreleasedFlag(
|
||||||
|
5,
|
||||||
|
name = "4",
|
||||||
|
namespace = "test"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -138,9 +182,9 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun teamFoodFlag_Overridden() {
|
fun teamFoodFlag_Overridden() {
|
||||||
whenever(flagManager.readFlagValue<Boolean>(eq(teamfoodableFlagA.id), any()))
|
whenever(flagManager.readFlagValue<Boolean>(eq(teamfoodableFlagA.id), any()))
|
||||||
.thenReturn(true)
|
.thenReturn(true)
|
||||||
whenever(flagManager.readFlagValue<Boolean>(eq(teamfoodableFlagB.id), any()))
|
whenever(flagManager.readFlagValue<Boolean>(eq(teamfoodableFlagB.id), any()))
|
||||||
.thenReturn(false)
|
.thenReturn(false)
|
||||||
whenever(flagManager.readFlagValue<Boolean>(eq(1), any())).thenReturn(true)
|
whenever(flagManager.readFlagValue<Boolean>(eq(1), any())).thenReturn(true)
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue()
|
assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue()
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isFalse()
|
assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isFalse()
|
||||||
@@ -161,17 +205,26 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
whenever(flagManager.readFlagValue<Boolean>(eq(3), any())).thenReturn(true)
|
whenever(flagManager.readFlagValue<Boolean>(eq(3), any())).thenReturn(true)
|
||||||
whenever(flagManager.readFlagValue<Boolean>(eq(5), any())).thenReturn(false)
|
whenever(flagManager.readFlagValue<Boolean>(eq(5), any())).thenReturn(false)
|
||||||
|
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(1, 1001))).isFalse()
|
assertThat(
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(2, 1002))).isTrue()
|
mFeatureFlagsDebug.isEnabled(
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(3, 1003))).isTrue()
|
ResourceBooleanFlag(
|
||||||
|
1,
|
||||||
|
"1",
|
||||||
|
"test",
|
||||||
|
1001
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).isFalse()
|
||||||
|
assertThat(mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(2, "2", "test", 1002))).isTrue()
|
||||||
|
assertThat(mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(3, "3", "test", 1003))).isTrue()
|
||||||
|
|
||||||
Assert.assertThrows(NameNotFoundException::class.java) {
|
Assert.assertThrows(NameNotFoundException::class.java) {
|
||||||
mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(4, 1004))
|
mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(4, "4", "test", 1004))
|
||||||
}
|
}
|
||||||
// Test that resource is loaded (and validated) even when the setting is set.
|
// Test that resource is loaded (and validated) even when the setting is set.
|
||||||
// This prevents developers from not noticing when they reference an invalid resource.
|
// This prevents developers from not noticing when they reference an invalid resource.
|
||||||
Assert.assertThrows(NameNotFoundException::class.java) {
|
Assert.assertThrows(NameNotFoundException::class.java) {
|
||||||
mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(5, 1005))
|
mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(5, "5", "test", 1005))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,36 +237,30 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
return@thenAnswer it.getArgument(1)
|
return@thenAnswer it.getArgument(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(1, "a"))).isFalse()
|
assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(1, "a", "test"))).isFalse()
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(2, "b"))).isTrue()
|
assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(2, "b", "test"))).isTrue()
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(3, "c", true))).isTrue()
|
assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(3, "c", "test", true))).isTrue()
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(4, "d", false))).isFalse()
|
assertThat(
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(5, "e"))).isFalse()
|
mFeatureFlagsDebug.isEnabled(
|
||||||
}
|
SysPropBooleanFlag(
|
||||||
|
4,
|
||||||
@Test
|
"d",
|
||||||
fun readDeviceConfigBooleanFlag() {
|
"test",
|
||||||
val namespace = "test_namespace"
|
false
|
||||||
deviceConfig.setProperty(namespace, "a", "true", false)
|
)
|
||||||
deviceConfig.setProperty(namespace, "b", "false", false)
|
)
|
||||||
deviceConfig.setProperty(namespace, "c", null, false)
|
).isFalse()
|
||||||
|
assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(5, "e", "test"))).isFalse()
|
||||||
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
|
@Test
|
||||||
fun readStringFlag() {
|
fun readStringFlag() {
|
||||||
whenever(flagManager.readFlagValue<String>(eq(3), any())).thenReturn("foo")
|
whenever(flagManager.readFlagValue<String>(eq(3), any())).thenReturn("foo")
|
||||||
whenever(flagManager.readFlagValue<String>(eq(4), any())).thenReturn("bar")
|
whenever(flagManager.readFlagValue<String>(eq(4), any())).thenReturn("bar")
|
||||||
assertThat(mFeatureFlagsDebug.getString(StringFlag(1, "biz"))).isEqualTo("biz")
|
assertThat(mFeatureFlagsDebug.getString(StringFlag(1, "1", "test", "biz"))).isEqualTo("biz")
|
||||||
assertThat(mFeatureFlagsDebug.getString(StringFlag(2, "baz"))).isEqualTo("baz")
|
assertThat(mFeatureFlagsDebug.getString(StringFlag(2, "2", "test", "baz"))).isEqualTo("baz")
|
||||||
assertThat(mFeatureFlagsDebug.getString(StringFlag(3, "buz"))).isEqualTo("foo")
|
assertThat(mFeatureFlagsDebug.getString(StringFlag(3, "3", "test", "buz"))).isEqualTo("foo")
|
||||||
assertThat(mFeatureFlagsDebug.getString(StringFlag(4, "buz"))).isEqualTo("bar")
|
assertThat(mFeatureFlagsDebug.getString(StringFlag(4, "4", "test", "buz"))).isEqualTo("bar")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -229,20 +276,47 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
whenever(flagManager.readFlagValue<String>(eq(4), any())).thenReturn("override4")
|
whenever(flagManager.readFlagValue<String>(eq(4), any())).thenReturn("override4")
|
||||||
whenever(flagManager.readFlagValue<String>(eq(6), any())).thenReturn("override6")
|
whenever(flagManager.readFlagValue<String>(eq(6), any())).thenReturn("override6")
|
||||||
|
|
||||||
assertThat(mFeatureFlagsDebug.getString(ResourceStringFlag(1, 1001))).isEqualTo("")
|
assertThat(
|
||||||
assertThat(mFeatureFlagsDebug.getString(ResourceStringFlag(2, 1002))).isEqualTo("resource2")
|
mFeatureFlagsDebug.getString(
|
||||||
assertThat(mFeatureFlagsDebug.getString(ResourceStringFlag(3, 1003))).isEqualTo("override3")
|
ResourceStringFlag(
|
||||||
|
1,
|
||||||
|
"1",
|
||||||
|
"test",
|
||||||
|
1001
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).isEqualTo("")
|
||||||
|
assertThat(
|
||||||
|
mFeatureFlagsDebug.getString(
|
||||||
|
ResourceStringFlag(
|
||||||
|
2,
|
||||||
|
"2",
|
||||||
|
"test",
|
||||||
|
1002
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).isEqualTo("resource2")
|
||||||
|
assertThat(
|
||||||
|
mFeatureFlagsDebug.getString(
|
||||||
|
ResourceStringFlag(
|
||||||
|
3,
|
||||||
|
"3",
|
||||||
|
"test",
|
||||||
|
1003
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).isEqualTo("override3")
|
||||||
|
|
||||||
Assert.assertThrows(NullPointerException::class.java) {
|
Assert.assertThrows(NullPointerException::class.java) {
|
||||||
mFeatureFlagsDebug.getString(ResourceStringFlag(4, 1004))
|
mFeatureFlagsDebug.getString(ResourceStringFlag(4, "4", "test", 1004))
|
||||||
}
|
}
|
||||||
Assert.assertThrows(NameNotFoundException::class.java) {
|
Assert.assertThrows(NameNotFoundException::class.java) {
|
||||||
mFeatureFlagsDebug.getString(ResourceStringFlag(5, 1005))
|
mFeatureFlagsDebug.getString(ResourceStringFlag(5, "5", "test", 1005))
|
||||||
}
|
}
|
||||||
// Test that resource is loaded (and validated) even when the setting is set.
|
// Test that resource is loaded (and validated) even when the setting is set.
|
||||||
// This prevents developers from not noticing when they reference an invalid resource.
|
// This prevents developers from not noticing when they reference an invalid resource.
|
||||||
Assert.assertThrows(NameNotFoundException::class.java) {
|
Assert.assertThrows(NameNotFoundException::class.java) {
|
||||||
mFeatureFlagsDebug.getString(ResourceStringFlag(6, 1005))
|
mFeatureFlagsDebug.getString(ResourceStringFlag(6, "6", "test", 1005))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,10 +324,10 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
fun readIntFlag() {
|
fun readIntFlag() {
|
||||||
whenever(flagManager.readFlagValue<Int>(eq(3), any())).thenReturn(22)
|
whenever(flagManager.readFlagValue<Int>(eq(3), any())).thenReturn(22)
|
||||||
whenever(flagManager.readFlagValue<Int>(eq(4), any())).thenReturn(48)
|
whenever(flagManager.readFlagValue<Int>(eq(4), any())).thenReturn(48)
|
||||||
assertThat(mFeatureFlagsDebug.getInt(IntFlag(1, 12))).isEqualTo(12)
|
assertThat(mFeatureFlagsDebug.getInt(IntFlag(1, "1", "test", 12))).isEqualTo(12)
|
||||||
assertThat(mFeatureFlagsDebug.getInt(IntFlag(2, 93))).isEqualTo(93)
|
assertThat(mFeatureFlagsDebug.getInt(IntFlag(2, "2", "test", 93))).isEqualTo(93)
|
||||||
assertThat(mFeatureFlagsDebug.getInt(IntFlag(3, 8))).isEqualTo(22)
|
assertThat(mFeatureFlagsDebug.getInt(IntFlag(3, "3", "test", 8))).isEqualTo(22)
|
||||||
assertThat(mFeatureFlagsDebug.getInt(IntFlag(4, 234))).isEqualTo(48)
|
assertThat(mFeatureFlagsDebug.getInt(IntFlag(4, "4", "test", 234))).isEqualTo(48)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -269,26 +343,26 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
whenever(flagManager.readFlagValue<Int>(eq(4), any())).thenReturn(500)
|
whenever(flagManager.readFlagValue<Int>(eq(4), any())).thenReturn(500)
|
||||||
whenever(flagManager.readFlagValue<Int>(eq(5), any())).thenReturn(9519)
|
whenever(flagManager.readFlagValue<Int>(eq(5), any())).thenReturn(9519)
|
||||||
|
|
||||||
assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(1, 1001))).isEqualTo(88)
|
assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(1, "1", "test", 1001))).isEqualTo(88)
|
||||||
assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(2, 1002))).isEqualTo(61)
|
assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(2, "2", "test", 1002))).isEqualTo(61)
|
||||||
assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(3, 1003))).isEqualTo(20)
|
assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(3, "3", "test", 1003))).isEqualTo(20)
|
||||||
|
|
||||||
Assert.assertThrows(NotFoundException::class.java) {
|
Assert.assertThrows(NotFoundException::class.java) {
|
||||||
mFeatureFlagsDebug.getInt(ResourceIntFlag(4, 1004))
|
mFeatureFlagsDebug.getInt(ResourceIntFlag(4, "4", "test", 1004))
|
||||||
}
|
}
|
||||||
// Test that resource is loaded (and validated) even when the setting is set.
|
// Test that resource is loaded (and validated) even when the setting is set.
|
||||||
// This prevents developers from not noticing when they reference an invalid resource.
|
// This prevents developers from not noticing when they reference an invalid resource.
|
||||||
Assert.assertThrows(NotFoundException::class.java) {
|
Assert.assertThrows(NotFoundException::class.java) {
|
||||||
mFeatureFlagsDebug.getInt(ResourceIntFlag(5, 1005))
|
mFeatureFlagsDebug.getInt(ResourceIntFlag(5, "5", "test", 1005))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun broadcastReceiver_IgnoresInvalidData() {
|
fun broadcastReceiver_IgnoresInvalidData() {
|
||||||
addFlag(UnreleasedFlag(1))
|
addFlag(UnreleasedFlag(1, "1", "test"))
|
||||||
addFlag(ResourceBooleanFlag(2, 1002))
|
addFlag(ResourceBooleanFlag(2, "2", "test", 1002))
|
||||||
addFlag(StringFlag(3, "flag3"))
|
addFlag(StringFlag(3, "3", "test", "flag3"))
|
||||||
addFlag(ResourceStringFlag(4, 1004))
|
addFlag(ResourceStringFlag(4, "4", "test", 1004))
|
||||||
|
|
||||||
broadcastReceiver.onReceive(mockContext, null)
|
broadcastReceiver.onReceive(mockContext, null)
|
||||||
broadcastReceiver.onReceive(mockContext, Intent())
|
broadcastReceiver.onReceive(mockContext, Intent())
|
||||||
@@ -304,7 +378,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun intentWithId_NoValueKeyClears() {
|
fun intentWithId_NoValueKeyClears() {
|
||||||
addFlag(UnreleasedFlag(1))
|
addFlag(UnreleasedFlag(1, name = "1", namespace = "test"))
|
||||||
|
|
||||||
// trying to erase an id not in the map does nothing
|
// trying to erase an id not in the map does nothing
|
||||||
broadcastReceiver.onReceive(
|
broadcastReceiver.onReceive(
|
||||||
@@ -323,10 +397,10 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun setBooleanFlag() {
|
fun setBooleanFlag() {
|
||||||
addFlag(UnreleasedFlag(1))
|
addFlag(UnreleasedFlag(1, "1", "test"))
|
||||||
addFlag(UnreleasedFlag(2))
|
addFlag(UnreleasedFlag(2, "2", "test"))
|
||||||
addFlag(ResourceBooleanFlag(3, 1003))
|
addFlag(ResourceBooleanFlag(3, "3", "test", 1003))
|
||||||
addFlag(ResourceBooleanFlag(4, 1004))
|
addFlag(ResourceBooleanFlag(4, "4", "test", 1004))
|
||||||
|
|
||||||
setByBroadcast(1, false)
|
setByBroadcast(1, false)
|
||||||
verifyPutData(1, "{\"type\":\"boolean\",\"value\":false}")
|
verifyPutData(1, "{\"type\":\"boolean\",\"value\":false}")
|
||||||
@@ -343,8 +417,8 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun setStringFlag() {
|
fun setStringFlag() {
|
||||||
addFlag(StringFlag(1, "flag1"))
|
addFlag(StringFlag(1, "flag1", "1", "test"))
|
||||||
addFlag(ResourceStringFlag(2, 1002))
|
addFlag(ResourceStringFlag(2, "2", "test", 1002))
|
||||||
|
|
||||||
setByBroadcast(1, "override1")
|
setByBroadcast(1, "override1")
|
||||||
verifyPutData(1, "{\"type\":\"string\",\"value\":\"override1\"}")
|
verifyPutData(1, "{\"type\":\"string\",\"value\":\"override1\"}")
|
||||||
@@ -355,7 +429,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun setFlag_ClearsCache() {
|
fun setFlag_ClearsCache() {
|
||||||
val flag1 = addFlag(StringFlag(1, "flag1"))
|
val flag1 = addFlag(StringFlag(1, "1", "test", "flag1"))
|
||||||
whenever(flagManager.readFlagValue<String>(eq(1), any())).thenReturn("original")
|
whenever(flagManager.readFlagValue<String>(eq(1), any())).thenReturn("original")
|
||||||
|
|
||||||
// gets the flag & cache it
|
// gets the flag & cache it
|
||||||
@@ -377,31 +451,31 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun serverSide_Overrides_MakesFalse() {
|
fun serverSide_Overrides_MakesFalse() {
|
||||||
val flag = ReleasedFlag(100)
|
val flag = ReleasedFlag(100, "100", "test")
|
||||||
|
|
||||||
serverFlagReader.setFlagValue(flag.id, false)
|
serverFlagReader.setFlagValue(flag.namespace, flag.name, false)
|
||||||
|
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(flag)).isFalse()
|
assertThat(mFeatureFlagsDebug.isEnabled(flag)).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun serverSide_Overrides_MakesTrue() {
|
fun serverSide_Overrides_MakesTrue() {
|
||||||
val flag = UnreleasedFlag(100)
|
val flag = UnreleasedFlag(100, name = "100", namespace = "test")
|
||||||
|
|
||||||
serverFlagReader.setFlagValue(flag.id, true)
|
serverFlagReader.setFlagValue(flag.namespace, flag.name, true)
|
||||||
|
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(flag)).isTrue()
|
assertThat(mFeatureFlagsDebug.isEnabled(flag)).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun dumpFormat() {
|
fun dumpFormat() {
|
||||||
val flag1 = ReleasedFlag(1)
|
val flag1 = ReleasedFlag(1, "1", "test")
|
||||||
val flag2 = ResourceBooleanFlag(2, 1002)
|
val flag2 = ResourceBooleanFlag(2, "2", "test", 1002)
|
||||||
val flag3 = UnreleasedFlag(3)
|
val flag3 = UnreleasedFlag(3, "3", "test")
|
||||||
val flag4 = StringFlag(4, "")
|
val flag4 = StringFlag(4, "4", "test", "")
|
||||||
val flag5 = StringFlag(5, "flag5default")
|
val flag5 = StringFlag(5, "5", "test", "flag5default")
|
||||||
val flag6 = ResourceStringFlag(6, 1006)
|
val flag6 = ResourceStringFlag(6, "6", "test", 1006)
|
||||||
val flag7 = ResourceStringFlag(7, 1007)
|
val flag7 = ResourceStringFlag(7, "7", "test", 1007)
|
||||||
|
|
||||||
whenever(resources.getBoolean(1002)).thenReturn(true)
|
whenever(resources.getBoolean(1002)).thenReturn(true)
|
||||||
whenever(resources.getString(1006)).thenReturn("resource1006")
|
whenever(resources.getString(1006)).thenReturn("resource1006")
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ import org.junit.Assert.assertThrows
|
|||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.`when` as whenever
|
|
||||||
import org.mockito.MockitoAnnotations
|
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
|
* NOTE: This test is for the version of FeatureFlagManager in src-release, which should not allow
|
||||||
@@ -59,7 +59,9 @@ class FeatureFlagsReleaseTest : SysuiTestCase() {
|
|||||||
fun testBooleanResourceFlag() {
|
fun testBooleanResourceFlag() {
|
||||||
val flagId = 213
|
val flagId = 213
|
||||||
val flagResourceId = 3
|
val flagResourceId = 3
|
||||||
val flag = ResourceBooleanFlag(flagId, flagResourceId)
|
val flagName = "213"
|
||||||
|
val flagNamespace = "test"
|
||||||
|
val flag = ResourceBooleanFlag(flagId, flagName, flagNamespace, flagResourceId)
|
||||||
whenever(mResources.getBoolean(flagResourceId)).thenReturn(true)
|
whenever(mResources.getBoolean(flagResourceId)).thenReturn(true)
|
||||||
assertThat(mFeatureFlagsRelease.isEnabled(flag)).isTrue()
|
assertThat(mFeatureFlagsRelease.isEnabled(flag)).isTrue()
|
||||||
}
|
}
|
||||||
@@ -71,57 +73,45 @@ class FeatureFlagsReleaseTest : SysuiTestCase() {
|
|||||||
whenever(mResources.getString(1003)).thenReturn(null)
|
whenever(mResources.getString(1003)).thenReturn(null)
|
||||||
whenever(mResources.getString(1004)).thenAnswer { throw NameNotFoundException() }
|
whenever(mResources.getString(1004)).thenAnswer { throw NameNotFoundException() }
|
||||||
|
|
||||||
assertThat(mFeatureFlagsRelease.getString(ResourceStringFlag(1, 1001))).isEqualTo("")
|
assertThat(mFeatureFlagsRelease.getString(
|
||||||
assertThat(mFeatureFlagsRelease.getString(ResourceStringFlag(2, 1002))).isEqualTo("res2")
|
ResourceStringFlag(1, "1", "test", 1001))).isEqualTo("")
|
||||||
|
assertThat(mFeatureFlagsRelease.getString(
|
||||||
|
ResourceStringFlag(2, "2", "test", 1002))).isEqualTo("res2")
|
||||||
|
|
||||||
assertThrows(NullPointerException::class.java) {
|
assertThrows(NullPointerException::class.java) {
|
||||||
mFeatureFlagsRelease.getString(ResourceStringFlag(3, 1003))
|
mFeatureFlagsRelease.getString(ResourceStringFlag(3, "3", "test", 1003))
|
||||||
}
|
}
|
||||||
assertThrows(NameNotFoundException::class.java) {
|
assertThrows(NameNotFoundException::class.java) {
|
||||||
mFeatureFlagsRelease.getString(ResourceStringFlag(4, 1004))
|
mFeatureFlagsRelease.getString(ResourceStringFlag(4, "4", "test", 1004))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@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
|
@Test
|
||||||
fun testSysPropBooleanFlag() {
|
fun testSysPropBooleanFlag() {
|
||||||
val flagId = 213
|
val flagId = 213
|
||||||
val flagName = "sys_prop_flag"
|
val flagName = "sys_prop_flag"
|
||||||
|
val flagNamespace = "test"
|
||||||
val flagDefault = true
|
val flagDefault = true
|
||||||
|
|
||||||
val flag = SysPropBooleanFlag(flagId, flagName, flagDefault)
|
val flag = SysPropBooleanFlag(flagId, flagName, flagNamespace, flagDefault)
|
||||||
whenever(mSystemProperties.getBoolean(flagName, flagDefault)).thenReturn(flagDefault)
|
whenever(mSystemProperties.getBoolean(flagName, flagDefault)).thenReturn(flagDefault)
|
||||||
assertThat(mFeatureFlagsRelease.isEnabled(flag)).isEqualTo(flagDefault)
|
assertThat(mFeatureFlagsRelease.isEnabled(flag)).isEqualTo(flagDefault)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun serverSide_OverridesReleased_MakesFalse() {
|
fun serverSide_OverridesReleased_MakesFalse() {
|
||||||
val flag = ReleasedFlag(100)
|
val flag = ReleasedFlag(100, "100", "test")
|
||||||
|
|
||||||
serverFlagReader.setFlagValue(flag.id, false)
|
serverFlagReader.setFlagValue(flag.namespace, flag.name, false)
|
||||||
|
|
||||||
assertThat(mFeatureFlagsRelease.isEnabled(flag)).isFalse()
|
assertThat(mFeatureFlagsRelease.isEnabled(flag)).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun serverSide_OverridesUnreleased_Ignored() {
|
fun serverSide_OverridesUnreleased_Ignored() {
|
||||||
val flag = UnreleasedFlag(100)
|
val flag = UnreleasedFlag(100, "100", "test")
|
||||||
|
|
||||||
serverFlagReader.setFlagValue(flag.id, true)
|
serverFlagReader.setFlagValue(flag.namespace, flag.name, true)
|
||||||
|
|
||||||
assertThat(mFeatureFlagsRelease.isEnabled(flag)).isFalse()
|
assertThat(mFeatureFlagsRelease.isEnabled(flag)).isFalse()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ class FlagCommandTest : SysuiTestCase() {
|
|||||||
@Mock private lateinit var featureFlags: FeatureFlagsDebug
|
@Mock private lateinit var featureFlags: FeatureFlagsDebug
|
||||||
@Mock private lateinit var pw: PrintWriter
|
@Mock private lateinit var pw: PrintWriter
|
||||||
private val flagMap = mutableMapOf<Int, Flag<*>>()
|
private val flagMap = mutableMapOf<Int, Flag<*>>()
|
||||||
private val flagA = UnreleasedFlag(500)
|
private val flagA = UnreleasedFlag(500, "500", "test")
|
||||||
private val flagB = ReleasedFlag(501)
|
private val flagB = ReleasedFlag(501, "501", "test")
|
||||||
private val stringFlag = StringFlag(502, "abracadabra")
|
private val stringFlag = StringFlag(502, "502", "test", "abracadabra")
|
||||||
private val intFlag = IntFlag(503, 12)
|
private val intFlag = IntFlag(503, "503", "test", 12)
|
||||||
|
|
||||||
private lateinit var cmd: FlagCommand
|
private lateinit var cmd: FlagCommand
|
||||||
|
|
||||||
|
|||||||
@@ -64,14 +64,14 @@ class FlagManagerTest : SysuiTestCase() {
|
|||||||
verifyNoMoreInteractions(mFlagSettingsHelper)
|
verifyNoMoreInteractions(mFlagSettingsHelper)
|
||||||
|
|
||||||
// adding the first listener registers the observer
|
// adding the first listener registers the observer
|
||||||
mFlagManager.addListener(ReleasedFlag(1), listener1)
|
mFlagManager.addListener(ReleasedFlag(1, "1", "test"), listener1)
|
||||||
val observer = withArgCaptor<ContentObserver> {
|
val observer = withArgCaptor<ContentObserver> {
|
||||||
verify(mFlagSettingsHelper).registerContentObserver(any(), any(), capture())
|
verify(mFlagSettingsHelper).registerContentObserver(any(), any(), capture())
|
||||||
}
|
}
|
||||||
verifyNoMoreInteractions(mFlagSettingsHelper)
|
verifyNoMoreInteractions(mFlagSettingsHelper)
|
||||||
|
|
||||||
// adding another listener does nothing
|
// adding another listener does nothing
|
||||||
mFlagManager.addListener(ReleasedFlag(2), listener2)
|
mFlagManager.addListener(ReleasedFlag(2, "2", "test"), listener2)
|
||||||
verifyNoMoreInteractions(mFlagSettingsHelper)
|
verifyNoMoreInteractions(mFlagSettingsHelper)
|
||||||
|
|
||||||
// removing the original listener does nothing with second one still present
|
// removing the original listener does nothing with second one still present
|
||||||
@@ -89,7 +89,7 @@ class FlagManagerTest : SysuiTestCase() {
|
|||||||
val listener = mock<FlagListenable.Listener>()
|
val listener = mock<FlagListenable.Listener>()
|
||||||
val clearCacheAction = mock<Consumer<Int>>()
|
val clearCacheAction = mock<Consumer<Int>>()
|
||||||
mFlagManager.clearCacheAction = clearCacheAction
|
mFlagManager.clearCacheAction = clearCacheAction
|
||||||
mFlagManager.addListener(ReleasedFlag(1), listener)
|
mFlagManager.addListener(ReleasedFlag(1, "1", "test"), listener)
|
||||||
val observer = withArgCaptor<ContentObserver> {
|
val observer = withArgCaptor<ContentObserver> {
|
||||||
verify(mFlagSettingsHelper).registerContentObserver(any(), any(), capture())
|
verify(mFlagSettingsHelper).registerContentObserver(any(), any(), capture())
|
||||||
}
|
}
|
||||||
@@ -101,8 +101,8 @@ class FlagManagerTest : SysuiTestCase() {
|
|||||||
fun testObserverInvokesListeners() {
|
fun testObserverInvokesListeners() {
|
||||||
val listener1 = mock<FlagListenable.Listener>()
|
val listener1 = mock<FlagListenable.Listener>()
|
||||||
val listener10 = mock<FlagListenable.Listener>()
|
val listener10 = mock<FlagListenable.Listener>()
|
||||||
mFlagManager.addListener(ReleasedFlag(1), listener1)
|
mFlagManager.addListener(ReleasedFlag(1, "1", "test"), listener1)
|
||||||
mFlagManager.addListener(ReleasedFlag(10), listener10)
|
mFlagManager.addListener(ReleasedFlag(10, "10", "test"), listener10)
|
||||||
val observer = withArgCaptor<ContentObserver> {
|
val observer = withArgCaptor<ContentObserver> {
|
||||||
verify(mFlagSettingsHelper).registerContentObserver(any(), any(), capture())
|
verify(mFlagSettingsHelper).registerContentObserver(any(), any(), capture())
|
||||||
}
|
}
|
||||||
@@ -127,8 +127,8 @@ class FlagManagerTest : SysuiTestCase() {
|
|||||||
fun testOnlySpecificFlagListenerIsInvoked() {
|
fun testOnlySpecificFlagListenerIsInvoked() {
|
||||||
val listener1 = mock<FlagListenable.Listener>()
|
val listener1 = mock<FlagListenable.Listener>()
|
||||||
val listener10 = mock<FlagListenable.Listener>()
|
val listener10 = mock<FlagListenable.Listener>()
|
||||||
mFlagManager.addListener(ReleasedFlag(1), listener1)
|
mFlagManager.addListener(ReleasedFlag(1, "1", "test"), listener1)
|
||||||
mFlagManager.addListener(ReleasedFlag(10), listener10)
|
mFlagManager.addListener(ReleasedFlag(10, "10", "test"), listener10)
|
||||||
|
|
||||||
mFlagManager.dispatchListenersAndMaybeRestart(1, null)
|
mFlagManager.dispatchListenersAndMaybeRestart(1, null)
|
||||||
val flagEvent1 = withArgCaptor<FlagListenable.FlagEvent> {
|
val flagEvent1 = withArgCaptor<FlagListenable.FlagEvent> {
|
||||||
@@ -148,8 +148,8 @@ class FlagManagerTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun testSameListenerCanBeUsedForMultipleFlags() {
|
fun testSameListenerCanBeUsedForMultipleFlags() {
|
||||||
val listener = mock<FlagListenable.Listener>()
|
val listener = mock<FlagListenable.Listener>()
|
||||||
mFlagManager.addListener(ReleasedFlag(1), listener)
|
mFlagManager.addListener(ReleasedFlag(1, "1", "test"), listener)
|
||||||
mFlagManager.addListener(ReleasedFlag(10), listener)
|
mFlagManager.addListener(ReleasedFlag(10, "10", "test"), listener)
|
||||||
|
|
||||||
mFlagManager.dispatchListenersAndMaybeRestart(1, null)
|
mFlagManager.dispatchListenersAndMaybeRestart(1, null)
|
||||||
val flagEvent1 = withArgCaptor<FlagListenable.FlagEvent> {
|
val flagEvent1 = withArgCaptor<FlagListenable.FlagEvent> {
|
||||||
@@ -177,7 +177,7 @@ class FlagManagerTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun testListenerCanSuppressRestart() {
|
fun testListenerCanSuppressRestart() {
|
||||||
val restartAction = mock<Consumer<Boolean>>()
|
val restartAction = mock<Consumer<Boolean>>()
|
||||||
mFlagManager.addListener(ReleasedFlag(1)) { event ->
|
mFlagManager.addListener(ReleasedFlag(1, "1", "test")) { event ->
|
||||||
event.requestNoRestart()
|
event.requestNoRestart()
|
||||||
}
|
}
|
||||||
mFlagManager.dispatchListenersAndMaybeRestart(1, restartAction)
|
mFlagManager.dispatchListenersAndMaybeRestart(1, restartAction)
|
||||||
@@ -188,7 +188,7 @@ class FlagManagerTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun testListenerOnlySuppressesRestartForOwnFlag() {
|
fun testListenerOnlySuppressesRestartForOwnFlag() {
|
||||||
val restartAction = mock<Consumer<Boolean>>()
|
val restartAction = mock<Consumer<Boolean>>()
|
||||||
mFlagManager.addListener(ReleasedFlag(10)) { event ->
|
mFlagManager.addListener(ReleasedFlag(10, "10", "test")) { event ->
|
||||||
event.requestNoRestart()
|
event.requestNoRestart()
|
||||||
}
|
}
|
||||||
mFlagManager.dispatchListenersAndMaybeRestart(1, restartAction)
|
mFlagManager.dispatchListenersAndMaybeRestart(1, restartAction)
|
||||||
@@ -199,10 +199,10 @@ class FlagManagerTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun testRestartWhenNotAllListenersRequestSuppress() {
|
fun testRestartWhenNotAllListenersRequestSuppress() {
|
||||||
val restartAction = mock<Consumer<Boolean>>()
|
val restartAction = mock<Consumer<Boolean>>()
|
||||||
mFlagManager.addListener(ReleasedFlag(10)) { event ->
|
mFlagManager.addListener(ReleasedFlag(10, "10", "test")) { event ->
|
||||||
event.requestNoRestart()
|
event.requestNoRestart()
|
||||||
}
|
}
|
||||||
mFlagManager.addListener(ReleasedFlag(10)) {
|
mFlagManager.addListener(ReleasedFlag(10, "10", "test")) {
|
||||||
// do not request
|
// do not request
|
||||||
}
|
}
|
||||||
mFlagManager.dispatchListenersAndMaybeRestart(1, restartAction)
|
mFlagManager.dispatchListenersAndMaybeRestart(1, restartAction)
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2021 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 androidx.test.filters.SmallTest
|
|
||||||
import com.android.systemui.SysuiTestCase
|
|
||||||
import com.google.common.truth.Truth
|
|
||||||
import java.lang.StringBuilder
|
|
||||||
import java.util.ArrayList
|
|
||||||
import java.util.HashMap
|
|
||||||
import org.junit.Test
|
|
||||||
|
|
||||||
@SmallTest
|
|
||||||
class FlagsTest : SysuiTestCase() {
|
|
||||||
@Test
|
|
||||||
fun testDuplicateFlagIdCheckWorks() {
|
|
||||||
val flags = Flags.collectFlagsInClass(DuplicateFlagContainer)
|
|
||||||
val duplicates = groupDuplicateFlags(flags)
|
|
||||||
Truth.assertWithMessage(generateAssertionMessage(duplicates))
|
|
||||||
.that(duplicates.size)
|
|
||||||
.isEqualTo(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testNoDuplicateFlagIds() {
|
|
||||||
val flags = Flags.collectFlagsInClass(Flags)
|
|
||||||
val duplicates = groupDuplicateFlags(flags)
|
|
||||||
Truth.assertWithMessage(generateAssertionMessage(duplicates))
|
|
||||||
.that(duplicates.size)
|
|
||||||
.isEqualTo(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateAssertionMessage(duplicates: Map<Int, List<String>>): String {
|
|
||||||
val stringBuilder = StringBuilder()
|
|
||||||
stringBuilder.append("Duplicate flag keys found: {")
|
|
||||||
for (id in duplicates.keys) {
|
|
||||||
stringBuilder
|
|
||||||
.append(" ")
|
|
||||||
.append(id)
|
|
||||||
.append(": [")
|
|
||||||
.append(java.lang.String.join(", ", duplicates[id]))
|
|
||||||
.append("]")
|
|
||||||
}
|
|
||||||
stringBuilder.append(" }")
|
|
||||||
return stringBuilder.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun groupDuplicateFlags(flags: Map<String, Flag<*>>): Map<Int, List<String>> {
|
|
||||||
val grouping: MutableMap<Int, MutableList<String>> = HashMap()
|
|
||||||
for (flag in flags) {
|
|
||||||
grouping.putIfAbsent(flag.value.id, ArrayList())
|
|
||||||
grouping[flag.value.id]!!.add(flag.key)
|
|
||||||
}
|
|
||||||
val result: MutableMap<Int, List<String>> = HashMap()
|
|
||||||
for (id in grouping.keys) {
|
|
||||||
if (grouping[id]!!.size > 1) {
|
|
||||||
result[id] = grouping[id]!!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
private object DuplicateFlagContainer {
|
|
||||||
val A_FLAG: BooleanFlag = UnreleasedFlag(0)
|
|
||||||
val B_FLAG: BooleanFlag = UnreleasedFlag(0)
|
|
||||||
val C_FLAG = StringFlag(0)
|
|
||||||
val D_FLAG: BooleanFlag = UnreleasedFlag(1)
|
|
||||||
val E_FLAG = DoubleFlag(3)
|
|
||||||
val F_FLAG = DoubleFlag(3)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -50,7 +50,7 @@ class ServerFlagReaderImplTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testChange_alertsListener() {
|
fun testChange_alertsListener() {
|
||||||
val flag = ReleasedFlag(1)
|
val flag = ReleasedFlag(1, "1", "test")
|
||||||
serverFlagReader.listenForChanges(listOf(flag), changeListener)
|
serverFlagReader.listenForChanges(listOf(flag), changeListener)
|
||||||
|
|
||||||
deviceConfig.setProperty(NAMESPACE, "flag_override_1", "1", false)
|
deviceConfig.setProperty(NAMESPACE, "flag_override_1", "1", false)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class FakeFeatureFlags : FeatureFlags {
|
|||||||
private val listenerFlagIds = mutableMapOf<FlagListenable.Listener, MutableSet<Int>>()
|
private val listenerFlagIds = mutableMapOf<FlagListenable.Listener, MutableSet<Int>>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
Flags.flagFields.forEach { entry: Map.Entry<String, Flag<*>> ->
|
FlagsFactory.knownFlags.forEach { entry: Map.Entry<String, Flag<*>> ->
|
||||||
knownFlagNames[entry.value.id] = entry.key
|
knownFlagNames[entry.value.id] = entry.key
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,8 +87,6 @@ class FakeFeatureFlags : FeatureFlags {
|
|||||||
|
|
||||||
override fun isEnabled(flag: ResourceBooleanFlag): Boolean = requireBooleanValue(flag.id)
|
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 isEnabled(flag: SysPropBooleanFlag): Boolean = requireBooleanValue(flag.id)
|
||||||
|
|
||||||
override fun getString(flag: StringFlag): String = requireStringValue(flag.id)
|
override fun getString(flag: StringFlag): String = requireStringValue(flag.id)
|
||||||
|
|||||||
Reference in New Issue
Block a user