Make FeatureFlagManager Dumpable

Also direct developers who find FeatureFlagManager in the src/ tree to the src-debug/ version

Fixes: 204127880
Bug: 203904245
Test: adb shell dumpsys activity service com.android.systemui
Test: FeatureFlagManagerTest
Merged-In: I6a42a697120179048e848f7f432fd753db514b9c
Change-Id: I5bec46e60befaa1890b9ff4d4bb5e89b0ebba256
diff --git a/packages/SystemUI/src-debug/com/android/systemui/flags/FeatureFlagManager.java b/packages/SystemUI/src-debug/com/android/systemui/flags/FeatureFlagManager.java
index 5b6845f..3a8ee29 100644
--- a/packages/SystemUI/src-debug/com/android/systemui/flags/FeatureFlagManager.java
+++ b/packages/SystemUI/src-debug/com/android/systemui/flags/FeatureFlagManager.java
@@ -23,11 +23,18 @@
 import android.os.Bundle;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
+
+import com.android.systemui.Dumpable;
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dump.DumpManager;
 
 import org.json.JSONException;
 import org.json.JSONObject;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -43,7 +50,7 @@
  * To restore a flag back to its default, leave the `--ez value <0|1>` off of the command.
  */
 @SysUISingleton
-public class FeatureFlagManager implements FlagReader, FlagWriter {
+public class FeatureFlagManager implements FlagReader, FlagWriter, Dumpable {
     private static final String TAG = "SysUIFlags";
 
     private static final String SYSPROP_PREFIX = "persist.systemui.flag_";
@@ -58,11 +65,13 @@
     private final Map<Integer, Boolean> mBooleanFlagCache = new HashMap<>();
 
     @Inject
-    public FeatureFlagManager(SystemPropertiesHelper systemPropertiesHelper, Context context) {
+    public FeatureFlagManager(SystemPropertiesHelper systemPropertiesHelper, Context context,
+            DumpManager dumpManager) {
         mSystemPropertiesHelper = systemPropertiesHelper;
 
         IntentFilter filter = new IntentFilter(ACTION_SET_FLAG);
         context.registerReceiver(mReceiver, filter, FLAGS_PERMISSION, null);
+        dumpManager.registerDumpable(TAG, this);
     }
 
     /** Return a {@link BooleanFlag}'s value. */
@@ -186,4 +195,16 @@
             }
         }
     };
+
+    @Override
+    public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
+        ArrayList<String> flagStrings = new ArrayList<>(mBooleanFlagCache.size());
+        for (Map.Entry<Integer, Boolean> entry : mBooleanFlagCache.entrySet()) {
+            flagStrings.add("  sysui_flag_" + entry.getKey() + ": " + entry.getValue());
+        }
+        flagStrings.sort(String.CASE_INSENSITIVE_ORDER);
+        for (String flagString : flagStrings) {
+            pw.println(flagString);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagManager.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagManager.java
index 85baed4..78f0b5f 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagManager.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagManager.java
@@ -16,23 +16,48 @@
 
 package com.android.systemui.flags;
 
+import android.util.SparseBooleanArray;
+
+import androidx.annotation.NonNull;
+
+import com.android.systemui.Dumpable;
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dump.DumpManager;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 
 import javax.inject.Inject;
 
 /**
  * Default implementation of the a Flag manager that returns default values for release builds
+ *
+ * There's a version of this file in src-debug which allows overriding, and has documentation about
+ * how to set flags.
  */
 @SysUISingleton
-public class FeatureFlagManager implements FlagReader, FlagWriter {
+public class FeatureFlagManager implements FlagReader, FlagWriter, Dumpable {
+    SparseBooleanArray mAccessedFlags = new SparseBooleanArray();
     @Inject
-    public FeatureFlagManager() {}
+    public FeatureFlagManager(DumpManager dumpManager) {
+        dumpManager.registerDumpable("SysUIFlags", this);
+    }
     public boolean isEnabled(String key, boolean defaultValue) {
         return defaultValue;
     }
     public boolean isEnabled(int key, boolean defaultValue) {
+        mAccessedFlags.append(key, defaultValue);
         return defaultValue;
     }
     public void setEnabled(String key, boolean value) {}
     public void setEnabled(int key, boolean value) {}
+
+    @Override
+    public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
+        int size = mAccessedFlags.size();
+        for (int i = 0; i < size; i++) {
+            pw.println("  sysui_flag_" + mAccessedFlags.keyAt(i)
+                    + ": " + mAccessedFlags.valueAt(i));
+        }
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagManagerTest.java
index 172dcda..b3c098c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagManagerTest.java
@@ -18,23 +18,35 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dump.DumpManager;
 
 import org.junit.Before;
 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 FeatureFlagManagerTest extends SysuiTestCase {
     FeatureFlagManager mFeatureFlagManager;
 
+    @Mock private DumpManager mDumpManager;
+
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
 
-        mFeatureFlagManager = new FeatureFlagManager();
+        mFeatureFlagManager = new FeatureFlagManager(mDumpManager);
     }
 
     @Test
@@ -43,4 +55,31 @@
         // Again, nothing changes.
         assertThat(mFeatureFlagManager.isEnabled(1, false)).isFalse();
     }
+
+    @Test
+    public void testDump() {
+        // Even if a flag is set before
+        mFeatureFlagManager.setEnabled(1, true);
+
+        // WHEN the flags have been accessed
+        assertFalse(mFeatureFlagManager.isEnabled(1, false));
+        assertTrue(mFeatureFlagManager.isEnabled(2, true));
+
+        // Even if a flag is set after
+        mFeatureFlagManager.setEnabled(2, false);
+
+        // THEN the dump contains the flags and the default values
+        String dump = dumpToString();
+        assertThat(dump).contains(" sysui_flag_1: false\n");
+        assertThat(dump).contains(" sysui_flag_2: true\n");
+    }
+
+    private String dumpToString() {
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        mFeatureFlagManager.dump(mock(FileDescriptor.class), pw, new String[0]);
+        pw.flush();
+        String dump = sw.toString();
+        return dump;
+    }
 }