diff options
14 files changed, 447 insertions, 14 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java index 8bf8e0926095..867f1178c3f8 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java @@ -20,6 +20,7 @@ import android.graphics.Rect; import android.util.Slog; import com.android.keyguard.KeyguardClockSwitch.ClockSize; +import com.android.systemui.communal.CommunalStateController; import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.shared.system.smartspace.SmartspaceTransitionController; import com.android.systemui.statusbar.notification.AnimatableProperty; @@ -64,6 +65,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV KeyguardClockSwitchController keyguardClockSwitchController, KeyguardStateController keyguardStateController, KeyguardUpdateMonitor keyguardUpdateMonitor, + CommunalStateController communalStateController, ConfigurationController configurationController, DozeParameters dozeParameters, KeyguardUnlockAnimationController keyguardUnlockAnimationController, @@ -76,8 +78,9 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV mConfigurationController = configurationController; mDozeParameters = dozeParameters; mKeyguardStateController = keyguardStateController; - mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController, - dozeParameters, unlockedScreenOffAnimationController, /* animateYPos= */ true); + mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, communalStateController, + keyguardStateController, dozeParameters, unlockedScreenOffAnimationController, + /* animateYPos= */ true); mKeyguardUnlockAnimationController = keyguardUnlockAnimationController; mSmartspaceTransitionController = smartspaceTransitionController; } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java index 28a54d56b071..a71b4f47640b 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java @@ -22,6 +22,7 @@ import android.view.View; import android.view.ViewPropertyAnimator; import com.android.systemui.animation.Interpolators; +import com.android.systemui.communal.CommunalStateController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.notification.AnimatableProperty; import com.android.systemui.statusbar.notification.PropertyAnimator; @@ -38,6 +39,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController; public class KeyguardVisibilityHelper { private View mView; + private final CommunalStateController mCommunalStateController; private final KeyguardStateController mKeyguardStateController; private final DozeParameters mDozeParameters; private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; @@ -47,11 +49,13 @@ public class KeyguardVisibilityHelper { private final AnimationProperties mAnimationProperties = new AnimationProperties(); public KeyguardVisibilityHelper(View view, + CommunalStateController communalStateController, KeyguardStateController keyguardStateController, DozeParameters dozeParameters, UnlockedScreenOffAnimationController unlockedScreenOffAnimationController, boolean animateYPos) { mView = view; + mCommunalStateController = communalStateController; mKeyguardStateController = keyguardStateController; mDozeParameters = dozeParameters; mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController; @@ -73,6 +77,14 @@ public class KeyguardVisibilityHelper { mView.animate().cancel(); boolean isOccluded = mKeyguardStateController.isOccluded(); mKeyguardViewVisibilityAnimating = false; + + // If the communal view is showing, hide immediately + if (mCommunalStateController.getCommunalViewShowing()) { + mView.setVisibility(View.GONE); + mView.setAlpha(1f); + return; + } + if ((!keyguardFadingAway && oldStatusBarState == KEYGUARD && statusBarState != KEYGUARD) || goingToFullShade) { mKeyguardViewVisibilityAnimating = true; diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewController.java b/packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewController.java index cb0c2827c7a5..320c2ea5ba78 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewController.java +++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalHostViewController.java @@ -53,6 +53,8 @@ public class CommunalHostViewController extends ViewController<CommunalHostView> private final StatusBarStateController mStatusBarStateController; private WeakReference<CommunalSource> mLastSource; private int mState; + private float mQsExpansion; + private float mShadeExpansion; @Retention(RetentionPolicy.RUNTIME) @IntDef({STATE_KEYGUARD_SHOWING, STATE_DOZING, STATE_BOUNCER_SHOWING, STATE_KEYGUARD_OCCLUDED}) @@ -264,4 +266,27 @@ public class CommunalHostViewController extends ViewController<CommunalHostView> mLastSource = source; showSource(); } + + /** + * Invoked when the quick settings is expanded. + * @param expansionFraction the percentage the QS shade has been expanded. + */ + public void updateQsExpansion(float expansionFraction) { + mQsExpansion = expansionFraction; + updateCommunalViewOccluded(); + } + + /** + * Invoked when the main shade is expanded. + * @param shadeExpansion the percentage the main shade has expanded. + */ + public void updateShadeExpansion(float shadeExpansion) { + mShadeExpansion = shadeExpansion; + updateCommunalViewOccluded(); + } + + private void updateCommunalViewOccluded() { + mCommunalStateController.setCommunalViewOccluded( + mQsExpansion > 0.0f || mShadeExpansion > 0.0f); + } } diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalStateController.java b/packages/SystemUI/src/com/android/systemui/communal/CommunalStateController.java index e5385ec1543f..c72f5422b1f5 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/CommunalStateController.java +++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalStateController.java @@ -34,6 +34,7 @@ import javax.inject.Inject; public class CommunalStateController implements CallbackController<CommunalStateController.Callback> { private final ArrayList<Callback> mCallbacks = new ArrayList<>(); + private boolean mCommunalViewOccluded; private boolean mCommunalViewShowing; /** @@ -45,6 +46,12 @@ public class CommunalStateController implements */ default void onCommunalViewShowingChanged() { } + + /** + * Called when the occlusion of the communal view changes. + */ + default void onCommunalViewOccludedChanged() { + } } @VisibleForTesting @@ -57,13 +64,32 @@ public class CommunalStateController implements * @param communalViewShowing {@code true} if the view is showing, {@code false} otherwise. */ public void setCommunalViewShowing(boolean communalViewShowing) { - if (mCommunalViewShowing != communalViewShowing) { - mCommunalViewShowing = communalViewShowing; + if (mCommunalViewShowing == communalViewShowing) { + return; + } + + mCommunalViewShowing = communalViewShowing; + + final ArrayList<Callback> callbacks = new ArrayList<>(mCallbacks); + for (Callback callback : callbacks) { + callback.onCommunalViewShowingChanged(); + } + } - final ArrayList<Callback> callbacks = new ArrayList<>(mCallbacks); - for (Callback callback : callbacks) { - callback.onCommunalViewShowingChanged(); - } + /** + * Sets whether the communal view is occluded (but otherwise still showing). + * @param communalViewOccluded {@code true} if the view is occluded, {@code false} otherwise. + */ + public void setCommunalViewOccluded(boolean communalViewOccluded) { + if (mCommunalViewOccluded == communalViewOccluded) { + return; + } + + mCommunalViewOccluded = communalViewOccluded; + + ArrayList<Callback> callbacks = new ArrayList<>(mCallbacks); + for (int i = 0; i < callbacks.size(); i++) { + callbacks.get(i).onCommunalViewOccludedChanged(); } } @@ -75,6 +101,14 @@ public class CommunalStateController implements return mCommunalViewShowing; } + /** + * Returns whether the communal view is occluded. + * @return {@code true} if the view is occluded, {@code false} otherwise. + */ + public boolean getCommunalViewOccluded() { + return mCommunalViewOccluded; + } + @Override public void addCallback(@NonNull Callback callback) { Objects.requireNonNull(callback, "Callback must not be null. b/128895449"); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinator.java new file mode 100644 index 000000000000..369e52f55278 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinator.java @@ -0,0 +1,70 @@ +/* + * 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.statusbar.notification.collection.coordinator; + +import androidx.annotation.NonNull; + +import com.android.systemui.communal.CommunalStateController; +import com.android.systemui.statusbar.NotificationLockscreenUserManager; +import com.android.systemui.statusbar.notification.NotificationEntryManager; +import com.android.systemui.statusbar.notification.collection.NotifPipeline; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter; + +import javax.inject.Inject; + +/** + * {@link CommunalCoordinator} prevents notifications from showing on the keyguard when the communal + * view is present. + */ +public class CommunalCoordinator implements Coordinator { + final CommunalStateController mCommunalStateController; + final NotificationEntryManager mNotificationEntryManager; + final NotificationLockscreenUserManager mNotificationLockscreenUserManager; + + @Inject + public CommunalCoordinator(NotificationEntryManager notificationEntryManager, + NotificationLockscreenUserManager notificationLockscreenUserManager, + CommunalStateController communalStateController) { + mNotificationEntryManager = notificationEntryManager; + mNotificationLockscreenUserManager = notificationLockscreenUserManager; + mCommunalStateController = communalStateController; + } + + final NotifFilter mFilter = new NotifFilter("CommunalCoordinator") { + @Override + public boolean shouldFilterOut(@NonNull NotificationEntry entry, long now) { + return mCommunalStateController.getCommunalViewShowing(); + } + }; + + final CommunalStateController.Callback mStateCallback = new CommunalStateController.Callback() { + @Override + public void onCommunalViewShowingChanged() { + mFilter.invalidateList(); + mNotificationEntryManager.updateNotifications("Communal mode state changed"); + } + }; + + @Override + public void attach(@NonNull NotifPipeline pipeline) { + pipeline.addPreGroupFilter(mFilter); + mCommunalStateController.addCallback(mStateCallback); + mNotificationLockscreenUserManager.addKeyguardNotificationSuppressor( + entry -> mCommunalStateController.getCommunalViewShowing()); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java index 25b201926239..47bc444396b9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java @@ -61,7 +61,8 @@ public class NotifCoordinators implements Dumpable { PreparationCoordinator preparationCoordinator, MediaCoordinator mediaCoordinator, SmartspaceDedupingCoordinator smartspaceDedupingCoordinator, - VisualStabilityCoordinator visualStabilityCoordinator) { + VisualStabilityCoordinator visualStabilityCoordinator, + CommunalCoordinator communalCoordinator) { dumpManager.registerDumpable(TAG, this); mCoordinators.add(new HideLocallyDismissedNotifsCoordinator()); @@ -74,6 +75,7 @@ public class NotifCoordinators implements Dumpable { mCoordinators.add(conversationCoordinator); mCoordinators.add(mediaCoordinator); mCoordinators.add(visualStabilityCoordinator); + mCoordinators.add(communalCoordinator); if (featureFlags.isSmartspaceDedupingEnabled()) { mCoordinators.add(smartspaceDedupingCoordinator); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index b8bef5592a71..e1dac45f97de 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -109,6 +109,7 @@ import com.android.systemui.communal.CommunalHostView; import com.android.systemui.communal.CommunalHostViewController; import com.android.systemui.communal.CommunalSource; import com.android.systemui.communal.CommunalSourceMonitor; +import com.android.systemui.communal.CommunalStateController; import com.android.systemui.communal.dagger.CommunalViewComponent; import com.android.systemui.controls.dagger.ControlsComponent; import com.android.systemui.dagger.qualifiers.DisplayId; @@ -327,6 +328,7 @@ public class NotificationPanelViewController extends PanelViewController { private final KeyguardBypassController mKeyguardBypassController; private final KeyguardUpdateMonitor mUpdateMonitor; private final CommunalSourceMonitor mCommunalSourceMonitor; + private final CommunalStateController mCommunalStateController; private final ConversationNotificationManager mConversationNotificationManager; private final AuthController mAuthController; private final MediaHierarchyManager mMediaHierarchyManager; @@ -711,6 +713,32 @@ public class NotificationPanelViewController extends PanelViewController { } }; + private final CommunalStateController.Callback mCommunalStateCallback = + new CommunalStateController.Callback() { + @Override + public void onCommunalViewShowingChanged() { + mKeyguardStatusViewController.setKeyguardStatusViewVisibility( + mBarState, + mKeyguardStateController.isKeyguardFadingAway(), + mStatusBarStateController.goingToFullShade(), + mBarState); + if (mKeyguardUserSwitcherController != null) { + mKeyguardUserSwitcherController.setKeyguardUserSwitcherVisibility( + mBarState, + mKeyguardStateController.isKeyguardFadingAway(), + mStatusBarStateController.goingToFullShade(), + mBarState); + } + if (mKeyguardQsUserSwitchController != null) { + mKeyguardQsUserSwitchController.setKeyguardQsUserSwitchVisibility( + mBarState, + mKeyguardStateController.isKeyguardFadingAway(), + mStatusBarStateController.goingToFullShade(), + mBarState); + } + } + }; + private final FalsingTapListener mFalsingTapListener = new FalsingTapListener() { @Override public void onDoubleTapRequired() { @@ -735,6 +763,7 @@ public class NotificationPanelViewController extends PanelViewController { FalsingCollector falsingCollector, NotificationLockscreenUserManager notificationLockscreenUserManager, NotificationEntryManager notificationEntryManager, + CommunalStateController communalStateController, KeyguardStateController keyguardStateController, StatusBarStateController statusBarStateController, DozeLog dozeLog, DozeParameters dozeParameters, CommandQueue commandQueue, VibratorHelper vibratorHelper, @@ -811,6 +840,7 @@ public class NotificationPanelViewController extends PanelViewController { mNotificationStackScrollLayoutController = notificationStackScrollLayoutController; mGroupManager = groupManager; mNotificationIconAreaController = notificationIconAreaController; + mCommunalStateController = communalStateController; mCommunalViewComponentFactory = communalViewComponentFactory; mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory; mKeyguardStatusBarViewComponentFactory = keyguardStatusBarViewComponentFactory; @@ -2384,6 +2414,10 @@ public class NotificationPanelViewController extends PanelViewController { setQSClippingBounds(); mNotificationStackScrollLayoutController.setQsExpansionFraction(qsExpansionFraction); mDepthController.setQsPanelExpansion(qsExpansionFraction); + + if (mCommunalViewController != null) { + mCommunalViewController.updateQsExpansion(qsExpansionFraction); + } } private void onStackYChanged(boolean shouldAnimate) { @@ -2722,6 +2756,10 @@ public class NotificationPanelViewController extends PanelViewController { } mTransitionToFullShadeQSPosition = position; updateQsExpansion(); + + if (mCommunalViewController != null) { + mCommunalViewController.updateShadeExpansion(mTransitioningToFullShadeProgress); + } } /** @@ -4660,6 +4698,7 @@ public class NotificationPanelViewController extends PanelViewController { mFalsingManager.addTapListener(mFalsingTapListener); mKeyguardIndicationController.init(); registerSettingsChangeListener(); + mCommunalStateController.addCallback(mCommunalStateCallback); } @Override @@ -4674,6 +4713,7 @@ public class NotificationPanelViewController extends PanelViewController { // Clear source when detached. setCommunalSource(null /*source*/); mFalsingManager.removeTapListener(mFalsingTapListener); + mCommunalStateController.removeCallback(mCommunalStateCallback); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java index 5e70d0dbc418..dd38f9826731 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java @@ -33,6 +33,7 @@ import com.android.keyguard.KeyguardVisibilityHelper; import com.android.keyguard.dagger.KeyguardUserSwitcherScope; import com.android.settingslib.drawable.CircleFramedDrawable; import com.android.systemui.R; +import com.android.systemui.communal.CommunalStateController; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.plugins.FalsingManager; @@ -116,6 +117,7 @@ public class KeyguardQsUserSwitchController extends ViewController<UserAvatarVie @Main Resources resources, ScreenLifecycle screenLifecycle, UserSwitcherController userSwitcherController, + CommunalStateController communalStateController, KeyguardStateController keyguardStateController, FalsingManager falsingManager, ConfigurationController configurationController, @@ -133,7 +135,7 @@ public class KeyguardQsUserSwitchController extends ViewController<UserAvatarVie mFalsingManager = falsingManager; mConfigurationController = configurationController; mStatusBarStateController = statusBarStateController; - mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, + mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, communalStateController, keyguardStateController, dozeParameters, unlockedScreenOffAnimationController, /* animateYPos= */ false); mUserDetailAdapter = new KeyguardUserDetailAdapter(context, userDetailViewAdapterProvider); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java index 43b2061ecd32..3240ad27954d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java @@ -42,6 +42,7 @@ import com.android.keyguard.dagger.KeyguardUserSwitcherScope; import com.android.settingslib.drawable.CircleFramedDrawable; import com.android.systemui.R; import com.android.systemui.animation.Interpolators; +import com.android.systemui.communal.CommunalStateController; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.plugins.statusbar.StatusBarStateController; @@ -157,6 +158,7 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS LayoutInflater layoutInflater, ScreenLifecycle screenLifecycle, UserSwitcherController userSwitcherController, + CommunalStateController communalStateController, KeyguardStateController keyguardStateController, SysuiStatusBarStateController statusBarStateController, KeyguardUpdateMonitor keyguardUpdateMonitor, @@ -172,7 +174,7 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS mKeyguardUpdateMonitor = keyguardUpdateMonitor; mAdapter = new KeyguardUserAdapter(mContext, resources, layoutInflater, mUserSwitcherController, this); - mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, + mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, communalStateController, keyguardStateController, dozeParameters, unlockedScreenOffAnimationController, /* animateYPos= */ false); mBackground = new KeyguardUserSwitcherScrim(context); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java index 6ec14fe46223..9c2382d5aa6e 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java @@ -22,6 +22,7 @@ import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import com.android.systemui.SysuiTestCase; +import com.android.systemui.communal.CommunalStateController; import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.shared.system.smartspace.SmartspaceTransitionController; import com.android.systemui.statusbar.phone.DozeParameters; @@ -50,6 +51,8 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase { @Mock private KeyguardStateController mKeyguardStateController; @Mock + private CommunalStateController mCommunalStateController; + @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor; @Mock ConfigurationController mConfigurationController; @@ -76,6 +79,7 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase { mKeyguardClockSwitchController, mKeyguardStateController, mKeyguardUpdateMonitor, + mCommunalStateController, mConfigurationController, mDozeParameters, mKeyguardUnlockAnimationController, diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardVisibilityHelperTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardVisibilityHelperTest.java new file mode 100644 index 000000000000..548b6551f586 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardVisibilityHelperTest.java @@ -0,0 +1,77 @@ +/* + * 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.keyguard; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.test.suitebuilder.annotation.SmallTest; +import android.view.View; +import android.view.ViewPropertyAnimator; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.communal.CommunalStateController; +import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; +import com.android.systemui.statusbar.policy.KeyguardStateController; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@SmallTest +public class KeyguardVisibilityHelperTest extends SysuiTestCase { + @Mock + private CommunalStateController mCommunalStateController; + @Mock + private KeyguardStateController mKeyguardStateController; + @Mock + com.android.systemui.statusbar.phone.DozeParameters mDozeParameters; + @Mock + UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; + @Mock + ViewPropertyAnimator mViewPropertyAnimator; + @Mock + View mTargetView; + + private KeyguardVisibilityHelper mKeyguardVisibilityHelper; + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + when(mTargetView.animate()).thenReturn(mViewPropertyAnimator); + mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mTargetView, + mCommunalStateController, mKeyguardStateController, mDozeParameters, + mUnlockedScreenOffAnimationController, false); + } + + @Test + public void testHideOnCommunal() { + // Verify view is hidden when communal is visible. + when(mCommunalStateController.getCommunalViewShowing()).thenReturn(true); + mKeyguardVisibilityHelper.setViewVisibility(StatusBarState.KEYGUARD, false, + false, StatusBarState.KEYGUARD); + verify(mTargetView).setVisibility(View.GONE); + verify(mTargetView).setAlpha(1.0f); + + // Verify view is shown when communal is not visible. + when(mCommunalStateController.getCommunalViewShowing()).thenReturn(false); + mKeyguardVisibilityHelper.setViewVisibility(StatusBarState.KEYGUARD, false, + false, StatusBarState.KEYGUARD); + verify(mTargetView).setVisibility(View.VISIBLE); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewControllerTest.java index 03d26bed725e..990637955b24 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalHostViewControllerTest.java @@ -159,6 +159,27 @@ public class CommunalHostViewControllerTest extends SysuiTestCase { } @Test + public void testReportOcclusion() { + // Ensure CommunalHostViewController reports view occluded when either the QS or Shade is + // expanded. + mController.updateShadeExpansion(0); + verify(mCommunalStateController).setCommunalViewOccluded(false); + clearInvocations(mCommunalStateController); + mController.updateQsExpansion(.5f); + verify(mCommunalStateController).setCommunalViewOccluded(true); + clearInvocations(mCommunalStateController); + mController.updateShadeExpansion(.7f); + verify(mCommunalStateController).setCommunalViewOccluded(true); + clearInvocations(mCommunalStateController); + mController.updateShadeExpansion(0); + verify(mCommunalStateController).setCommunalViewOccluded(true); + clearInvocations(mCommunalStateController); + mController.updateQsExpansion(0f); + verify(mCommunalStateController).setCommunalViewOccluded(false); + clearInvocations(mCommunalStateController); + } + + @Test public void testCommunalStateControllerHideNotified() { ArgumentCaptor<KeyguardUpdateMonitorCallback> callbackCapture = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinatorTest.java new file mode 100644 index 000000000000..01e4cce0cc30 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/CommunalCoordinatorTest.java @@ -0,0 +1,92 @@ +/* + * 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.statusbar.notification.collection.coordinator; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; + +import android.test.suitebuilder.annotation.SmallTest; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.communal.CommunalStateController; +import com.android.systemui.statusbar.NotificationLockscreenUserManager; +import com.android.systemui.statusbar.notification.NotificationEntryManager; +import com.android.systemui.statusbar.notification.collection.NotifPipeline; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter; +import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + + +@SmallTest +public class CommunalCoordinatorTest extends SysuiTestCase { + @Mock + CommunalStateController mCommunalStateController; + @Mock + NotificationEntryManager mNotificationEntryManager; + @Mock + NotificationLockscreenUserManager mNotificationLockscreenUserManager; + @Mock + NotifPipeline mNotifPipeline; + @Mock + NotificationEntry mNotificationEntry; + @Mock + Pluggable.PluggableListener mFilterListener; + + CommunalCoordinator mCoordinator; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mCoordinator = new CommunalCoordinator(mNotificationEntryManager, + mNotificationLockscreenUserManager, mCommunalStateController); + } + + @Test + public void testNotificationSuppressionInCommunal() { + mCoordinator.attach(mNotifPipeline); + final ArgumentCaptor<CommunalStateController.Callback> stateCallbackCaptor = + ArgumentCaptor.forClass(CommunalStateController.Callback.class); + verify(mCommunalStateController).addCallback(stateCallbackCaptor.capture()); + + final CommunalStateController.Callback stateCallback = stateCallbackCaptor.getValue(); + + final ArgumentCaptor<NotifFilter> filterCaptor = + ArgumentCaptor.forClass(NotifFilter.class); + verify(mNotifPipeline).addPreGroupFilter(filterCaptor.capture()); + + final NotifFilter filter = filterCaptor.getValue(); + + // Verify that notifications are not filtered out by default. + assert (!filter.shouldFilterOut(mNotificationEntry, 0)); + + filter.setInvalidationListener(mFilterListener); + + // Verify that notifications are filtered out when communal is showing and that the filter + // pipeline is notified. + stateCallback.onCommunalViewShowingChanged(); + verify(mFilterListener).onPluggableInvalidated(any()); + verify(mNotificationEntryManager).updateNotifications(any()); + assert (filter.shouldFilterOut(mNotificationEntry, 0)); + + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java index 954fcfdc9125..e9d698fd882c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java @@ -93,6 +93,7 @@ import com.android.systemui.communal.CommunalHostView; import com.android.systemui.communal.CommunalHostViewController; import com.android.systemui.communal.CommunalSource; import com.android.systemui.communal.CommunalSourceMonitor; +import com.android.systemui.communal.CommunalStateController; import com.android.systemui.communal.dagger.CommunalViewComponent; import com.android.systemui.controls.dagger.ControlsComponent; import com.android.systemui.doze.DozeLog; @@ -131,7 +132,10 @@ import com.android.systemui.statusbar.notification.stack.NotificationRoundnessMa import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController; import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController; +import com.android.systemui.statusbar.policy.KeyguardUserSwitcherView; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.settings.SecureSettings; import com.android.systemui.util.time.FakeSystemClock; @@ -178,7 +182,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private KeyguardStatusBarView mKeyguardStatusBar; @Mock - private View mUserSwitcherView; + private KeyguardUserSwitcherView mUserSwitcherView; @Mock private ViewStub mUserSwitcherStubView; @Mock @@ -247,8 +251,16 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private KeyguardQsUserSwitchComponent.Factory mKeyguardQsUserSwitchComponentFactory; @Mock + private KeyguardQsUserSwitchComponent mKeyguardQsUserSwitchComponent; + @Mock + private KeyguardQsUserSwitchController mKeyguardQsUserSwitchController; + @Mock private KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory; @Mock + private KeyguardUserSwitcherComponent mKeyguardUserSwitcherComponent; + @Mock + private KeyguardUserSwitcherController mKeyguardUserSwitcherController; + @Mock private IdleViewComponent.Factory mIdleViewComponentFactory; @Mock private IdleViewComponent mIdleViewComponent; @@ -275,6 +287,9 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private CommunalHostView mCommunalHostView; @Mock + private CommunalStateController mCommunalStateController; + private CommunalStateController.Callback mCommunalStateControllerCallback; + @Mock private KeyguardClockSwitchController mKeyguardClockSwitchController; @Mock private KeyguardStatusViewController mKeyguardStatusViewController; @@ -396,6 +411,14 @@ public class NotificationPanelViewTest extends SysuiTestCase { when(mFragmentService.getFragmentHostManager(mView)).thenReturn(mFragmentHostManager); FlingAnimationUtils.Builder flingAnimationUtilsBuilder = new FlingAnimationUtils.Builder( mDisplayMetrics); + when(mKeyguardQsUserSwitchComponentFactory.build(any())) + .thenReturn(mKeyguardQsUserSwitchComponent); + when(mKeyguardQsUserSwitchComponent.getKeyguardQsUserSwitchController()) + .thenReturn(mKeyguardQsUserSwitchController); + when(mKeyguardUserSwitcherComponentFactory.build(any())) + .thenReturn(mKeyguardUserSwitcherComponent); + when(mKeyguardUserSwitcherComponent.getKeyguardUserSwitcherController()) + .thenReturn(mKeyguardUserSwitcherController); doAnswer((Answer<Void>) invocation -> { mTouchHandler = invocation.getArgument(0); @@ -440,6 +463,8 @@ public class NotificationPanelViewTest extends SysuiTestCase { .thenReturn(mIdleHostViewController); when(mLayoutInflater.inflate(eq(R.layout.keyguard_status_view), any(), anyBoolean())) .thenReturn(mKeyguardStatusView); + when(mLayoutInflater.inflate(eq(R.layout.keyguard_user_switcher), any(), anyBoolean())) + .thenReturn(mUserSwitcherView); when(mLayoutInflater.inflate(eq(R.layout.keyguard_bottom_area), any(), anyBoolean())) .thenReturn(mKeyguardBottomArea); when(mNotificationRemoteInputManager.isRemoteInputActive()).thenReturn(false); @@ -453,8 +478,8 @@ public class NotificationPanelViewTest extends SysuiTestCase { coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController, mFalsingManager, new FalsingCollectorFake(), mNotificationLockscreenUserManager, mNotificationEntryManager, - mKeyguardStateController, mStatusBarStateController, mDozeLog, - mDozeParameters, mCommandQueue, mVibratorHelper, + mCommunalStateController, mKeyguardStateController, mStatusBarStateController, + mDozeLog, mDozeParameters, mCommandQueue, mVibratorHelper, mLatencyTracker, mPowerManager, mAccessibilityManager, 0, mUpdateMonitor, mCommunalSourceMonitor, mMetricsLogger, mActivityManager, mConfigurationController, () -> flingAnimationUtilsBuilder, mStatusBarTouchableRegionManager, @@ -878,6 +903,30 @@ public class NotificationPanelViewTest extends SysuiTestCase { assertThat(sourceCapture.getValue()).isEqualTo(null); } + @Test + public void testKeyguardStatusViewUpdatedWithCommunalPresence() { + givenViewAttached(); + + when(mResources.getBoolean( + com.android.internal.R.bool.config_keyguardUserSwitcher)).thenReturn(true); + updateMultiUserSetting(true); + + ArgumentCaptor<CommunalStateController.Callback> communalCallbackCapture = + ArgumentCaptor.forClass(CommunalStateController.Callback.class); + verify(mCommunalStateController).addCallback(communalCallbackCapture.capture()); + final CommunalStateController.Callback communalStateControllerCallback = + communalCallbackCapture.getValue(); + + clearInvocations(mKeyguardStatusViewController, mKeyguardUserSwitcherController); + // Ensure changes in communal visibility leads to setting the keyguard status view + // visibility. + communalStateControllerCallback.onCommunalViewShowingChanged(); + verify(mKeyguardStatusViewController).setKeyguardStatusViewVisibility(anyInt(), + anyBoolean(), anyBoolean(), anyInt()); + verify(mKeyguardUserSwitcherController).setKeyguardUserSwitcherVisibility(anyInt(), + anyBoolean(), anyBoolean(), anyInt()); + } + private void triggerPositionClockAndNotifications() { mNotificationPanelViewController.closeQs(); } |