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

Commit 295ea3e7 authored by Jeff DeCew's avatar Jeff DeCew
Browse files

Make FeatureFlags a Dumpable

Test: atest FeatureFlagReaderTest#testDump
Test: adb shell dumpsys activity service com.android.systemui | grep -A20 FeatureFlag
Change-Id: Ic5f58758d97f1d8623d312c3ccbff2f03bff91e4
parent 4813785c
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -21,16 +21,23 @@ import android.content.res.Resources;
import android.util.SparseArray;

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

import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.FlagReaderPlugin;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.util.wrapper.BuildInfo;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;

import javax.inject.Inject;
/**
 * Reads and caches feature flags for quick access
@@ -55,7 +62,7 @@ import javax.inject.Inject;
 * Calls to this class should probably be wrapped by a method in {@link FeatureFlags}.
 */
@SysUISingleton
public class FeatureFlagReader {
public class FeatureFlagReader implements Dumpable {
    private final Resources mResources;
    private final boolean mAreFlagsOverrideable;
    private final PluginManager mPluginManager;
@@ -68,6 +75,7 @@ public class FeatureFlagReader {
    public FeatureFlagReader(
            @Main Resources resources,
            BuildInfo build,
            DumpManager dumpManager,
            PluginManager pluginManager,
            SystemPropertiesHelper systemPropertiesHelper) {
        mResources = resources;
@@ -76,6 +84,7 @@ public class FeatureFlagReader {
        mAreFlagsOverrideable =
                build.isDebuggable() && mResources.getBoolean(R.bool.are_flags_overrideable);

        dumpManager.registerDumpable("FeatureFlags", this);
        mPluginManager.addPluginListener(mPluginListener, FlagReaderPlugin.class);
    }

@@ -172,6 +181,23 @@ public class FeatureFlagReader {
        }
    }

    @Override
    public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
        ArrayList<String> flagStrings = new ArrayList<>(mCachedFlags.size());
        for (int i = 0; i < mCachedFlags.size(); i++) {
            int key = mCachedFlags.keyAt(i);
            // get the object by the key.
            CachedFlag flag = mCachedFlags.get(key);
            flagStrings.add("  " + RESNAME_PREFIX + flag.name + ": " + flag.value + "\n");
        }
        flagStrings.sort(String.CASE_INSENSITIVE_ORDER);
        pw.println("AreFlagsOverrideable: " + mAreFlagsOverrideable);
        pw.println("Cached FeatureFlags:");
        for (String flagString : flagStrings) {
            pw.print(flagString);
        }
    }

    private static class CachedFlag {
        public final String name;
        public final boolean value;
+35 −2
Original line number Diff line number Diff line
@@ -16,11 +16,14 @@

package com.android.systemui.flags;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -32,6 +35,7 @@ import androidx.test.filters.SmallTest;

import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.util.wrapper.BuildInfo;

@@ -40,10 +44,15 @@ import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.StringWriter;

@SmallTest
public class FeatureFlagReaderTest extends SysuiTestCase {
    @Mock private Resources mResources;
    @Mock private BuildInfo mBuildInfo;
    @Mock private DumpManager mDumpManager;
    @Mock private PluginManager mPluginManager;
    @Mock private SystemPropertiesHelper mSystemPropertiesHelper;

@@ -66,7 +75,7 @@ public class FeatureFlagReaderTest extends SysuiTestCase {
        when(mBuildInfo.isDebuggable()).thenReturn(isDebuggable);
        when(mResources.getBoolean(R.bool.are_flags_overrideable)).thenReturn(isOverrideable);
        mReader = new FeatureFlagReader(
                mResources, mBuildInfo, mPluginManager, mSystemPropertiesHelper);
                mResources, mBuildInfo, mDumpManager, mPluginManager, mSystemPropertiesHelper);
    }

    @Test
@@ -127,9 +136,29 @@ public class FeatureFlagReaderTest extends SysuiTestCase {
                .getBoolean(fakeStorageKey(FLAG_RESID_0), false);
    }

    @Test
    public void testDump() {
        // GIVEN that the flag 0 (by override) and 1 (by default) are both true
        overrideFlag(FLAG_RESID_0, true);

        // WHEN the flags have been accessed
        assertTrue(mReader.isEnabled(FLAG_RESID_0));
        assertTrue(mReader.isEnabled(FLAG_RESID_1));

        // THEN the dump contains the flags and their correct values
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        mReader.dump(mock(FileDescriptor.class), pw, new String[0]);
        pw.flush();
        String dump = sw.toString();
        assertThat(dump).contains(" flag_testname_" + FLAG_RESID_0 + ": true\n");
        assertThat(dump).contains(" flag_testname_" + FLAG_RESID_1 + ": true\n");
        assertThat(dump).contains("AreFlagsOverrideable: true\n");
    }

    private void defineFlag(int resId, boolean value) {
        when(mResources.getBoolean(resId)).thenReturn(value);
        when(mResources.getResourceEntryName(resId)).thenReturn(fakeStorageKey(resId));
        when(mResources.getResourceEntryName(resId)).thenReturn(fakeResourceEntryName(resId));
    }

    private void overrideFlag(int resId, boolean value) {
@@ -137,6 +166,10 @@ public class FeatureFlagReaderTest extends SysuiTestCase {
                .thenReturn(value);
    }

    private String fakeResourceEntryName(@BoolRes int resId) {
        return "flag_testname_" + resId;
    }

    private String fakeStorageKey(@BoolRes int resId) {
        return "persist.systemui.flag_testname_" + resId;
    }