diff options
6 files changed, 104 insertions, 0 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java index 5c6f73f0a4a2..3a67c6dccc93 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java @@ -678,6 +678,17 @@ public class BubbleController implements ConfigurationChangeListener, mDataRepository.removeBubblesForUser(removedUserId, parentUserId); } + /** Called when sensitive notification state has changed */ + public void onSensitiveNotificationProtectionStateChanged( + boolean sensitiveNotificationProtectionActive) { + if (mStackView != null) { + mStackView.onSensitiveNotificationProtectionStateChanged( + sensitiveNotificationProtectionActive); + ProtoLog.d(WM_SHELL_BUBBLES, "onSensitiveNotificationProtectionStateChanged=%b", + sensitiveNotificationProtectionActive); + } + } + /** Whether bubbles are showing in the bubble bar. */ public boolean isShowingAsBubbleBar() { return canShowAsBubbleBar() && mBubbleStateListener != null; @@ -2578,6 +2589,14 @@ public class BubbleController implements ConfigurationChangeListener, mMainExecutor.execute( () -> BubbleController.this.onNotificationPanelExpandedChanged(expanded)); } + + @Override + public void onSensitiveNotificationProtectionStateChanged( + boolean sensitiveNotificationProtectionActive) { + mMainExecutor.execute( + () -> BubbleController.this.onSensitiveNotificationProtectionStateChanged( + sensitiveNotificationProtectionActive)); + } } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java index b23fd5269eae..e7da034a7422 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java @@ -291,6 +291,11 @@ public class BubbleStackView extends FrameLayout */ private boolean mRemovingLastBubbleWhileExpanded = false; + /** + * Whether sensitive notification protection should disable flyout + */ + private boolean mSensitiveNotificationProtectionActive = false; + /** Animator for animating the expanded view's alpha (including the TaskView inside it). */ private final ValueAnimator mExpandedViewAlphaAnimator = ValueAnimator.ofFloat(0f, 1f); @@ -2199,6 +2204,11 @@ public class BubbleStackView extends FrameLayout } } + void onSensitiveNotificationProtectionStateChanged( + boolean sensitiveNotificationProtectionActive) { + mSensitiveNotificationProtectionActive = sensitiveNotificationProtectionActive; + } + /** * Asks the BubbleController to hide the IME from anywhere, whether it's focused on Bubbles or * not. @@ -2842,6 +2852,7 @@ public class BubbleStackView extends FrameLayout || isExpanded() || mIsExpansionAnimating || mIsGestureInProgress + || mSensitiveNotificationProtectionActive || mBubbleToExpandAfterFlyoutCollapse != null || bubbleView == null) { if (bubbleView != null && mFlyout.getVisibility() != VISIBLE) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java index 28af0ca6ac6c..26077cf7057b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java @@ -286,6 +286,16 @@ public interface Bubbles { void onUserRemoved(int removedUserId); /** + * Called when the Sensitive notification protection state has changed, such as when media + * projection starts and stops. + * + * @param sensitiveNotificationProtectionActive {@code true} if notifications should be + * protected + */ + void onSensitiveNotificationProtectionStateChanged( + boolean sensitiveNotificationProtectionActive); + + /** * A listener to be notified of bubble state changes, used by launcher to render bubbles in * its process. */ diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index e8931770b15e..1157d97f2f2e 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -126,6 +126,7 @@ import com.android.systemui.statusbar.pipeline.dagger.StatusBarPipelineModule; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.PolicyModule; +import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.statusbar.policy.dagger.SmartRepliesInflationModule; import com.android.systemui.statusbar.policy.dagger.StatusBarPolicyModule; @@ -358,6 +359,7 @@ public abstract class SystemUIModule { VisualInterruptionDecisionProvider visualInterruptionDecisionProvider, ZenModeController zenModeController, NotificationLockscreenUserManager notifUserManager, + SensitiveNotificationProtectionController sensitiveNotificationProtectionController, CommonNotifCollection notifCollection, NotifPipeline notifPipeline, SysUiState sysUiState, @@ -376,6 +378,7 @@ public abstract class SystemUIModule { visualInterruptionDecisionProvider, zenModeController, notifUserManager, + sensitiveNotificationProtectionController, notifCollection, notifPipeline, sysUiState, diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java index 139d190ae63c..65dede83f3d6 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java @@ -25,6 +25,7 @@ import static android.service.notification.NotificationListenerService.REASON_GR import static android.service.notification.NotificationStats.DISMISSAL_BUBBLE; import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL; +import static com.android.server.notification.Flags.screenshareNotificationHiding; import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES; import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME; @@ -69,6 +70,7 @@ import com.android.systemui.statusbar.notification.collection.render.Notificatio import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider; import com.android.systemui.statusbar.phone.StatusBarWindowCallback; import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.wm.shell.bubbles.Bubble; import com.android.wm.shell.bubbles.BubbleEntry; @@ -102,6 +104,7 @@ public class BubblesManager { private final NotificationVisibilityProvider mVisibilityProvider; private final VisualInterruptionDecisionProvider mVisualInterruptionDecisionProvider; private final NotificationLockscreenUserManager mNotifUserManager; + private final SensitiveNotificationProtectionController mSensitiveNotifProtectionController; private final CommonNotifCollection mCommonNotifCollection; private final NotifPipeline mNotifPipeline; private final NotifPipelineFlags mNotifPipelineFlags; @@ -111,6 +114,7 @@ public class BubblesManager { // TODO (b/145659174): allow for multiple callbacks to support the "shadow" new notif pipeline private final List<NotifCallback> mCallbacks = new ArrayList<>(); private final StatusBarWindowCallback mStatusBarWindowCallback; + private final Runnable mSensitiveStateChangedListener; private boolean mPanelExpanded; /** @@ -130,6 +134,7 @@ public class BubblesManager { VisualInterruptionDecisionProvider visualInterruptionDecisionProvider, ZenModeController zenModeController, NotificationLockscreenUserManager notifUserManager, + SensitiveNotificationProtectionController sensitiveNotificationProtectionController, CommonNotifCollection notifCollection, NotifPipeline notifPipeline, SysUiState sysUiState, @@ -149,6 +154,7 @@ public class BubblesManager { visualInterruptionDecisionProvider, zenModeController, notifUserManager, + sensitiveNotificationProtectionController, notifCollection, notifPipeline, sysUiState, @@ -173,6 +179,7 @@ public class BubblesManager { VisualInterruptionDecisionProvider visualInterruptionDecisionProvider, ZenModeController zenModeController, NotificationLockscreenUserManager notifUserManager, + SensitiveNotificationProtectionController sensitiveNotificationProtectionController, CommonNotifCollection notifCollection, NotifPipeline notifPipeline, SysUiState sysUiState, @@ -188,6 +195,7 @@ public class BubblesManager { mVisibilityProvider = visibilityProvider; mVisualInterruptionDecisionProvider = visualInterruptionDecisionProvider; mNotifUserManager = notifUserManager; + mSensitiveNotifProtectionController = sensitiveNotificationProtectionController; mCommonNotifCollection = notifCollection; mNotifPipeline = notifPipeline; mNotifPipelineFlags = notifPipelineFlags; @@ -251,6 +259,22 @@ public class BubblesManager { }; notificationShadeWindowController.registerCallback(mStatusBarWindowCallback); + mSensitiveStateChangedListener = new Runnable() { + @Override + public void run() { + if (!screenshareNotificationHiding()) { + return; + } + bubbles.onSensitiveNotificationProtectionStateChanged( + mSensitiveNotifProtectionController.isSensitiveStateActive()); + } + }; + + if (screenshareNotificationHiding()) { + mSensitiveNotifProtectionController + .registerSensitiveStateListener(mSensitiveStateChangedListener); + } + mSysuiProxy = new Bubbles.SysuiProxy() { @Override public void isNotificationPanelExpand(Consumer<Boolean> callback) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index d87df0af6ba9..4a63a080a150 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -26,6 +26,7 @@ import static android.service.notification.NotificationListenerService.REASON_AP import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; +import static com.android.server.notification.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING; import static com.google.common.truth.Truth.assertThat; @@ -46,6 +47,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import static kotlinx.coroutines.flow.FlowKt.emptyFlow; @@ -73,6 +75,8 @@ import android.os.PowerManager; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; import android.service.dreams.IDreamManager; import android.service.notification.NotificationListenerService; import android.service.notification.ZenModeConfig; @@ -161,6 +165,7 @@ import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController; +import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository; import com.android.systemui.statusbar.policy.data.repository.FakeUserSetupRepository; @@ -257,6 +262,8 @@ public class BubblesTest extends SysuiTestCase { private NotificationShadeWindowView mNotificationShadeWindowView; @Mock private AuthController mAuthController; + @Mock + private SensitiveNotificationProtectionController mSensitiveNotificationProtectionController; private SysUiState mSysUiState; private boolean mSysUiStateBubblesExpanded; @@ -272,6 +279,8 @@ public class BubblesTest extends SysuiTestCase { private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverArgumentCaptor; @Captor private ArgumentCaptor<KeyguardStateController.Callback> mKeyguardStateControllerCallbackCaptor; + @Captor + private ArgumentCaptor<Runnable> mSensitiveStateChangedListener; private BubblesManager mBubblesManager; private TestableBubbleController mBubbleController; @@ -595,6 +604,7 @@ public class BubblesTest extends SysuiTestCase { interruptionDecisionProvider, mZenModeController, mLockscreenUserManager, + mSensitiveNotificationProtectionController, mCommonNotifCollection, mNotifPipeline, mSysUiState, @@ -2204,6 +2214,33 @@ public class BubblesTest extends SysuiTestCase { assertThat(mBubbleController.getLayerView().isExpanded()).isFalse(); } + @DisableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING) + @Test + public void doesNotRegisterSensitiveStateListener() { + verifyZeroInteractions(mSensitiveNotificationProtectionController); + } + + @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING) + @Test + public void registerSensitiveStateListener() { + verify(mSensitiveNotificationProtectionController).registerSensitiveStateListener(any()); + } + + @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING) + @Test + public void onSensitiveNotificationProtectionStateChanged() { + verify(mSensitiveNotificationProtectionController, atLeastOnce()) + .registerSensitiveStateListener(mSensitiveStateChangedListener.capture()); + + when(mSensitiveNotificationProtectionController.isSensitiveStateActive()).thenReturn(true); + mSensitiveStateChangedListener.getValue().run(); + verify(mBubbleController).onSensitiveNotificationProtectionStateChanged(true); + + when(mSensitiveNotificationProtectionController.isSensitiveStateActive()).thenReturn(false); + mSensitiveStateChangedListener.getValue().run(); + verify(mBubbleController).onSensitiveNotificationProtectionStateChanged(false); + } + /** Creates a bubble using the userId and package. */ private Bubble createBubble(int userId, String pkg) { final UserHandle userHandle = new UserHandle(userId); |