Loading quickstep/src/com/android/launcher3/uioverrides/TogglableFlag.java 0 → 100644 +32 −0 Original line number Diff line number Diff line /* * 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); } } robolectric_tests/src/com/android/launcher3/config/FlagOverrideRule.java +5 −3 Original line number Diff line number Diff line 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; Loading Loading @@ -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?"); Loading @@ -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; Loading @@ -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()); } } Loading src/com/android/launcher3/config/BaseFlags.java +13 −61 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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") Loading Loading @@ -124,7 +118,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); } } Loading @@ -140,27 +134,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); } } Loading @@ -170,14 +164,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(); Loading Loading @@ -221,7 +217,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())); Loading @@ -241,48 +237,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; } } } src/com/android/launcher3/config/FlagTogglerPrefUi.java +6 −5 Original line number Diff line number Diff line Loading @@ -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}. Loading Loading @@ -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); } Loading @@ -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()); Loading @@ -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())); Loading Loading @@ -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()); } Loading src_ui_overrides/com/android/launcher3/uioverrides/TogglableFlag.java 0 → 100644 +31 −0 Original line number Diff line number Diff line /* * 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
quickstep/src/com/android/launcher3/uioverrides/TogglableFlag.java 0 → 100644 +32 −0 Original line number Diff line number Diff line /* * 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); } }
robolectric_tests/src/com/android/launcher3/config/FlagOverrideRule.java +5 −3 Original line number Diff line number Diff line 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; Loading Loading @@ -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?"); Loading @@ -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; Loading @@ -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()); } } Loading
src/com/android/launcher3/config/BaseFlags.java +13 −61 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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") Loading Loading @@ -124,7 +118,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); } } Loading @@ -140,27 +134,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); } } Loading @@ -170,14 +164,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(); Loading Loading @@ -221,7 +217,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())); Loading @@ -241,48 +237,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; } } }
src/com/android/launcher3/config/FlagTogglerPrefUi.java +6 −5 Original line number Diff line number Diff line Loading @@ -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}. Loading Loading @@ -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); } Loading @@ -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()); Loading @@ -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())); Loading Loading @@ -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()); } Loading
src_ui_overrides/com/android/launcher3/uioverrides/TogglableFlag.java 0 → 100644 +31 −0 Original line number Diff line number Diff line /* * 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; } }