Merge changes I29bf2065,Ic858826c,I7fe0bd12 into tm-qpr-dev am: 2dcc550cb7
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20414824 Change-Id: If053320b02960ffbc57c4d88316e16d3284481f0 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
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",
|
||||||
|
|||||||
@@ -63,9 +63,9 @@ 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 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
|
||||||
) : ParcelableFlag<Boolean> {
|
) : ParcelableFlag<Boolean> {
|
||||||
@@ -80,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()
|
||||||
@@ -87,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)
|
||||||
@@ -100,11 +104,11 @@ 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 name: String,
|
||||||
override val namespace: 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, name, namespace, teamfood, overridden)
|
) : BooleanFlag(id, name, namespace, false, teamfood, overridden)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Flag that is true by default.
|
* A Flag that is true by default.
|
||||||
@@ -113,11 +117,11 @@ data class UnreleasedFlag constructor(
|
|||||||
*/
|
*/
|
||||||
data class ReleasedFlag constructor(
|
data class ReleasedFlag constructor(
|
||||||
override val id: Int,
|
override val id: Int,
|
||||||
override val name: String = "",
|
override val name: String,
|
||||||
override val namespace: 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, name, namespace, 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.
|
||||||
@@ -126,9 +130,9 @@ 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 name: String = "",
|
|
||||||
override val namespace: String = "",
|
|
||||||
override val teamfood: Boolean = false
|
override val teamfood: Boolean = false
|
||||||
) : ResourceFlag<Boolean>
|
) : ResourceFlag<Boolean>
|
||||||
|
|
||||||
@@ -157,8 +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 namespace: String,
|
||||||
override val default: Boolean = false,
|
override val default: Boolean = false,
|
||||||
override val namespace: String = ""
|
|
||||||
) : 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
|
||||||
@@ -166,9 +170,9 @@ 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 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
|
||||||
) : ParcelableFlag<String> {
|
) : ParcelableFlag<String> {
|
||||||
@@ -182,28 +186,32 @@ 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 name: String = "",
|
|
||||||
override val namespace: String = "",
|
|
||||||
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 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
|
||||||
) : ParcelableFlag<Int> {
|
) : ParcelableFlag<Int> {
|
||||||
@@ -218,20 +226,24 @@ 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 name: String = "",
|
|
||||||
override val namespace: String = "",
|
|
||||||
override val teamfood: Boolean = false
|
override val teamfood: Boolean = false
|
||||||
) : ResourceFlag<Int>
|
) : ResourceFlag<Int>
|
||||||
|
|
||||||
@@ -239,8 +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 name: String,
|
||||||
override val namespace: String = "",
|
override val namespace: String,
|
||||||
override val overridden: Boolean = false
|
override val overridden: Boolean = false
|
||||||
) : ParcelableFlag<Long> {
|
) : ParcelableFlag<Long> {
|
||||||
|
|
||||||
@@ -254,20 +266,24 @@ 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 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
|
||||||
) : ParcelableFlag<Float> {
|
) : ParcelableFlag<Float> {
|
||||||
@@ -282,29 +298,33 @@ 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 name: String = "",
|
|
||||||
override val namespace: String = "",
|
|
||||||
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 name: String = "",
|
|
||||||
override val namespace: String = "",
|
|
||||||
override val overridden: Boolean = false
|
override val overridden: Boolean = false
|
||||||
) : ParcelableFlag<Double> {
|
) : ParcelableFlag<Double> {
|
||||||
|
|
||||||
@@ -318,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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -168,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()) {
|
||||||
|
|||||||
@@ -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,24 +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)
|
@JvmField val NEW_ELLIPSE_DETECTION = unreleasedFlag(214, "new_ellipse_detection")
|
||||||
|
|
||||||
@JvmField val NEW_UDFPS_OVERLAY = UnreleasedFlag(215)
|
@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.
|
||||||
@@ -144,134 +156,152 @@ 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(216, 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
|
// TODO(b/244064524): Tracking Bug
|
||||||
@JvmField val QS_SECONDARY_DATA_SUB_INFO = UnreleasedFlag(508, teamfood = true)
|
@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 =
|
||||||
UnreleasedFlag(
|
unreleasedFlag(
|
||||||
1102,
|
1102,
|
||||||
name = "record_task_content",
|
name = "record_task_content",
|
||||||
namespace = DeviceConfig.NAMESPACE_WINDOW_MANAGER,
|
namespace = DeviceConfig.NAMESPACE_WINDOW_MANAGER,
|
||||||
@@ -281,135 +311,101 @@ object Flags {
|
|||||||
// 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
|
// 1600 - accessibility
|
||||||
@JvmField val A11Y_FLOATING_MENU_FLING_SPRING_ANIMATIONS = UnreleasedFlag(1600)
|
@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
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -57,21 +57,32 @@ import org.mockito.Mockito.`when` as whenever
|
|||||||
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, teamfood = true)
|
private val teamfoodableFlagA = UnreleasedFlag(
|
||||||
private val teamfoodableFlagB = ReleasedFlag(501, teamfood = 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() {
|
||||||
@@ -91,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()
|
||||||
@@ -106,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
|
||||||
@@ -160,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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,21 +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,
|
||||||
|
"d",
|
||||||
|
"test",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).isFalse()
|
||||||
|
assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(5, "e", "test"))).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
|
||||||
@@ -213,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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,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
|
||||||
@@ -253,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())
|
||||||
@@ -288,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(
|
||||||
@@ -307,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}")
|
||||||
@@ -327,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\"}")
|
||||||
@@ -339,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
|
||||||
@@ -361,7 +451,7 @@ 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.namespace, flag.name, false)
|
serverFlagReader.setFlagValue(flag.namespace, flag.name, false)
|
||||||
|
|
||||||
@@ -370,7 +460,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@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.namespace, flag.name, true)
|
serverFlagReader.setFlagValue(flag.namespace, flag.name, true)
|
||||||
|
|
||||||
@@ -379,13 +469,13 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@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")
|
||||||
|
|||||||
@@ -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,14 +73,16 @@ 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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,16 +90,17 @@ class FeatureFlagsReleaseTest : SysuiTestCase() {
|
|||||||
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.namespace, flag.name, false)
|
serverFlagReader.setFlagValue(flag.namespace, flag.name, false)
|
||||||
|
|
||||||
@@ -104,7 +109,7 @@ class FeatureFlagsReleaseTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun serverSide_OverridesUnreleased_Ignored() {
|
fun serverSide_OverridesUnreleased_Ignored() {
|
||||||
val flag = UnreleasedFlag(100)
|
val flag = UnreleasedFlag(100, "100", "test")
|
||||||
|
|
||||||
serverFlagReader.setFlagValue(flag.namespace, flag.name, true)
|
serverFlagReader.setFlagValue(flag.namespace, flag.name, true)
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user