Merge "Add SensitiveNotificationProtectionLog" into main
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 cc3729b..8b7c85b 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -119,6 +119,16 @@
         return factory.create("LSShadeTransitionLog", 50);
     }
 
+    /** */
+    @Provides
+    @SysUISingleton
+    @SensitiveNotificationProtectionLog
+    public static LogBuffer provideSensitiveNotificationProtectionLogBuffer(
+            LogBufferFactory factory
+    ) {
+        return factory.create("SensitiveNotificationProtectionLog", 10);
+    }
+
     /** Provides a logging buffer for shade window messages. */
     @Provides
     @SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/SensitiveNotificationProtectionLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/SensitiveNotificationProtectionLog.kt
new file mode 100644
index 0000000..54e87cd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/SensitiveNotificationProtectionLog.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2024 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 javax.inject.Qualifier
+
+/** A [com.android.systemui.log.LogBuffer] for SensitiveNotificationProtection. */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class SensitiveNotificationProtectionLog
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java
index 6956a7d..18ec68b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java
@@ -51,6 +51,7 @@
 public class SensitiveNotificationProtectionControllerImpl
         implements SensitiveNotificationProtectionController {
     private static final String LOG_TAG = "SNPC";
+    private final SensitiveNotificationProtectionControllerLogger mLogger;
     private final ArraySet<String> mExemptPackages = new ArraySet<>();
     private final ListenerSet<Runnable> mListeners = new ListenerSet<>();
     private volatile MediaProjectionInfo mProjection;
@@ -66,6 +67,7 @@
                         if (mDisableScreenShareProtections) {
                             Log.w(LOG_TAG,
                                     "Screen share protections disabled, ignoring projectionstart");
+                            mLogger.logProjectionStart(false, info.getPackageName());
                             return;
                         }
 
@@ -73,6 +75,7 @@
                         // Launch cookie only set (non-null) if sharing single app/task
                         updateProjectionStateAndNotifyListeners(
                                 (info.getLaunchCookie() == null) ? info : null);
+                        mLogger.logProjectionStart(isSensitiveStateActive(), info.getPackageName());
                     } finally {
                         Trace.endSection();
                     }
@@ -82,6 +85,7 @@
                 public void onStop(MediaProjectionInfo info) {
                     Trace.beginSection("SNPC.onProjectionStop");
                     try {
+                        mLogger.logProjectionStop();
                         updateProjectionStateAndNotifyListeners(null);
                     } finally {
                         Trace.endSection();
@@ -96,7 +100,10 @@
             MediaProjectionManager mediaProjectionManager,
             IActivityManager activityManager,
             @Main Handler mainHandler,
-            @Background Executor bgExecutor) {
+            @Background Executor bgExecutor,
+            SensitiveNotificationProtectionControllerLogger logger) {
+        mLogger = logger;
+
         if (!screenshareNotificationHiding()) {
             return;
         }
@@ -202,8 +209,6 @@
             return false;
         }
 
-        // TODO(b/316955558): Add disabled by developer option
-
         return !mExemptPackages.contains(projection.getPackageName());
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerLogger.kt
new file mode 100644
index 0000000..70c5239
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerLogger.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2024 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.statusbar.policy
+
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.log.dagger.SensitiveNotificationProtectionLog
+import javax.inject.Inject
+
+/** Logger for [SensitiveNotificationProtectionController]. */
+class SensitiveNotificationProtectionControllerLogger
+@Inject
+constructor(@SensitiveNotificationProtectionLog private val buffer: LogBuffer) {
+    fun logProjectionStart(protectionEnabled: Boolean, pkg: String) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                bool1 = protectionEnabled
+                str1 = pkg
+            },
+            { "Projection started - protection enabled:$bool1, pkg=$str1" }
+        )
+    }
+
+    fun logProjectionStop() {
+        buffer.log(TAG, LogLevel.DEBUG, {}, { "Projection ended - protection disabled" })
+    }
+}
+
+private const val TAG = "SNPC"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt
index 7592356..933b5b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt
@@ -24,6 +24,7 @@
 import androidx.test.filters.SmallTest
 import com.android.server.notification.Flags
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.log.logcatLogBuffer
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.settings.FakeGlobalSettings
 import com.android.systemui.util.time.FakeSystemClock
@@ -38,6 +39,8 @@
 @RunWith(AndroidTestingRunner::class)
 @DisableFlags(Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING)
 class SensitiveNotificationProtectionControllerFlagDisabledTest : SysuiTestCase() {
+    private val logger = SensitiveNotificationProtectionControllerLogger(logcatLogBuffer())
+
     @Mock private lateinit var handler: Handler
     @Mock private lateinit var activityManager: IActivityManager
     @Mock private lateinit var mediaProjectionManager: MediaProjectionManager
@@ -54,7 +57,8 @@
                 mediaProjectionManager,
                 activityManager,
                 handler,
-                FakeExecutor(FakeSystemClock())
+                FakeExecutor(FakeSystemClock()),
+                logger
             )
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt
index a2af38f..4b4e315 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt
@@ -34,6 +34,7 @@
 import androidx.test.filters.SmallTest
 import com.android.server.notification.Flags
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.log.logcatLogBuffer
 import com.android.systemui.statusbar.RankingBuilder
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
@@ -63,6 +64,8 @@
 @RunWithLooper
 @EnableFlags(Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING)
 class SensitiveNotificationProtectionControllerTest : SysuiTestCase() {
+    private val logger = SensitiveNotificationProtectionControllerLogger(logcatLogBuffer())
+
     @Mock private lateinit var activityManager: IActivityManager
     @Mock private lateinit var mediaProjectionManager: MediaProjectionManager
     @Mock private lateinit var mediaProjectionInfo: MediaProjectionInfo
@@ -93,7 +96,8 @@
                 mediaProjectionManager,
                 activityManager,
                 mockExecutorHandler(executor),
-                executor
+                executor,
+                logger
             )
 
         // Process pending work (getting global setting and list of exemptions)