Merge "Add DeviceConfig feature flag type to SystemUI" into tm-qpr-dev

This commit is contained in:
Nick Chameyev
2022-06-10 15:57:17 +00:00
committed by Android (Google) Code Review
7 changed files with 102 additions and 1 deletions

View File

@@ -36,6 +36,12 @@ interface ResourceFlag<T> : Flag<T> {
val resourceId: Int
}
interface DeviceConfigFlag<T> : Flag<T> {
val name: String
val namespace: String
val default: T
}
interface SysPropFlag<T> : Flag<T> {
val name: String
val default: T
@@ -74,6 +80,14 @@ data class ResourceBooleanFlag @JvmOverloads constructor(
override val teamfood: Boolean = false
) : ResourceFlag<Boolean>
data class DeviceConfigBooleanFlag @JvmOverloads constructor(
override val id: Int,
override val name: String,
override val namespace: String,
override val default: Boolean = false,
override val teamfood: Boolean = false
) : DeviceConfigFlag<Boolean>
data class SysPropBooleanFlag @JvmOverloads constructor(
override val id: Int,
override val name: String,

View File

@@ -28,6 +28,9 @@ interface FeatureFlags : FlagListenable {
/** Returns a boolean value for the given flag. */
fun isEnabled(flag: ResourceBooleanFlag): Boolean
/** Returns a boolean value for the given flag. */
fun isEnabled(flag: DeviceConfigBooleanFlag): Boolean
/** Returns a boolean value for the given flag. */
fun isEnabled(flag: SysPropBooleanFlag): Boolean

View File

@@ -32,6 +32,7 @@ import android.content.res.Resources;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.util.Log;
import androidx.annotation.NonNull;
@@ -44,6 +45,7 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.statusbar.commandline.Command;
import com.android.systemui.statusbar.commandline.CommandRegistry;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.settings.SecureSettings;
import java.io.PrintWriter;
@@ -81,6 +83,7 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable {
private final SecureSettings mSecureSettings;
private final Resources mResources;
private final SystemPropertiesHelper mSystemProperties;
private final DeviceConfigProxy mDeviceConfigProxy;
private final Map<Integer, Flag<?>> mAllFlags;
private final Map<Integer, Boolean> mBooleanFlagCache = new TreeMap<>();
private final Map<Integer, String> mStringFlagCache = new TreeMap<>();
@@ -94,6 +97,7 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable {
SystemPropertiesHelper systemProperties,
@Main Resources resources,
DumpManager dumpManager,
DeviceConfigProxy deviceConfigProxy,
@Named(ALL_FLAGS) Map<Integer, Flag<?>> allFlags,
CommandRegistry commandRegistry,
IStatusBarService barService) {
@@ -101,6 +105,7 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable {
mSecureSettings = secureSettings;
mResources = resources;
mSystemProperties = systemProperties;
mDeviceConfigProxy = deviceConfigProxy;
mAllFlags = allFlags;
mBarService = barService;
@@ -137,6 +142,18 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable {
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);
}
@Override
public boolean isEnabled(@NonNull SysPropBooleanFlag flag) {
int id = flag.getId();
@@ -293,6 +310,8 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable {
setFlagValue(flag.getId(), value, BooleanFlagSerializer.INSTANCE);
} else if (flag instanceof ResourceBooleanFlag) {
setFlagValue(flag.getId(), value, BooleanFlagSerializer.INSTANCE);
} else if (flag instanceof DeviceConfigBooleanFlag) {
setFlagValue(flag.getId(), value, BooleanFlagSerializer.INSTANCE);
} else if (flag instanceof SysPropBooleanFlag) {
// Store SysProp flags in SystemProperties where they can read by outside parties.
mSystemProperties.setBoolean(((SysPropBooleanFlag) flag).getName(), value);
@@ -394,6 +413,10 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable {
return new BooleanFlag(
f.getId(), isEnabled((ResourceBooleanFlag) f), f.getTeamfood());
}
if (f instanceof DeviceConfigBooleanFlag) {
return new BooleanFlag(
f.getId(), isEnabled((DeviceConfigBooleanFlag) f), f.getTeamfood());
}
if (f instanceof SysPropBooleanFlag) {
// TODO(b/223379190): Teamfood not supported for sysprop flags yet.
return new BooleanFlag(

View File

@@ -19,6 +19,7 @@ package com.android.systemui.flags;
import static java.util.Objects.requireNonNull;
import android.content.res.Resources;
import android.provider.DeviceConfig;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -28,6 +29,7 @@ import com.android.systemui.Dumpable;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.util.DeviceConfigProxy;
import java.io.PrintWriter;
import java.util.Map;
@@ -44,6 +46,7 @@ import javax.inject.Inject;
public class FeatureFlagsRelease implements FeatureFlags, Dumpable {
private final Resources mResources;
private final SystemPropertiesHelper mSystemProperties;
private final DeviceConfigProxy mDeviceConfigProxy;
SparseBooleanArray mBooleanCache = new SparseBooleanArray();
SparseArray<String> mStringCache = new SparseArray<>();
@@ -51,9 +54,11 @@ public class FeatureFlagsRelease implements FeatureFlags, Dumpable {
public FeatureFlagsRelease(
@Main Resources resources,
SystemPropertiesHelper systemProperties,
DeviceConfigProxy deviceConfigProxy,
DumpManager dumpManager) {
mResources = resources;
mSystemProperties = systemProperties;
mDeviceConfigProxy = deviceConfigProxy;
dumpManager.registerDumpable("SysUIFlags", this);
}
@@ -78,6 +83,18 @@ public class FeatureFlagsRelease implements FeatureFlags, Dumpable {
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
public boolean isEnabled(SysPropBooleanFlag flag) {
int cacheIndex = mBooleanCache.indexOfKey(flag.getId());

View File

@@ -16,6 +16,8 @@
package com.android.systemui.flags;
import static android.provider.DeviceConfig.NAMESPACE_WINDOW_MANAGER;
import com.android.internal.annotations.Keep;
import com.android.systemui.R;
@@ -173,6 +175,11 @@ public class Flags {
public static final SysPropBooleanFlag BUBBLES_HOME_GESTURE =
new SysPropBooleanFlag(1101, "persist.wm.debug.bubbles_home_gesture", true);
@Keep
public static final DeviceConfigBooleanFlag WM_ENABLE_PARTIAL_SCREEN_SHARING =
new DeviceConfigBooleanFlag(1102, "record_task_content",
NAMESPACE_WINDOW_MANAGER, false, true);
// 1200 - predictive back
@Keep
public static final SysPropBooleanFlag WM_ENABLE_PREDICTIVE_BACK = new SysPropBooleanFlag(

View File

@@ -26,6 +26,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.util.DeviceConfigProxyFake
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.capture
@@ -75,6 +76,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
private lateinit var broadcastReceiver: BroadcastReceiver
private lateinit var clearCacheAction: Consumer<Int>
private val deviceConfig = DeviceConfigProxyFake()
private val teamfoodableFlagA = BooleanFlag(500, false, true)
private val teamfoodableFlagB = BooleanFlag(501, true, true)
@@ -90,6 +92,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
systemProperties,
resources,
dumpManager,
deviceConfig,
flagMap,
commandRegistry,
barService
@@ -194,6 +197,21 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(5, "e"))).isFalse()
}
@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(mFeatureFlagsDebug.isEnabled(DeviceConfigBooleanFlag(1, "a", namespace)))
.isTrue()
assertThat(mFeatureFlagsDebug.isEnabled(DeviceConfigBooleanFlag(2, "b", namespace)))
.isFalse()
assertThat(mFeatureFlagsDebug.isEnabled(DeviceConfigBooleanFlag(3, "c", namespace)))
.isFalse()
}
@Test
fun testReadStringFlag() {
whenever(flagManager.readFlagValue<String>(eq(3), any())).thenReturn("foo")

View File

@@ -20,6 +20,7 @@ import android.content.res.Resources
import android.test.suitebuilder.annotation.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.util.DeviceConfigProxyFake
import com.android.systemui.util.mockito.any
import com.google.common.truth.Truth.assertThat
import org.junit.After
@@ -44,10 +45,13 @@ class FeatureFlagsReleaseTest : SysuiTestCase() {
@Mock private lateinit var mSystemProperties: SystemPropertiesHelper
@Mock private lateinit var mDumpManager: DumpManager
private val deviceConfig = DeviceConfigProxyFake()
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
mFeatureFlagsRelease = FeatureFlagsRelease(mResources, mSystemProperties, mDumpManager)
mFeatureFlagsRelease = FeatureFlagsRelease(mResources, mSystemProperties, deviceConfig,
mDumpManager)
}
@After
@@ -84,6 +88,21 @@ class FeatureFlagsReleaseTest : SysuiTestCase() {
}
}
@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
fun testSysPropBooleanFlag() {
val flagId = 213