Make TogglableFlag backed by DeviceConfig for e2e testing
Bug: 138964490 TL;DR;; need this to be part of QQ1 or QD1 to verify if DeviceConfig can be supported for launcher toggleableFlags. Not handled in this CL: - When flag is locally modified, that will override the flag value How that scenario is handled should be discussed separately and is not within scope of this CL. Change-Id: I2e6694a40bee9202ed0b0d559e3b5607634071bf
This commit is contained in:
parent
1b0445dfa4
commit
d4204437de
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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.launcher3.uioverrides;
|
||||
|
||||
import android.provider.DeviceConfig;
|
||||
import com.android.launcher3.config.BaseFlags.BaseTogglableFlag;
|
||||
|
||||
public class TogglableFlag extends BaseTogglableFlag {
|
||||
|
||||
public TogglableFlag(String key, boolean defaultValue, String description) {
|
||||
super(key, defaultValue, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getInitialValue(boolean value) {
|
||||
return DeviceConfig.getBoolean("launcher", getKey(), value);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package com.android.launcher3.config;
|
||||
|
||||
|
||||
import com.android.launcher3.config.BaseFlags.BaseTogglableFlag;
|
||||
import com.android.launcher3.uioverrides.TogglableFlag;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
@ -70,7 +72,7 @@ public final class FlagOverrideRule implements TestRule {
|
|||
};
|
||||
}
|
||||
|
||||
private void override(BaseFlags.TogglableFlag flag, boolean newValue) {
|
||||
private void override(BaseTogglableFlag flag, boolean newValue) {
|
||||
if (!ruleInProgress) {
|
||||
throw new IllegalStateException(
|
||||
"Rule isn't in progress. Did you remember to mark it with @Rule?");
|
||||
|
@ -93,7 +95,7 @@ public final class FlagOverrideRule implements TestRule {
|
|||
|
||||
private void applyAnnotation(FlagOverride flagOverride) {
|
||||
boolean found = false;
|
||||
for (BaseFlags.TogglableFlag flag : FeatureFlags.getTogglableFlags()) {
|
||||
for (TogglableFlag flag : FeatureFlags.getTogglableFlags()) {
|
||||
if (flag.getKey().equals(flagOverride.key())) {
|
||||
override(flag, flagOverride.value());
|
||||
found = true;
|
||||
|
@ -109,7 +111,7 @@ public final class FlagOverrideRule implements TestRule {
|
|||
* Resets all flags to their default values.
|
||||
*/
|
||||
private void clearOverrides() {
|
||||
for (BaseFlags.TogglableFlag flag : FeatureFlags.getTogglableFlags()) {
|
||||
for (BaseTogglableFlag flag : FeatureFlags.getTogglableFlags()) {
|
||||
flag.setForTests(flag.getDefaultValue());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,20 +18,16 @@ package com.android.launcher3.config;
|
|||
|
||||
import static androidx.core.util.Preconditions.checkNotNull;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.GuardedBy;
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import com.android.launcher3.Utilities;
|
||||
|
||||
import com.android.launcher3.uioverrides.TogglableFlag;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.SortedMap;
|
||||
|
@ -41,11 +37,9 @@ import java.util.TreeMap;
|
|||
* Defines a set of flags used to control various launcher behaviors.
|
||||
*
|
||||
* <p>All the flags should be defined here with appropriate default values.
|
||||
*
|
||||
* <p>This class is kept package-private to prevent direct access.
|
||||
*/
|
||||
@Keep
|
||||
abstract class BaseFlags {
|
||||
public abstract class BaseFlags {
|
||||
|
||||
private static final Object sLock = new Object();
|
||||
@GuardedBy("sLock")
|
||||
|
@ -116,7 +110,7 @@ abstract class BaseFlags {
|
|||
// Avoid the disk read for user builds
|
||||
if (Utilities.IS_DEBUG_DEVICE) {
|
||||
synchronized (sLock) {
|
||||
for (TogglableFlag flag : sFlags) {
|
||||
for (BaseTogglableFlag flag : sFlags) {
|
||||
flag.initialize(context);
|
||||
}
|
||||
}
|
||||
|
@ -132,27 +126,27 @@ abstract class BaseFlags {
|
|||
SortedMap<String, TogglableFlag> flagsByKey = new TreeMap<>();
|
||||
synchronized (sLock) {
|
||||
for (TogglableFlag flag : sFlags) {
|
||||
flagsByKey.put(flag.key, flag);
|
||||
flagsByKey.put(((BaseTogglableFlag) flag).getKey(), flag);
|
||||
}
|
||||
}
|
||||
return new ArrayList<>(flagsByKey.values());
|
||||
}
|
||||
|
||||
public static class TogglableFlag {
|
||||
public static abstract class BaseTogglableFlag {
|
||||
private final String key;
|
||||
private final boolean defaultValue;
|
||||
private final String description;
|
||||
private boolean currentValue;
|
||||
|
||||
TogglableFlag(
|
||||
public BaseTogglableFlag(
|
||||
String key,
|
||||
boolean defaultValue,
|
||||
String description) {
|
||||
this.key = checkNotNull(key);
|
||||
this.currentValue = this.defaultValue = defaultValue;
|
||||
this.currentValue = this.defaultValue = getInitialValue(defaultValue);
|
||||
this.description = checkNotNull(description);
|
||||
synchronized (sLock) {
|
||||
sFlags.add(this);
|
||||
sFlags.add((TogglableFlag)this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,14 +156,16 @@ abstract class BaseFlags {
|
|||
currentValue = value;
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
void initialize(Context context) {
|
||||
currentValue = getFromStorage(context, defaultValue);
|
||||
}
|
||||
|
||||
protected abstract boolean getInitialValue(boolean value);
|
||||
|
||||
public void updateStorage(Context context, boolean value) {
|
||||
SharedPreferences.Editor editor = context.getSharedPreferences(FLAGS_PREF_NAME,
|
||||
Context.MODE_PRIVATE).edit();
|
||||
|
@ -213,7 +209,7 @@ abstract class BaseFlags {
|
|||
return true;
|
||||
}
|
||||
if (o instanceof TogglableFlag) {
|
||||
TogglableFlag that = (TogglableFlag) o;
|
||||
BaseTogglableFlag that = (BaseTogglableFlag) o;
|
||||
return (this.key.equals(that.getKey()))
|
||||
&& (this.defaultValue == that.getDefaultValue())
|
||||
&& (this.description.equals(that.getDescription()));
|
||||
|
@ -233,48 +229,4 @@ abstract class BaseFlags {
|
|||
return h$;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the FeatureFlag's value in Settings.Global instead of our SharedPrefs.
|
||||
* This is useful if we want to be able to control this flag from another process.
|
||||
*/
|
||||
public static final class ToggleableGlobalSettingsFlag extends TogglableFlag {
|
||||
private ContentResolver contentResolver;
|
||||
|
||||
ToggleableGlobalSettingsFlag(String key, boolean defaultValue, String description) {
|
||||
super(key, defaultValue, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(Context context) {
|
||||
contentResolver = context.getContentResolver();
|
||||
contentResolver.registerContentObserver(Settings.Global.getUriFor(getKey()), true,
|
||||
new ContentObserver(new Handler(Looper.getMainLooper())) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
superInitialize(context);
|
||||
}});
|
||||
superInitialize(context);
|
||||
}
|
||||
|
||||
private void superInitialize(Context context) {
|
||||
super.initialize(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStorage(Context context, boolean value) {
|
||||
if (contentResolver == null) {
|
||||
return;
|
||||
}
|
||||
Settings.Global.putInt(contentResolver, getKey(), value ? 1 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean getFromStorage(Context context, boolean defaultValue) {
|
||||
if (contentResolver == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return Settings.Global.getInt(contentResolver, getKey(), defaultValue ? 1 : 0) == 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,12 +26,13 @@ import android.view.MenuItem;
|
|||
import android.widget.Toast;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.config.BaseFlags.TogglableFlag;
|
||||
|
||||
import androidx.preference.PreferenceDataStore;
|
||||
import androidx.preference.PreferenceFragment;
|
||||
import androidx.preference.PreferenceGroup;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import com.android.launcher3.config.BaseFlags.BaseTogglableFlag;
|
||||
import com.android.launcher3.uioverrides.TogglableFlag;
|
||||
|
||||
/**
|
||||
* Dev-build only UI allowing developers to toggle flag settings. See {@link FeatureFlags}.
|
||||
|
@ -62,7 +63,7 @@ public final class FlagTogglerPrefUi {
|
|||
|
||||
@Override
|
||||
public boolean getBoolean(String key, boolean defaultValue) {
|
||||
for (TogglableFlag flag : FeatureFlags.getTogglableFlags()) {
|
||||
for (BaseTogglableFlag flag : FeatureFlags.getTogglableFlags()) {
|
||||
if (flag.getKey().equals(key)) {
|
||||
return flag.getFromStorage(mContext, defaultValue);
|
||||
}
|
||||
|
@ -83,7 +84,7 @@ public final class FlagTogglerPrefUi {
|
|||
// flag with a different value than the default. That way, when we flip flags in
|
||||
// future, engineers will pick up the new value immediately. To accomplish this, we use a
|
||||
// custom preference data store.
|
||||
for (TogglableFlag flag : FeatureFlags.getTogglableFlags()) {
|
||||
for (BaseTogglableFlag flag : FeatureFlags.getTogglableFlags()) {
|
||||
SwitchPreference switchPreference = new SwitchPreference(mContext);
|
||||
switchPreference.setKey(flag.getKey());
|
||||
switchPreference.setDefaultValue(flag.getDefaultValue());
|
||||
|
@ -99,7 +100,7 @@ public final class FlagTogglerPrefUi {
|
|||
/**
|
||||
* Updates the summary to show the description and whether the flag overrides the default value.
|
||||
*/
|
||||
private void updateSummary(SwitchPreference switchPreference, TogglableFlag flag) {
|
||||
private void updateSummary(SwitchPreference switchPreference, BaseTogglableFlag flag) {
|
||||
String onWarning = flag.getDefaultValue() ? "" : "<b>OVERRIDDEN</b><br>";
|
||||
String offWarning = flag.getDefaultValue() ? "<b>OVERRIDDEN</b><br>" : "";
|
||||
switchPreference.setSummaryOn(Html.fromHtml(onWarning + flag.getDescription()));
|
||||
|
@ -134,7 +135,7 @@ public final class FlagTogglerPrefUi {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean getFlagStateFromSharedPrefs(TogglableFlag flag) {
|
||||
private boolean getFlagStateFromSharedPrefs(BaseTogglableFlag flag) {
|
||||
return mDataStore.getBoolean(flag.getKey(), flag.getDefaultValue());
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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.launcher3.uioverrides;
|
||||
|
||||
import com.android.launcher3.config.BaseFlags.BaseTogglableFlag;
|
||||
|
||||
public class TogglableFlag extends BaseTogglableFlag {
|
||||
|
||||
public TogglableFlag(String key, boolean defaultValue, String description) {
|
||||
super(key, defaultValue, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getInitialValue(boolean value) {
|
||||
return value;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue