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

Commit 5346e090 authored by Dave Mankoff's avatar Dave Mankoff
Browse files

Move contents of FeatureFlags into FeatureFlagManager.

The meaningful contents of FeatureFlags only relates to debug
builds and has been moved into the debug version of
FeatureFlagManager.

Bug: 203548872
Test: atest SystemUITests && manual
Change-Id: Ifcef0cfe4e2d07daec34dfc7a6cbe2d305b312b5
parent 3379ab41
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -19,6 +19,11 @@ package com.android.systemui.flags
 * Plugin for loading flag values
 * Plugin for loading flag values
 */
 */
interface FlagReader {
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.  */
    /** Returns a boolean value for the given flag.  */
    fun isEnabled(id: Int, def: Boolean): Boolean {
    fun isEnabled(id: Int, def: Boolean): Boolean {
        return def
        return def
+33 −6
Original line number Original line Diff line number Diff line
@@ -26,13 +26,16 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Bundle;
import android.util.Log;
import android.util.Log;


import androidx.annotation.BoolRes;
import androidx.annotation.NonNull;
import androidx.annotation.NonNull;


import com.android.systemui.Dumpable;
import com.android.systemui.Dumpable;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.settings.SecureSettings;


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


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


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


    /** Return a {@link BooleanFlag}'s value. */
    @Override
    @Override
    public boolean isEnabled(int id, boolean defaultValue) {
    public boolean isEnabled(BooleanFlag flag) {
        int id = flag.getId();
        if (!mBooleanFlagCache.containsKey(id)) {
        if (!mBooleanFlagCache.containsKey(id)) {
            Boolean result = isEnabledInternal(id);
            boolean def = flag.getDefault();
            mBooleanFlagCache.put(id, result == null ? defaultValue : result);
            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 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. */
    /** Returns the stored value or null if not set. */
    private Boolean isEnabledInternal(int id) {
    private Boolean isEnabledInternal(int id) {
        try {
        try {
@@ -98,6 +121,10 @@ public class FeatureFlagManager implements FlagReader, FlagWriter, Dumpable {
        return null;
        return null;
    }
    }


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

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


package com.android.systemui.flags;
package com.android.systemui.flags;


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


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


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


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


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

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


import android.content.Context;
import android.content.Context;
import android.content.res.Resources;
import android.util.FeatureFlagUtils;
import android.util.FeatureFlagUtils;
import android.util.Log;
import android.util.Log;
import android.util.SparseArray;
import android.widget.Toast;
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.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;
import javax.inject.Inject;


@@ -43,31 +32,13 @@ import javax.inject.Inject;
 */
 */
@SysUISingleton
@SysUISingleton
public class FeatureFlags {
public class FeatureFlags {
    private final Resources mResources;
    private final FlagReader mFlagReader;
    private final FlagReader mFlagReader;
    private final Context mContext;
    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
    @Inject
    public FeatureFlags(@Main Resources resources, FlagReader flagReader, Context context) {
    public FeatureFlags(FlagReader flagReader, Context context) {
        mResources = resources;
        mFlagReader = flagReader;
        mFlagReader = flagReader;
        mContext = context;
        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.
     * @return The value of the flag.
     */
     */
    public boolean isEnabled(BooleanFlag flag) {
    public boolean isEnabled(BooleanFlag flag) {
        boolean def = flag.getDefault();
        return mFlagReader.isEnabled(flag);
        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);
        }
    }
    }


    public void assertLegacyPipelineEnabled() {
    public void assertLegacyPipelineEnabled() {
@@ -205,20 +151,4 @@ public class FeatureFlags {
    public static boolean isProviderModelSettingEnabled(Context context) {
    public static boolean isProviderModelSettingEnabled(Context context) {
        return FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL);
        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 Original line Diff line number Diff line
@@ -53,8 +53,6 @@ import java.io.StringWriter;
public class FeatureFlagManagerTest extends SysuiTestCase {
public class FeatureFlagManagerTest extends SysuiTestCase {
    FeatureFlagManager mFeatureFlagManager;
    FeatureFlagManager mFeatureFlagManager;


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


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


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


    @After
    @After
    public void onFinished() {
    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.
        // The dump manager should be registered with even for the release version, but that's it.
        verify(mDumpManager).registerDumpable(anyString(), any());
        verify(mDumpManager).registerDumpable(anyString(), any());
        verifyNoMoreInteractions(mDumpManager);
        verifyNoMoreInteractions(mDumpManager);
Loading