Loading packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt +42 −24 Original line number Diff line number Diff line Loading @@ -16,28 +16,31 @@ package com.android.systemui.flags import android.annotation.BoolRes import android.annotation.IntegerRes import android.annotation.StringRes import android.os.Parcel import android.os.Parcelable interface Flag<T> : Parcelable { interface Flag<T> { val id: Int val default: T val resourceOverride: Int } interface ParcelableFlag<T> : Flag<T>, Parcelable { val default: T override fun describeContents() = 0 fun hasResourceOverride(): Boolean { return resourceOverride != -1 } interface ResourceFlag<T> : Flag<T> { val resourceId: Int } // Consider using the "parcelize" kotlin library. data class BooleanFlag @JvmOverloads constructor( override val id: Int, override val default: Boolean = false, override val resourceOverride: Int = -1 ) : Flag<Boolean> { override val default: Boolean = false ) : ParcelableFlag<Boolean> { companion object { @JvmField Loading @@ -58,11 +61,15 @@ data class BooleanFlag @JvmOverloads constructor( } } data class ResourceBooleanFlag constructor( override val id: Int, @BoolRes override val resourceId: Int ) : ResourceFlag<Boolean> data class StringFlag @JvmOverloads constructor( override val id: Int, override val default: String = "", override val resourceOverride: Int = -1 ) : Flag<String> { override val default: String = "" ) : ParcelableFlag<String> { companion object { @JvmField val CREATOR = object : Parcelable.Creator<StringFlag> { Loading @@ -82,11 +89,15 @@ data class StringFlag @JvmOverloads constructor( } } data class ResourceStringFlag constructor( override val id: Int, @StringRes override val resourceId: Int ) : ResourceFlag<String> data class IntFlag @JvmOverloads constructor( override val id: Int, override val default: Int = 0, override val resourceOverride: Int = -1 ) : Flag<Int> { override val default: Int = 0 ) : ParcelableFlag<Int> { companion object { @JvmField Loading @@ -107,11 +118,15 @@ data class IntFlag @JvmOverloads constructor( } } data class ResourceIntFlag constructor( override val id: Int, @IntegerRes override val resourceId: Int ) : ResourceFlag<Int> data class LongFlag @JvmOverloads constructor( override val id: Int, override val default: Long = 0, override val resourceOverride: Int = -1 ) : Flag<Long> { override val default: Long = 0 ) : ParcelableFlag<Long> { companion object { @JvmField Loading @@ -134,9 +149,8 @@ data class LongFlag @JvmOverloads constructor( data class FloatFlag @JvmOverloads constructor( override val id: Int, override val default: Float = 0f, override val resourceOverride: Int = -1 ) : Flag<Float> { override val default: Float = 0f ) : ParcelableFlag<Float> { companion object { @JvmField Loading @@ -157,11 +171,15 @@ data class FloatFlag @JvmOverloads constructor( } } data class ResourceFloatFlag constructor( override val id: Int, override val resourceId: Int ) : ResourceFlag<Int> data class DoubleFlag @JvmOverloads constructor( override val id: Int, override val default: Double = 0.0, override val resourceOverride: Int = -1 ) : Flag<Double> { override val default: Double = 0.0 ) : ParcelableFlag<Double> { companion object { @JvmField Loading packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt +5 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ class FlagManager constructor( object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val extras: Bundle? = getResultExtras(false) val listOfFlags: java.util.ArrayList<Flag<*>>? = val listOfFlags: java.util.ArrayList<ParcelableFlag<*>>? = extras?.getParcelableArrayList(FIELD_FLAGS) if (listOfFlags != null) { completer.set(listOfFlags) Loading Loading @@ -108,6 +108,10 @@ class FlagManager constructor( } } override fun isEnabled(flag: ResourceBooleanFlag): Boolean { throw RuntimeException("Not implemented in FlagManager") } override fun addListener(listener: FlagReader.Listener) { synchronized(listeners) { val registerNeeded = listeners.isEmpty() Loading packages/SystemUI/shared/src/com/android/systemui/flags/FlagReader.kt +2 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ interface FlagReader { return flag.default } fun isEnabled(flag: ResourceBooleanFlag): Boolean /** Returns a boolean value for the given flag. */ fun isEnabled(id: Int, def: Boolean): Boolean { return def Loading packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java +43 −15 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static com.android.systemui.flags.FlagManager.FIELD_FLAGS; import static com.android.systemui.flags.FlagManager.FIELD_ID; import static com.android.systemui.flags.FlagManager.FIELD_VALUE; import android.annotation.Nullable; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; Loading @@ -30,7 +31,6 @@ import android.content.res.Resources; import android.os.Bundle; import android.util.Log; import androidx.annotation.BoolRes; import androidx.annotation.NonNull; import com.android.systemui.Dumpable; Loading Loading @@ -89,16 +89,18 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { public boolean isEnabled(BooleanFlag flag) { int id = flag.getId(); if (!mBooleanFlagCache.containsKey(id)) { boolean def = flag.getDefault(); if (flag.hasResourceOverride()) { try { def = isEnabledInOverlay(flag.getResourceOverride()); } catch (Resources.NotFoundException e) { // no-op mBooleanFlagCache.put(id, isEnabled(id, flag.getDefault())); } return mBooleanFlagCache.get(id); } mBooleanFlagCache.put(id, isEnabled(id, def)); @Override public boolean isEnabled(ResourceBooleanFlag flag) { int id = flag.getId(); if (!mBooleanFlagCache.containsKey(id)) { mBooleanFlagCache.put( id, isEnabled(id, mResources.getBoolean(flag.getResourceId()))); } return mBooleanFlagCache.get(id); Loading @@ -111,6 +113,7 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { return result == null ? defaultValue : result; } /** Returns the stored value or null if not set. */ private Boolean isEnabledInternal(int id) { try { Loading @@ -121,10 +124,6 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { return null; } private boolean isEnabledInOverlay(@BoolRes int resId) { return mResources.getBoolean(resId); } /** Set whether a given {@link BooleanFlag} is enabled or not. */ public void setEnabled(int id, boolean value) { Boolean currentValue = isEnabledInternal(id); Loading Loading @@ -185,9 +184,19 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { } else if (ACTION_GET_FLAGS.equals(action)) { Map<Integer, Flag<?>> knownFlagMap = Flags.collectFlags(); ArrayList<Flag<?>> flags = new ArrayList<>(knownFlagMap.values()); // Convert all flags to parcelable flags. ArrayList<ParcelableFlag<?>> pFlags = new ArrayList<>(); for (Flag<?> f : flags) { ParcelableFlag<?> pf = toParcelableFlag(f); if (pf != null) { pFlags.add(pf); } } Bundle extras = getResultExtras(true); if (extras != null) { extras.putParcelableArrayList(FIELD_FLAGS, flags); extras.putParcelableArrayList(FIELD_FLAGS, pFlags); } } } Loading Loading @@ -215,6 +224,25 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { setEnabled(id, extras.getBoolean(FIELD_VALUE)); } } /** * Ensures that the data we send to the app reflects the current state of the flags. * * Also converts an non-parcelable versions of the flags to their parcelable versions. */ @Nullable private ParcelableFlag<?> toParcelableFlag(Flag<?> f) { if (f instanceof BooleanFlag) { return new BooleanFlag(f.getId(), isEnabled((BooleanFlag) f)); } if (f instanceof ResourceBooleanFlag) { return new BooleanFlag(f.getId(), isEnabled((ResourceBooleanFlag) f)); } // TODO: add support for other flag types. Log.w(TAG, "Unsupported Flag Type. Please file a bug."); return null; } }; @Override Loading packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java +20 −6 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package com.android.systemui.flags; import android.content.res.Resources; import android.util.SparseBooleanArray; import androidx.annotation.NonNull; 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 java.io.FileDescriptor; Loading @@ -37,9 +39,11 @@ import javax.inject.Inject; */ @SysUISingleton public class FeatureFlagsRelease implements FeatureFlags, Dumpable { SparseBooleanArray mAccessedFlags = new SparseBooleanArray(); private final Resources mResources; SparseBooleanArray mFlagCache = new SparseBooleanArray(); @Inject public FeatureFlagsRelease(DumpManager dumpManager) { public FeatureFlagsRelease(@Main Resources resources, DumpManager dumpManager) { mResources = resources; dumpManager.registerDumpable("SysUIFlags", this); } Loading @@ -54,19 +58,29 @@ public class FeatureFlagsRelease implements FeatureFlags, Dumpable { return isEnabled(flag.getId(), flag.getDefault()); } @Override public boolean isEnabled(ResourceBooleanFlag flag) { int cacheIndex = mFlagCache.indexOfKey(flag.getId()); if (cacheIndex < 0) { return isEnabled(flag.getId(), mResources.getBoolean(flag.getResourceId())); } return mFlagCache.valueAt(cacheIndex); } @Override public boolean isEnabled(int key, boolean defaultValue) { mAccessedFlags.append(key, defaultValue); mFlagCache.append(key, defaultValue); return defaultValue; } @Override public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) { pw.println("can override: false"); int size = mAccessedFlags.size(); int size = mFlagCache.size(); for (int i = 0; i < size; i++) { pw.println(" sysui_flag_" + mAccessedFlags.keyAt(i) + ": " + mAccessedFlags.valueAt(i)); pw.println(" sysui_flag_" + mFlagCache.keyAt(i) + ": " + mFlagCache.valueAt(i)); } } } Loading
packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt +42 −24 Original line number Diff line number Diff line Loading @@ -16,28 +16,31 @@ package com.android.systemui.flags import android.annotation.BoolRes import android.annotation.IntegerRes import android.annotation.StringRes import android.os.Parcel import android.os.Parcelable interface Flag<T> : Parcelable { interface Flag<T> { val id: Int val default: T val resourceOverride: Int } interface ParcelableFlag<T> : Flag<T>, Parcelable { val default: T override fun describeContents() = 0 fun hasResourceOverride(): Boolean { return resourceOverride != -1 } interface ResourceFlag<T> : Flag<T> { val resourceId: Int } // Consider using the "parcelize" kotlin library. data class BooleanFlag @JvmOverloads constructor( override val id: Int, override val default: Boolean = false, override val resourceOverride: Int = -1 ) : Flag<Boolean> { override val default: Boolean = false ) : ParcelableFlag<Boolean> { companion object { @JvmField Loading @@ -58,11 +61,15 @@ data class BooleanFlag @JvmOverloads constructor( } } data class ResourceBooleanFlag constructor( override val id: Int, @BoolRes override val resourceId: Int ) : ResourceFlag<Boolean> data class StringFlag @JvmOverloads constructor( override val id: Int, override val default: String = "", override val resourceOverride: Int = -1 ) : Flag<String> { override val default: String = "" ) : ParcelableFlag<String> { companion object { @JvmField val CREATOR = object : Parcelable.Creator<StringFlag> { Loading @@ -82,11 +89,15 @@ data class StringFlag @JvmOverloads constructor( } } data class ResourceStringFlag constructor( override val id: Int, @StringRes override val resourceId: Int ) : ResourceFlag<String> data class IntFlag @JvmOverloads constructor( override val id: Int, override val default: Int = 0, override val resourceOverride: Int = -1 ) : Flag<Int> { override val default: Int = 0 ) : ParcelableFlag<Int> { companion object { @JvmField Loading @@ -107,11 +118,15 @@ data class IntFlag @JvmOverloads constructor( } } data class ResourceIntFlag constructor( override val id: Int, @IntegerRes override val resourceId: Int ) : ResourceFlag<Int> data class LongFlag @JvmOverloads constructor( override val id: Int, override val default: Long = 0, override val resourceOverride: Int = -1 ) : Flag<Long> { override val default: Long = 0 ) : ParcelableFlag<Long> { companion object { @JvmField Loading @@ -134,9 +149,8 @@ data class LongFlag @JvmOverloads constructor( data class FloatFlag @JvmOverloads constructor( override val id: Int, override val default: Float = 0f, override val resourceOverride: Int = -1 ) : Flag<Float> { override val default: Float = 0f ) : ParcelableFlag<Float> { companion object { @JvmField Loading @@ -157,11 +171,15 @@ data class FloatFlag @JvmOverloads constructor( } } data class ResourceFloatFlag constructor( override val id: Int, override val resourceId: Int ) : ResourceFlag<Int> data class DoubleFlag @JvmOverloads constructor( override val id: Int, override val default: Double = 0.0, override val resourceOverride: Int = -1 ) : Flag<Double> { override val default: Double = 0.0 ) : ParcelableFlag<Double> { companion object { @JvmField Loading
packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt +5 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ class FlagManager constructor( object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val extras: Bundle? = getResultExtras(false) val listOfFlags: java.util.ArrayList<Flag<*>>? = val listOfFlags: java.util.ArrayList<ParcelableFlag<*>>? = extras?.getParcelableArrayList(FIELD_FLAGS) if (listOfFlags != null) { completer.set(listOfFlags) Loading Loading @@ -108,6 +108,10 @@ class FlagManager constructor( } } override fun isEnabled(flag: ResourceBooleanFlag): Boolean { throw RuntimeException("Not implemented in FlagManager") } override fun addListener(listener: FlagReader.Listener) { synchronized(listeners) { val registerNeeded = listeners.isEmpty() Loading
packages/SystemUI/shared/src/com/android/systemui/flags/FlagReader.kt +2 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ interface FlagReader { return flag.default } fun isEnabled(flag: ResourceBooleanFlag): Boolean /** Returns a boolean value for the given flag. */ fun isEnabled(id: Int, def: Boolean): Boolean { return def Loading
packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java +43 −15 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static com.android.systemui.flags.FlagManager.FIELD_FLAGS; import static com.android.systemui.flags.FlagManager.FIELD_ID; import static com.android.systemui.flags.FlagManager.FIELD_VALUE; import android.annotation.Nullable; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; Loading @@ -30,7 +31,6 @@ import android.content.res.Resources; import android.os.Bundle; import android.util.Log; import androidx.annotation.BoolRes; import androidx.annotation.NonNull; import com.android.systemui.Dumpable; Loading Loading @@ -89,16 +89,18 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { public boolean isEnabled(BooleanFlag flag) { int id = flag.getId(); if (!mBooleanFlagCache.containsKey(id)) { boolean def = flag.getDefault(); if (flag.hasResourceOverride()) { try { def = isEnabledInOverlay(flag.getResourceOverride()); } catch (Resources.NotFoundException e) { // no-op mBooleanFlagCache.put(id, isEnabled(id, flag.getDefault())); } return mBooleanFlagCache.get(id); } mBooleanFlagCache.put(id, isEnabled(id, def)); @Override public boolean isEnabled(ResourceBooleanFlag flag) { int id = flag.getId(); if (!mBooleanFlagCache.containsKey(id)) { mBooleanFlagCache.put( id, isEnabled(id, mResources.getBoolean(flag.getResourceId()))); } return mBooleanFlagCache.get(id); Loading @@ -111,6 +113,7 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { return result == null ? defaultValue : result; } /** Returns the stored value or null if not set. */ private Boolean isEnabledInternal(int id) { try { Loading @@ -121,10 +124,6 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { return null; } private boolean isEnabledInOverlay(@BoolRes int resId) { return mResources.getBoolean(resId); } /** Set whether a given {@link BooleanFlag} is enabled or not. */ public void setEnabled(int id, boolean value) { Boolean currentValue = isEnabledInternal(id); Loading Loading @@ -185,9 +184,19 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { } else if (ACTION_GET_FLAGS.equals(action)) { Map<Integer, Flag<?>> knownFlagMap = Flags.collectFlags(); ArrayList<Flag<?>> flags = new ArrayList<>(knownFlagMap.values()); // Convert all flags to parcelable flags. ArrayList<ParcelableFlag<?>> pFlags = new ArrayList<>(); for (Flag<?> f : flags) { ParcelableFlag<?> pf = toParcelableFlag(f); if (pf != null) { pFlags.add(pf); } } Bundle extras = getResultExtras(true); if (extras != null) { extras.putParcelableArrayList(FIELD_FLAGS, flags); extras.putParcelableArrayList(FIELD_FLAGS, pFlags); } } } Loading Loading @@ -215,6 +224,25 @@ public class FeatureFlagsDebug implements FeatureFlags, Dumpable { setEnabled(id, extras.getBoolean(FIELD_VALUE)); } } /** * Ensures that the data we send to the app reflects the current state of the flags. * * Also converts an non-parcelable versions of the flags to their parcelable versions. */ @Nullable private ParcelableFlag<?> toParcelableFlag(Flag<?> f) { if (f instanceof BooleanFlag) { return new BooleanFlag(f.getId(), isEnabled((BooleanFlag) f)); } if (f instanceof ResourceBooleanFlag) { return new BooleanFlag(f.getId(), isEnabled((ResourceBooleanFlag) f)); } // TODO: add support for other flag types. Log.w(TAG, "Unsupported Flag Type. Please file a bug."); return null; } }; @Override Loading
packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java +20 −6 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package com.android.systemui.flags; import android.content.res.Resources; import android.util.SparseBooleanArray; import androidx.annotation.NonNull; 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 java.io.FileDescriptor; Loading @@ -37,9 +39,11 @@ import javax.inject.Inject; */ @SysUISingleton public class FeatureFlagsRelease implements FeatureFlags, Dumpable { SparseBooleanArray mAccessedFlags = new SparseBooleanArray(); private final Resources mResources; SparseBooleanArray mFlagCache = new SparseBooleanArray(); @Inject public FeatureFlagsRelease(DumpManager dumpManager) { public FeatureFlagsRelease(@Main Resources resources, DumpManager dumpManager) { mResources = resources; dumpManager.registerDumpable("SysUIFlags", this); } Loading @@ -54,19 +58,29 @@ public class FeatureFlagsRelease implements FeatureFlags, Dumpable { return isEnabled(flag.getId(), flag.getDefault()); } @Override public boolean isEnabled(ResourceBooleanFlag flag) { int cacheIndex = mFlagCache.indexOfKey(flag.getId()); if (cacheIndex < 0) { return isEnabled(flag.getId(), mResources.getBoolean(flag.getResourceId())); } return mFlagCache.valueAt(cacheIndex); } @Override public boolean isEnabled(int key, boolean defaultValue) { mAccessedFlags.append(key, defaultValue); mFlagCache.append(key, defaultValue); return defaultValue; } @Override public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) { pw.println("can override: false"); int size = mAccessedFlags.size(); int size = mFlagCache.size(); for (int i = 0; i < size; i++) { pw.println(" sysui_flag_" + mAccessedFlags.keyAt(i) + ": " + mAccessedFlags.valueAt(i)); pw.println(" sysui_flag_" + mFlagCache.keyAt(i) + ": " + mFlagCache.valueAt(i)); } } }