diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java index a32b7e3b28360..6964838e7e411 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java @@ -70,6 +70,7 @@ import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback; import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager; import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm; +import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.HeadsUpManager; @@ -93,6 +94,10 @@ public interface NotificationsModule { StackScrollAlgorithm.SectionProvider bindSectionProvider( NotificationSectionsManager impl); + @Binds + StackScrollAlgorithm.BypassController bindBypassController( + KeyguardBypassController impl); + /** Provides an instance of {@link NotificationEntryManager} */ @SysUISingleton @Provides diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java index 197920f7be196..9846b28ba5f9a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java @@ -29,6 +29,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableView; +import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.BypassController; import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider; import javax.inject.Inject; @@ -43,6 +44,7 @@ public class AmbientState { private static final boolean NOTIFICATIONS_HAVE_SHADOWS = false; private final SectionProvider mSectionProvider; + private final BypassController mBypassController; private int mScrollY; private boolean mDimmed; private ActivatableNotificationView mActivatedChild; @@ -152,14 +154,25 @@ public class AmbientState { return mStackHeight; } + /** + * @return Height of notifications panel, with the animation from pulseHeight accounted for. + */ + // TODO(b/192348384): move this logic to getStackHeight, and remove this and getInnerHeight + public float getPulseStackHeight() { + float pulseHeight = Math.min(mPulseHeight, mStackHeight); + return MathUtils.lerp(mStackHeight, pulseHeight, mDozeAmount); + } + /** Tracks the state from AlertingNotificationManager#hasNotifications() */ private boolean mHasAlertEntries; @Inject public AmbientState( Context context, - @NonNull SectionProvider sectionProvider) { + @NonNull SectionProvider sectionProvider, + @NonNull BypassController bypassController) { mSectionProvider = sectionProvider; + mBypassController = bypassController; reload(context); } @@ -297,6 +310,13 @@ public class AmbientState { } } + /** + * Is bypass currently enabled? + */ + public boolean isBypassEnabled() { + return mBypassController.isBypassEnabled(); + } + public float getOverScrollAmount(boolean top) { return top ? mOverScrollTopAmount : mOverScrollBottomAmount; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java index 3fc8b8d9aef11..e65038b32bf0f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java @@ -421,10 +421,20 @@ public class StackScrollAlgorithm { // When pulsing (incoming notification on AOD), innerHeight is 0; clamp all // to shelf start, thereby hiding all notifications (except the first one, which // we later unhide in updatePulsingState) - final int stackBottom = - !ambientState.isShadeExpanded() || ambientState.isDozing() - ? ambientState.getInnerHeight() - : (int) ambientState.getStackHeight(); + // TODO(b/192348384): merge InnerHeight with StackHeight + final int stackBottom; + if (ambientState.isBypassEnabled()) { + // We want to use the stackHeight when pulse expanding, since the animation + // isn't currently optimized if the pulseHeight is continuously changing + // Let's improve this when we're merging the heights above + stackBottom = ambientState.isPulseExpanding() + ? (int) ambientState.getStackHeight() + : ambientState.getInnerHeight(); + } else { + stackBottom = !ambientState.isShadeExpanded() || ambientState.isDozing() + ? ambientState.getInnerHeight() + : (int) ambientState.getPulseStackHeight(); + } final int shelfStart = stackBottom - ambientState.getShelf().getIntrinsicHeight(); viewState.yTranslation = Math.min(viewState.yTranslation, shelfStart); @@ -742,4 +752,14 @@ public class StackScrollAlgorithm { */ boolean beginsSection(@NonNull View view, @Nullable View previous); } + + /** + * Interface for telling the StackScrollAlgorithm information about the bypass state + */ + public interface BypassController { + /** + * True if bypass is enabled. Note that this is always false if face auth is not enabled. + */ + boolean isBypassEnabled(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt index c9d08427c8caa..2cb0a3a289019 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt @@ -28,6 +28,7 @@ import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.NotificationLockscreenUserManager import com.android.systemui.statusbar.StatusBarState +import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.tuner.TunerService import java.io.FileDescriptor @@ -35,7 +36,7 @@ import java.io.PrintWriter import javax.inject.Inject @SysUISingleton -open class KeyguardBypassController : Dumpable { +open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassController { private val mKeyguardStateController: KeyguardStateController private val statusBarStateController: StatusBarStateController @@ -67,6 +68,9 @@ open class KeyguardBypassController : Dumpable { lateinit var unlockController: BiometricUnlockController var isPulseExpanding = false + /** delegates to [bypassEnabled] but conforms to [StackScrollAlgorithm.BypassController] */ + override fun isBypassEnabled() = bypassEnabled + /** * If face unlock dismisses the lock screen or keeps user on keyguard for the current user. */ diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java index 04d7b7261ba72..b03df880f0baa 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java @@ -64,6 +64,7 @@ import com.android.systemui.statusbar.notification.collection.legacy.Notificatio import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.FooterView; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.KeyguardBypassEnabledProvider; +import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; @@ -101,6 +102,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { @Mock private RemoteInputController mRemoteInputController; @Mock private NotificationRoundnessManager mNotificationRoundnessManager; @Mock private KeyguardBypassEnabledProvider mKeyguardBypassEnabledProvider; + @Mock private KeyguardBypassController mBypassController; @Mock private NotificationSectionsManager mNotificationSectionsManager; @Mock private NotificationSection mNotificationSection; @Mock private SysuiStatusBarStateController mStatusBarStateController; @@ -132,7 +134,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController); // Interact with real instance of AmbientState. - mAmbientState = new AmbientState(mContext, mNotificationSectionsManager); + mAmbientState = new AmbientState(mContext, mNotificationSectionsManager, mBypassController); // The actual class under test. You may need to work with this class directly when // testing anonymous class members of mStackScroller, like mMenuEventListener,