diff options
| author | 2024-02-05 20:16:37 +0000 | |
|---|---|---|
| committer | 2024-02-05 20:16:37 +0000 | |
| commit | 0514919a557b704b091a881b5b3a9f616c8ef0b7 (patch) | |
| tree | acb67a2c5bc3d378b6af88cf8a90f9e2c50bcb4c | |
| parent | 18347dfddba7f40cdb1600c33f91c0d254e39d7c (diff) | |
| parent | ceb432951547159b58726eed514cdd25f2741ed5 (diff) | |
Merge "Add sensitive notification protection exemptions" into main
3 files changed, 272 insertions, 90 deletions
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 11e374f24f9c..d4c180df7442 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java @@ -18,25 +18,36 @@ package com.android.systemui.statusbar.policy; import static com.android.server.notification.Flags.screenshareNotificationHiding; +import android.annotation.MainThread; +import android.app.IActivityManager; +import android.content.Context; import android.media.projection.MediaProjectionInfo; import android.media.projection.MediaProjectionManager; import android.os.Handler; +import android.os.RemoteException; import android.os.Trace; import android.service.notification.StatusBarNotification; +import android.util.ArraySet; +import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.dagger.SysUISingleton; +import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.util.Assert; import com.android.systemui.util.ListenerSet; +import java.util.concurrent.Executor; + import javax.inject.Inject; /** Implementation of SensitiveNotificationProtectionController. **/ @SysUISingleton public class SensitiveNotificationProtectionControllerImpl implements SensitiveNotificationProtectionController { - private final MediaProjectionManager mMediaProjectionManager; + private static final String LOG_TAG = "SNPC"; + private final ArraySet<String> mExemptPackages = new ArraySet<>(); private final ListenerSet<Runnable> mListeners = new ListenerSet<>(); private volatile MediaProjectionInfo mProjection; @@ -45,44 +56,100 @@ public class SensitiveNotificationProtectionControllerImpl new MediaProjectionManager.Callback() { @Override public void onStart(MediaProjectionInfo info) { - Trace.beginSection( - "SNPC.onProjectionStart"); - // Only enable sensitive content protection if sharing full screen - // Launch cookie only set (non-null) if sharing single app/task - updateProjectionState((info.getLaunchCookie() == null) ? info : null); - Trace.endSection(); + Trace.beginSection("SNPC.onProjectionStart"); + try { + // Only enable sensitive content protection if sharing full screen + // Launch cookie only set (non-null) if sharing single app/task + updateProjectionStateAndNotifyListeners( + (info.getLaunchCookie() == null) ? info : null); + } finally { + Trace.endSection(); + } } @Override public void onStop(MediaProjectionInfo info) { - Trace.beginSection( - "SNPC.onProjectionStop"); - updateProjectionState(null); - Trace.endSection(); - } - - private void updateProjectionState(MediaProjectionInfo info) { - // capture previous state - boolean wasSensitive = isSensitiveStateActive(); - - // update internal state - mProjection = info; - - // if either previous or new state is sensitive, notify listeners. - if (wasSensitive || isSensitiveStateActive()) { - mListeners.forEach(Runnable::run); + Trace.beginSection("SNPC.onProjectionStop"); + try { + updateProjectionStateAndNotifyListeners(null); + } finally { + Trace.endSection(); } } }; @Inject public SensitiveNotificationProtectionControllerImpl( + Context context, MediaProjectionManager mediaProjectionManager, - @Main Handler mainHandler) { - mMediaProjectionManager = mediaProjectionManager; + IActivityManager activityManager, + @Main Handler mainHandler, + @Background Executor bgExecutor) { + if (!screenshareNotificationHiding()) { + return; + } + + bgExecutor.execute(() -> { + ArraySet<String> exemptPackages = new ArraySet<>(); + // Exempt SystemUI + exemptPackages.add(context.getPackageName()); + + // Exempt approved bug report handlers + try { + exemptPackages.addAll(activityManager.getBugreportWhitelistedPackages()); + } catch (RemoteException e) { + Log.e( + LOG_TAG, + "Error adding bug report handlers to exemption, continuing without", + e); + // silent failure, skip adding packages to exemption + } + + // if currently projecting, notify listeners of exemption changes + mainHandler.post(() -> { + Trace.beginSection("SNPC.exemptPackagesUpdated"); + try { + updateExemptPackagesAndNotifyListeners(exemptPackages); + } finally { + Trace.endSection(); + } + }); + }); - if (screenshareNotificationHiding()) { - mMediaProjectionManager.addCallback(mMediaProjectionCallback, mainHandler); + mediaProjectionManager.addCallback(mMediaProjectionCallback, mainHandler); + } + + /** + * Notify listeners of possible ProjectionState change regardless of current + * isSensitiveStateActive value. Method used to ensure updates occur after mExemptPackages gets + * updated, which directly changes the outcome of isSensitiveStateActive + */ + @MainThread + private void updateExemptPackagesAndNotifyListeners(ArraySet<String> exemptPackages) { + Assert.isMainThread(); + mExemptPackages.addAll(exemptPackages); + + if (mProjection != null) { + mListeners.forEach(Runnable::run); + } + } + + /** + * Update ProjectionState respecting current isSensitiveStateActive value. Only notifies + * listeners + */ + @MainThread + private void updateProjectionStateAndNotifyListeners(MediaProjectionInfo info) { + Assert.isMainThread(); + // capture previous state + boolean wasSensitive = isSensitiveStateActive(); + + // update internal state + mProjection = info; + + // if either previous or new state is sensitive, notify listeners. + if (wasSensitive || isSensitiveStateActive()) { + mListeners.forEach(Runnable::run); } } @@ -96,11 +163,17 @@ public class SensitiveNotificationProtectionControllerImpl mListeners.remove(onSensitiveStateChanged); } + // TODO(b/323396693): opportunity for optimization @Override public boolean isSensitiveStateActive() { + MediaProjectionInfo projection = mProjection; + if (projection == null) { + return false; + } + // TODO(b/316955558): Add disabled by developer option - // TODO(b/316955306): Add feature exemption for sysui and bug handlers - return mProjection != null; + + return !mExemptPackages.contains(projection.getPackageName()); } @Override 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 new file mode 100644 index 000000000000..98be163bdf34 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerFlagDisabledTest.kt @@ -0,0 +1,63 @@ +/* + * 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 android.app.IActivityManager +import android.media.projection.MediaProjectionManager +import android.os.Handler +import android.platform.test.annotations.DisableFlags +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.server.notification.Flags +import com.android.systemui.SysuiTestCase +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.time.FakeSystemClock +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.verifyZeroInteractions +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@DisableFlags(Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING) +class SensitiveNotificationProtectionControllerFlagDisabledTest : SysuiTestCase() { + @Mock private lateinit var handler: Handler + @Mock private lateinit var activityManager: IActivityManager + @Mock private lateinit var mediaProjectionManager: MediaProjectionManager + private lateinit var controller: SensitiveNotificationProtectionControllerImpl + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + + controller = + SensitiveNotificationProtectionControllerImpl( + mContext, + mediaProjectionManager, + activityManager, + handler, + FakeExecutor(FakeSystemClock()) + ) + } + + @Test + fun init_noRegisterMediaProjectionManagerCallback() { + verifyZeroInteractions(mediaProjectionManager) + } +} 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 9919c6b78aab..a1aff48ae1b7 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 @@ -17,88 +17,93 @@ package com.android.systemui.statusbar.policy import android.app.ActivityOptions +import android.app.IActivityManager import android.app.Notification import android.media.projection.MediaProjectionInfo import android.media.projection.MediaProjectionManager -import android.os.Handler +import android.platform.test.annotations.EnableFlags import android.service.notification.StatusBarNotification import android.testing.AndroidTestingRunner +import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest import com.android.server.notification.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.notification.collection.NotificationEntry +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.concurrency.mockExecutorHandler +import com.android.systemui.util.mockito.whenever +import com.android.systemui.util.mockito.withArgCaptor +import com.android.systemui.util.time.FakeSystemClock import org.junit.Assert.assertFalse import org.junit.Assert.assertNotNull import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.any -import org.mockito.Captor import org.mockito.Mock import org.mockito.Mockito.mock -import org.mockito.Mockito.reset import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.Mockito.verifyZeroInteractions -import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations @SmallTest @RunWith(AndroidTestingRunner::class) +@RunWithLooper +@EnableFlags(Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING) class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { - @Mock private lateinit var handler: Handler - + @Mock private lateinit var activityManager: IActivityManager @Mock private lateinit var mediaProjectionManager: MediaProjectionManager - @Mock private lateinit var mediaProjectionInfo: MediaProjectionInfo - @Mock private lateinit var listener1: Runnable @Mock private lateinit var listener2: Runnable @Mock private lateinit var listener3: Runnable - @Captor - private lateinit var mediaProjectionCallbackCaptor: - ArgumentCaptor<MediaProjectionManager.Callback> - + private lateinit var mediaProjectionCallback: MediaProjectionManager.Callback private lateinit var controller: SensitiveNotificationProtectionControllerImpl @Before fun setUp() { + allowTestableLooperAsMainThread() // for updating exempt packages and notifying listeners MockitoAnnotations.initMocks(this) - mSetFlagsRule.enableFlags(Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING) setShareFullScreen() + whenever(activityManager.bugreportWhitelistedPackages) + .thenReturn(listOf(BUGREPORT_PACKAGE_NAME)) + + val executor = FakeExecutor(FakeSystemClock()) - controller = SensitiveNotificationProtectionControllerImpl(mediaProjectionManager, handler) + controller = + SensitiveNotificationProtectionControllerImpl( + mContext, + mediaProjectionManager, + activityManager, + mockExecutorHandler(executor), + executor + ) + + // Process exemption processing + executor.runAllReady() // Obtain useful MediaProjectionCallback - verify(mediaProjectionManager).addCallback(mediaProjectionCallbackCaptor.capture(), any()) + mediaProjectionCallback = withArgCaptor { + verify(mediaProjectionManager).addCallback(capture(), any()) + } } @Test - fun init_flagEnabled_registerMediaProjectionManagerCallback() { - assertNotNull(mediaProjectionCallbackCaptor.value) - } - - @Test - fun init_flagDisabled_noRegisterMediaProjectionManagerCallback() { - mSetFlagsRule.disableFlags(Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING) - reset(mediaProjectionManager) - - controller = SensitiveNotificationProtectionControllerImpl(mediaProjectionManager, handler) - - verifyZeroInteractions(mediaProjectionManager) + fun init_registerMediaProjectionManagerCallback() { + assertNotNull(mediaProjectionCallback) } @Test fun registerSensitiveStateListener_singleListener() { controller.registerSensitiveStateListener(listener1) - mediaProjectionCallbackCaptor.value.onStart(mediaProjectionInfo) - mediaProjectionCallbackCaptor.value.onStop(mediaProjectionInfo) + mediaProjectionCallback.onStart(mediaProjectionInfo) + mediaProjectionCallback.onStop(mediaProjectionInfo) verify(listener1, times(2)).run() } @@ -108,8 +113,8 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { controller.registerSensitiveStateListener(listener1) controller.registerSensitiveStateListener(listener2) - mediaProjectionCallbackCaptor.value.onStart(mediaProjectionInfo) - mediaProjectionCallbackCaptor.value.onStop(mediaProjectionInfo) + mediaProjectionCallback.onStart(mediaProjectionInfo) + mediaProjectionCallback.onStop(mediaProjectionInfo) verify(listener1, times(2)).run() verify(listener2, times(2)).run() @@ -117,12 +122,12 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { @Test fun registerSensitiveStateListener_afterProjectionActive() { - mediaProjectionCallbackCaptor.value.onStart(mediaProjectionInfo) + mediaProjectionCallback.onStart(mediaProjectionInfo) controller.registerSensitiveStateListener(listener1) verifyZeroInteractions(listener1) - mediaProjectionCallbackCaptor.value.onStop(mediaProjectionInfo) + mediaProjectionCallback.onStop(mediaProjectionInfo) verify(listener1).run() } @@ -131,15 +136,15 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { fun unregisterSensitiveStateListener_singleListener() { controller.registerSensitiveStateListener(listener1) - mediaProjectionCallbackCaptor.value.onStart(mediaProjectionInfo) - mediaProjectionCallbackCaptor.value.onStop(mediaProjectionInfo) + mediaProjectionCallback.onStart(mediaProjectionInfo) + mediaProjectionCallback.onStop(mediaProjectionInfo) verify(listener1, times(2)).run() controller.unregisterSensitiveStateListener(listener1) - mediaProjectionCallbackCaptor.value.onStart(mediaProjectionInfo) - mediaProjectionCallbackCaptor.value.onStop(mediaProjectionInfo) + mediaProjectionCallback.onStart(mediaProjectionInfo) + mediaProjectionCallback.onStop(mediaProjectionInfo) verifyNoMoreInteractions(listener1) } @@ -150,8 +155,8 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { controller.registerSensitiveStateListener(listener2) controller.registerSensitiveStateListener(listener3) - mediaProjectionCallbackCaptor.value.onStart(mediaProjectionInfo) - mediaProjectionCallbackCaptor.value.onStop(mediaProjectionInfo) + mediaProjectionCallback.onStart(mediaProjectionInfo) + mediaProjectionCallback.onStop(mediaProjectionInfo) verify(listener1, times(2)).run() verify(listener2, times(2)).run() @@ -160,8 +165,8 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { controller.unregisterSensitiveStateListener(listener1) controller.unregisterSensitiveStateListener(listener2) - mediaProjectionCallbackCaptor.value.onStart(mediaProjectionInfo) - mediaProjectionCallbackCaptor.value.onStop(mediaProjectionInfo) + mediaProjectionCallback.onStart(mediaProjectionInfo) + mediaProjectionCallback.onStop(mediaProjectionInfo) verifyNoMoreInteractions(listener1) verifyNoMoreInteractions(listener2) @@ -175,24 +180,24 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { @Test fun isSensitiveStateActive_projectionActive_true() { - mediaProjectionCallbackCaptor.value.onStart(mediaProjectionInfo) + mediaProjectionCallback.onStart(mediaProjectionInfo) assertTrue(controller.isSensitiveStateActive) } @Test fun isSensitiveStateActive_projectionInactiveAfterActive_false() { - mediaProjectionCallbackCaptor.value.onStart(mediaProjectionInfo) - mediaProjectionCallbackCaptor.value.onStop(mediaProjectionInfo) + mediaProjectionCallback.onStart(mediaProjectionInfo) + mediaProjectionCallback.onStop(mediaProjectionInfo) assertFalse(controller.isSensitiveStateActive) } @Test fun isSensitiveStateActive_projectionActiveAfterInactive_true() { - mediaProjectionCallbackCaptor.value.onStart(mediaProjectionInfo) - mediaProjectionCallbackCaptor.value.onStop(mediaProjectionInfo) - mediaProjectionCallbackCaptor.value.onStart(mediaProjectionInfo) + mediaProjectionCallback.onStart(mediaProjectionInfo) + mediaProjectionCallback.onStop(mediaProjectionInfo) + mediaProjectionCallback.onStart(mediaProjectionInfo) assertTrue(controller.isSensitiveStateActive) } @@ -200,7 +205,25 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { @Test fun isSensitiveStateActive_projectionActive_singleActivity_false() { setShareSingleApp() - mediaProjectionCallbackCaptor.value.onStart(mediaProjectionInfo) + mediaProjectionCallback.onStart(mediaProjectionInfo) + + assertFalse(controller.isSensitiveStateActive) + } + + @Test + fun isSensitiveStateActive_projectionActive_sysuiExempt_false() { + // SystemUi context packge name is exempt, but in test scenarios its + // com.android.systemui.tests so use that instead of hardcoding + whenever(mediaProjectionInfo.packageName).thenReturn(mContext.packageName) + mediaProjectionCallback.onStart(mediaProjectionInfo) + + assertFalse(controller.isSensitiveStateActive) + } + + @Test + fun isSensitiveStateActive_projectionActive_bugReportHandlerExempt_false() { + whenever(mediaProjectionInfo.packageName).thenReturn(BUGREPORT_PACKAGE_NAME) + mediaProjectionCallback.onStart(mediaProjectionInfo) assertFalse(controller.isSensitiveStateActive) } @@ -215,7 +238,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { @Test fun shouldProtectNotification_projectionActive_singleActivity_false() { setShareSingleApp() - mediaProjectionCallbackCaptor.value.onStart(mediaProjectionInfo) + mediaProjectionCallback.onStart(mediaProjectionInfo) val notificationEntry = setupNotificationEntry(TEST_PACKAGE_NAME) @@ -224,7 +247,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { @Test fun shouldProtectNotification_projectionActive_fgsNotificationFromProjectionApp_false() { - mediaProjectionCallbackCaptor.value.onStart(mediaProjectionInfo) + mediaProjectionCallback.onStart(mediaProjectionInfo) val notificationEntry = setupFgsNotificationEntry(TEST_PROJECTION_PACKAGE_NAME) @@ -233,7 +256,7 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { @Test fun shouldProtectNotification_projectionActive_fgsNotificationNotFromProjectionApp_true() { - mediaProjectionCallbackCaptor.value.onStart(mediaProjectionInfo) + mediaProjectionCallback.onStart(mediaProjectionInfo) val notificationEntry = setupFgsNotificationEntry(TEST_PACKAGE_NAME) @@ -242,21 +265,43 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { @Test fun shouldProtectNotification_projectionActive_notFgsNotification_true() { - mediaProjectionCallbackCaptor.value.onStart(mediaProjectionInfo) + mediaProjectionCallback.onStart(mediaProjectionInfo) val notificationEntry = setupNotificationEntry(TEST_PROJECTION_PACKAGE_NAME) assertTrue(controller.shouldProtectNotification(notificationEntry)) } + @Test + fun shouldProtectNotification_projectionActive_sysuiExempt_false() { + // SystemUi context packge name is exempt, but in test scenarios its + // com.android.systemui.tests so use that instead of hardcoding + whenever(mediaProjectionInfo.packageName).thenReturn(mContext.packageName) + mediaProjectionCallback.onStart(mediaProjectionInfo) + + val notificationEntry = setupNotificationEntry(TEST_PACKAGE_NAME, false) + + assertFalse(controller.shouldProtectNotification(notificationEntry)) + } + + @Test + fun shouldProtectNotification_projectionActive_bugReportHandlerExempt_false() { + whenever(mediaProjectionInfo.packageName).thenReturn(BUGREPORT_PACKAGE_NAME) + mediaProjectionCallback.onStart(mediaProjectionInfo) + + val notificationEntry = setupNotificationEntry(TEST_PACKAGE_NAME, false) + + assertFalse(controller.shouldProtectNotification(notificationEntry)) + } + private fun setShareFullScreen() { - `when`(mediaProjectionInfo.packageName).thenReturn(TEST_PROJECTION_PACKAGE_NAME) - `when`(mediaProjectionInfo.launchCookie).thenReturn(null) + whenever(mediaProjectionInfo.packageName).thenReturn(TEST_PROJECTION_PACKAGE_NAME) + whenever(mediaProjectionInfo.launchCookie).thenReturn(null) } private fun setShareSingleApp() { - `when`(mediaProjectionInfo.packageName).thenReturn(TEST_PROJECTION_PACKAGE_NAME) - `when`(mediaProjectionInfo.launchCookie).thenReturn(ActivityOptions.LaunchCookie()) + whenever(mediaProjectionInfo.packageName).thenReturn(TEST_PROJECTION_PACKAGE_NAME) + whenever(mediaProjectionInfo.launchCookie).thenReturn(ActivityOptions.LaunchCookie()) } private fun setupNotificationEntry( @@ -266,10 +311,10 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { val notificationEntry = mock(NotificationEntry::class.java) val sbn = mock(StatusBarNotification::class.java) val notification = mock(Notification::class.java) - `when`(notificationEntry.sbn).thenReturn(sbn) - `when`(sbn.packageName).thenReturn(packageName) - `when`(sbn.notification).thenReturn(notification) - `when`(notification.isFgsOrUij).thenReturn(isFgs) + whenever(notificationEntry.sbn).thenReturn(sbn) + whenever(sbn.packageName).thenReturn(packageName) + whenever(sbn.notification).thenReturn(notification) + whenever(notification.isFgsOrUij).thenReturn(isFgs) return notificationEntry } @@ -282,5 +327,6 @@ class SensitiveNotificationProtectionControllerTest : SysuiTestCase() { private const val TEST_PROJECTION_PACKAGE_NAME = "com.android.systemui.statusbar.policy.projectionpackage" private const val TEST_PACKAGE_NAME = "com.android.systemui.statusbar.policy.testpackage" + private const val BUGREPORT_PACKAGE_NAME = "com.android.test.bugreporthandler" } } |