Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d08226f authored by Dave Mankoff's avatar Dave Mankoff Committed by Android (Google) Code Review
Browse files

Merge "Move contents of FeatureFlags into FeatureFlagManager." into sc-v2-dev

parents 35b8e2b9 5346e090
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -19,6 +19,11 @@ package com.android.systemui.flags
 * Plugin for loading flag values
 */
interface FlagReader {
    /** Returns a boolean value for the given flag.  */
    fun isEnabled(flag: BooleanFlag): Boolean {
        return flag.default
    }

    /** Returns a boolean value for the given flag.  */
    fun isEnabled(id: Int, def: Boolean): Boolean {
        return def
+33 −6
Original line number Diff line number Diff line
@@ -26,13 +26,16 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
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;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.util.settings.SecureSettings;

@@ -62,14 +65,19 @@ public class FeatureFlagManager implements FlagReader, FlagWriter, Dumpable {

    private final FlagManager mFlagManager;
    private final SecureSettings mSecureSettings;
    private final Resources mResources;
    private final Map<Integer, Boolean> mBooleanFlagCache = new HashMap<>();

    @Inject
    public FeatureFlagManager(FlagManager flagManager,
            SecureSettings secureSettings, Context context,
    public FeatureFlagManager(
            FlagManager flagManager,
            Context context,
            SecureSettings secureSettings,
            @Main Resources resources,
            DumpManager dumpManager) {
        mFlagManager = flagManager;
        mSecureSettings = secureSettings;
        mResources = resources;
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_SET_FLAG);
        filter.addAction(ACTION_GET_FLAGS);
@@ -77,17 +85,32 @@ public class FeatureFlagManager implements FlagReader, FlagWriter, Dumpable {
        dumpManager.registerDumpable(TAG, this);
    }

    /** Return a {@link BooleanFlag}'s value. */
    @Override
    public boolean isEnabled(int id, boolean defaultValue) {
    public boolean isEnabled(BooleanFlag flag) {
        int id = flag.getId();
        if (!mBooleanFlagCache.containsKey(id)) {
            Boolean result = isEnabledInternal(id);
            mBooleanFlagCache.put(id, result == null ? defaultValue : result);
            boolean def = flag.getDefault();
            if (flag.hasResourceOverride()) {
                try {
                    def = isEnabledInOverlay(flag.getResourceOverride());
                } catch (Resources.NotFoundException e) {
                    // no-op
                }
            }

            mBooleanFlagCache.put(id, isEnabled(id, def));
        }

        return mBooleanFlagCache.get(id);
    }

    /** Return a {@link BooleanFlag}'s value. */
    @Override
    public boolean isEnabled(int id, boolean defaultValue) {
        Boolean result = isEnabledInternal(id);
        return result == null ? defaultValue : result;
    }

    /** Returns the stored value or null if not set. */
    private Boolean isEnabledInternal(int id) {
        try {
@@ -98,6 +121,10 @@ public class FeatureFlagManager implements FlagReader, FlagWriter, Dumpable {
        return null;
    }

    private boolean isEnabledInOverlay(@BoolRes int resId) {
        return mResources.getBoolean(resId);
    }

    /** Set whether a given {@link BooleanFlag} is enabled or not. */
    @Override
    public void setEnabled(int id, boolean value) {
+6 −4
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.systemui.flags;

import android.content.Context;
import android.util.SparseBooleanArray;

import androidx.annotation.NonNull;
@@ -24,7 +23,6 @@ import androidx.annotation.NonNull;
import com.android.systemui.Dumpable;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.util.settings.SecureSettings;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -41,8 +39,7 @@ import javax.inject.Inject;
public class FeatureFlagManager implements FlagReader, FlagWriter, Dumpable {
    SparseBooleanArray mAccessedFlags = new SparseBooleanArray();
    @Inject
    public FeatureFlagManager(
            SecureSettings secureSettings, Context context, DumpManager dumpManager) {
    public FeatureFlagManager(DumpManager dumpManager) {
        dumpManager.registerDumpable("SysUIFlags", this);
    }

@@ -52,6 +49,11 @@ public class FeatureFlagManager implements FlagReader, FlagWriter, Dumpable {
    @Override
    public void removeListener(Listener run) {}

    @Override
    public boolean isEnabled(BooleanFlag flag) {
        return isEnabled(flag.getId(), flag.getDefault());
    }

    @Override
    public boolean isEnabled(int key, boolean defaultValue) {
        mAccessedFlags.append(key, defaultValue);
+2 −72
Original line number Diff line number Diff line
@@ -17,22 +17,11 @@
package com.android.systemui.flags;

import android.content.Context;
import android.content.res.Resources;
import android.util.FeatureFlagUtils;
import android.util.Log;
import android.util.SparseArray;
import android.widget.Toast;

import androidx.annotation.BoolRes;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

@@ -43,31 +32,13 @@ import javax.inject.Inject;
 */
@SysUISingleton
public class FeatureFlags {
    private final Resources mResources;
    private final FlagReader mFlagReader;
    private final Context mContext;
    private final Map<Integer, Flag<?>> mFlagMap = new HashMap<>();
    private final Map<Integer, List<Listener>> mListeners = new HashMap<>();
    private final SparseArray<Boolean> mCachedFlags = new SparseArray<>();

    @Inject
    public FeatureFlags(@Main Resources resources, FlagReader flagReader, Context context) {
        mResources = resources;
    public FeatureFlags(FlagReader flagReader, Context context) {
        mFlagReader = flagReader;
        mContext = context;

        flagReader.addListener(mListener);
    }

    private final FlagReader.Listener mListener = id -> {
        if (mListeners.containsKey(id) && mFlagMap.containsKey(id)) {
            mListeners.get(id).forEach(listener -> listener.onFlagChanged(mFlagMap.get(id)));
        }
    };

    @VisibleForTesting
    void addFlag(Flag<?> flag) {
        mFlagMap.put(flag.getId(), flag);
    }

    /**
@@ -75,32 +46,7 @@ public class FeatureFlags {
     * @return The value of the flag.
     */
    public boolean isEnabled(BooleanFlag flag) {
        boolean def = flag.getDefault();
        if (flag.hasResourceOverride()) {
            try {
                def = isEnabledInOverlay(flag.getResourceOverride());
            } catch (Resources.NotFoundException e) {
                // no-op
            }
        }
        return mFlagReader.isEnabled(flag.getId(), def);
    }

    /**
     * @param flag The {@link IntFlag} of interest.

    /** Add a listener for a specific flag. */
    public void addFlagListener(Flag<?> flag, Listener listener) {
        mListeners.putIfAbsent(flag.getId(), new ArrayList<>());
        mListeners.get(flag.getId()).add(listener);
        mFlagMap.putIfAbsent(flag.getId(), flag);
    }

    /** Remove a listener for a specific flag. */
    public void removeFlagListener(Flag<?> flag, Listener listener) {
        if (mListeners.containsKey(flag.getId())) {
            mListeners.get(flag.getId()).remove(listener);
        }
        return mFlagReader.isEnabled(flag);
    }

    public void assertLegacyPipelineEnabled() {
@@ -205,20 +151,4 @@ public class FeatureFlags {
    public static boolean isProviderModelSettingEnabled(Context context) {
        return FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL);
    }

    private boolean isEnabledInOverlay(@BoolRes int resId) {
        synchronized (mCachedFlags) {
            if (!mCachedFlags.contains(resId)) {
                mCachedFlags.put(resId, mResources.getBoolean(resId));
            }

            return mCachedFlags.get(resId);
        }
    }

    /** Simple interface for beinga alerted when a specific flag changes value. */
    public interface Listener {
        /** */
        void onFlagChanged(Flag<?> flag);
    }
}
+1 −6
Original line number Diff line number Diff line
@@ -53,8 +53,6 @@ import java.io.StringWriter;
public class FeatureFlagManagerTest extends SysuiTestCase {
    FeatureFlagManager mFeatureFlagManager;

    @Mock private FlagManager mFlagManager;
    @Mock private SecureSettings mSecureSettings;
    @Mock private Context mContext;
    @Mock private DumpManager mDumpManager;

@@ -62,14 +60,11 @@ public class FeatureFlagManagerTest extends SysuiTestCase {
    public void setup() {
        MockitoAnnotations.initMocks(this);

        mFeatureFlagManager = new FeatureFlagManager(mSecureSettings, mContext, mDumpManager);
        mFeatureFlagManager = new FeatureFlagManager(mDumpManager);
    }

    @After
    public void onFinished() {
        // SecureSettings and Context are provided for constructor consistency with the
        // debug version of the FeatureFlagManager, but should never be used.
        verifyZeroInteractions(mSecureSettings, mContext);
        // The dump manager should be registered with even for the release version, but that's it.
        verify(mDumpManager).registerDumpable(anyString(), any());
        verifyNoMoreInteractions(mDumpManager);
Loading