Merge "[Disable Flags Logging] Add logging for QSFragment, since it locally modifies the disable flags." into sc-v2-dev
diff --git a/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt b/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
index c1db8ed..9e00381 100644
--- a/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
@@ -61,7 +61,7 @@
  *
  * @param name The name of this buffer
  * @param maxLogs The maximum number of messages to keep in memory at any one time, including the
- * unused pool.
+ * unused pool. Must be >= [poolSize].
  * @param poolSize The maximum amount that the size of the buffer is allowed to flex in response to
  * sequential calls to [document] that aren't immediately followed by a matching call to [push].
  */
@@ -71,6 +71,13 @@
     private val poolSize: Int,
     private val logcatEchoTracker: LogcatEchoTracker
 ) {
+    init {
+        if (maxLogs < poolSize) {
+            throw IllegalArgumentException("maxLogs must be greater than or equal to poolSize, " +
+                    "but maxLogs=$maxLogs < $poolSize=poolSize")
+        }
+    }
+
     private val buffer: ArrayDeque<LogMessageImpl> = ArrayDeque()
 
     var frozen = false
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index 72601e9..46e2274 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -112,6 +112,17 @@
     }
 
     /**
+     * Provides a logging buffer for logs related to {@link com.android.systemui.qs.QSFragment}'s
+     * disable flag adjustments.
+     */
+    @Provides
+    @SysUISingleton
+    @QSFragmentDisableLog
+    public static LogBuffer provideQSFragmentDisableLogBuffer(LogBufferFactory factory) {
+        return factory.create("QSFragmentDisableFlagsLog", 10);
+    }
+
+    /**
      * Provides a logging buffer for logs related to swiping away the status bar while in immersive
      * mode. See {@link com.android.systemui.statusbar.gesture.SwipeStatusBarAwayGestureLogger}.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/QSFragmentDisableLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/QSFragmentDisableLog.java
new file mode 100644
index 0000000..557a254
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/QSFragmentDisableLog.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.android.systemui.log.LogBuffer;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+/**
+ * A {@link LogBuffer} for disable flag adjustments made in
+ * {@link com.android.systemui.qs.QSFragment}.
+ */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface QSFragmentDisableLog {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index eeca239..dd876b7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -15,6 +15,7 @@
 package com.android.systemui.qs;
 
 import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
+import static com.android.systemui.statusbar.DisableFlagsLogger.DisableState;
 
 import static com.android.systemui.media.dagger.MediaModule.QS_PANEL;
 import static com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL;
@@ -101,6 +102,7 @@
     private final MediaHost mQsMediaHost;
     private final MediaHost mQqsMediaHost;
     private final QSFragmentComponent.Factory mQsComponentFactory;
+    private final QSFragmentDisableFlagsLogger mQsFragmentDisableFlagsLogger;
     private final QSTileHost mHost;
     private boolean mShowCollapsedOnKeyguard;
     private boolean mLastKeyguardAndExpanded;
@@ -151,6 +153,7 @@
             @Named(QUICK_QS_PANEL) MediaHost qqsMediaHost,
             KeyguardBypassController keyguardBypassController,
             QSFragmentComponent.Factory qsComponentFactory,
+            QSFragmentDisableFlagsLogger qsFragmentDisableFlagsLogger,
             FalsingManager falsingManager, DumpManager dumpManager) {
         mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
         mCommandQueue = commandQueue;
@@ -158,6 +161,7 @@
         mQsMediaHost = qsMediaHost;
         mQqsMediaHost = qqsMediaHost;
         mQsComponentFactory = qsComponentFactory;
+        mQsFragmentDisableFlagsLogger = qsFragmentDisableFlagsLogger;
         commandQueue.observe(getLifecycle(), this);
         mHost = qsTileHost;
         mFalsingManager = falsingManager;
@@ -363,8 +367,14 @@
         if (displayId != getContext().getDisplayId()) {
             return;
         }
+        int state2BeforeAdjustment = state2;
         state2 = mRemoteInputQuickSettingsDisabler.adjustDisableFlags(state2);
 
+        mQsFragmentDisableFlagsLogger.logDisableFlagChange(
+                /* new= */ new DisableState(state1, state2BeforeAdjustment),
+                /* newAfterLocalModification= */ new DisableState(state1, state2)
+        );
+
         final boolean disabled = (state2 & DISABLE2_QUICK_SETTINGS) != 0;
         if (disabled == mQsDisabled) return;
         mQsDisabled = disabled;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragmentDisableFlagsLogger.kt b/packages/SystemUI/src/com/android/systemui/qs/QSFragmentDisableFlagsLogger.kt
new file mode 100644
index 0000000..17a815e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragmentDisableFlagsLogger.kt
@@ -0,0 +1,48 @@
+package com.android.systemui.qs
+
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogLevel
+import com.android.systemui.log.dagger.QSFragmentDisableLog
+import com.android.systemui.statusbar.DisableFlagsLogger
+import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment
+import javax.inject.Inject
+
+/** A helper class for logging disable flag changes made in [QSFragment]. */
+class QSFragmentDisableFlagsLogger @Inject constructor(
+    @QSFragmentDisableLog private val buffer: LogBuffer,
+    private val disableFlagsLogger: DisableFlagsLogger
+) {
+
+    /**
+     * Logs a string representing the new state received by [QSFragment] and any modifications that
+     * were made to the flags locally.
+     *
+     * @param new see [DisableFlagsLogger.getDisableFlagsString]
+     * @param newAfterLocalModification see [DisableFlagsLogger.getDisableFlagsString]
+     */
+    fun logDisableFlagChange(
+        new: DisableFlagsLogger.DisableState,
+        newAfterLocalModification: DisableFlagsLogger.DisableState
+    ) {
+        buffer.log(
+            TAG,
+            LogLevel.INFO,
+            {
+                int1 = new.disable1
+                int2 = new.disable2
+                long1 = newAfterLocalModification.disable1.toLong()
+                long2 = newAfterLocalModification.disable2.toLong()
+            },
+            {
+                disableFlagsLogger.getDisableFlagsString(
+                    old = null,
+                    new = DisableFlagsLogger.DisableState(int1, int2),
+                    newAfterLocalModification =
+                        DisableFlagsLogger.DisableState(long1.toInt(), long2.toInt())
+                )
+            }
+        )
+    }
+}
+
+private const val TAG = "QSFragmentDisableFlagsLog"
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentDisableFlagsLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentDisableFlagsLoggerTest.kt
new file mode 100644
index 0000000..e2c6ff9
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentDisableFlagsLoggerTest.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.log.LogBufferFactory
+import com.android.systemui.log.LogcatEchoTracker
+import com.android.systemui.statusbar.DisableFlagsLogger
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.mockito.Mockito.mock
+import java.io.PrintWriter
+import java.io.StringWriter
+
+@SmallTest
+class QSFragmentDisableFlagsLoggerTest : SysuiTestCase() {
+
+    private val buffer = LogBufferFactory(DumpManager(), mock(LogcatEchoTracker::class.java))
+        .create("buffer", 10)
+    private val disableFlagsLogger = DisableFlagsLogger(
+        listOf(DisableFlagsLogger.DisableFlag(0b001, 'A', 'a')),
+        listOf(DisableFlagsLogger.DisableFlag(0b001, 'B', 'b'))
+    )
+    private val logger = QSFragmentDisableFlagsLogger(buffer, disableFlagsLogger)
+
+    @Test
+    fun logDisableFlagChange_bufferHasStates() {
+        val state = DisableFlagsLogger.DisableState(0, 1)
+
+        logger.logDisableFlagChange(state, state)
+
+        val stringWriter = StringWriter()
+        buffer.dump(PrintWriter(stringWriter), tailLength = 0)
+        val actualString = stringWriter.toString()
+        val expectedLogString = disableFlagsLogger.getDisableFlagsString(
+            old = null, new = state, newAfterLocalModification = state
+        )
+
+        assertThat(actualString).contains(expectedLogString)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index c4bab73..30664ba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -183,6 +183,7 @@
                 mQQSMediaHost,
                 mBypassController,
                 mQsComponentFactory,
+                mock(QSFragmentDisableFlagsLogger.class),
                 mFalsingManager,
                 mock(DumpManager.class));
     }