Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +19 −19 Original line number Diff line number Diff line Loading @@ -155,7 +155,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable * gap is drawn between them). In this case we don't want to round their corners. */ private static final int DISTANCE_BETWEEN_ADJACENT_SECTIONS_PX = 1; private KeyguardBypassEnabledProvider mKeyguardBypassEnabledProvider; private boolean mKeyguardBypassEnabled; private ExpandHelper mExpandHelper; private NotificationSwipeHelper mSwipeHelper; Loading Loading @@ -649,13 +649,21 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable inflateFooterView(); } /** * Sets whether keyguard bypass is enabled. If true, this layout will be rendered in bypass * mode when it is on the keyguard. */ public void setKeyguardBypassEnabled(boolean isEnabled) { mKeyguardBypassEnabled = isEnabled; } /** * @return the height at which we will wake up when pulsing */ public float getWakeUpHeight() { ExpandableView firstChild = getFirstChildWithBackground(); if (firstChild != null) { if (mKeyguardBypassEnabledProvider.getBypassEnabled()) { if (mKeyguardBypassEnabled) { return firstChild.getHeadsUpHeightWithoutHeader(); } else { return firstChild.getCollapsedHeight(); Loading Loading @@ -783,7 +791,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } } boolean shouldDrawBackground; if (mKeyguardBypassEnabledProvider.getBypassEnabled() && onKeyguard()) { if (mKeyguardBypassEnabled && onKeyguard()) { shouldDrawBackground = isPulseExpanding(); } else { shouldDrawBackground = !mAmbientState.isDozing() || anySectionHasVisibleChild; Loading Loading @@ -898,15 +906,12 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } private void reinitView() { initView(getContext(), mKeyguardBypassEnabledProvider, mSwipeHelper); initView(getContext(), mSwipeHelper); } @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) void initView(Context context, KeyguardBypassEnabledProvider keyguardBypassEnabledProvider, NotificationSwipeHelper swipeHelper) { void initView(Context context, NotificationSwipeHelper swipeHelper) { mScroller = new OverScroller(getContext()); mKeyguardBypassEnabledProvider = keyguardBypassEnabledProvider; mSwipeHelper = swipeHelper; setDescendantFocusability(FOCUS_AFTER_DESCENDANTS); Loading Loading @@ -1346,7 +1351,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private void notifyAppearChangedListeners() { float appear; float expandAmount; if (mKeyguardBypassEnabledProvider.getBypassEnabled() && onKeyguard()) { if (mKeyguardBypassEnabled && onKeyguard()) { appear = calculateAppearFractionBypass(); expandAmount = getPulseHeight(); } else { Loading Loading @@ -2384,8 +2389,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable minTopPosition = firstVisibleSection.getBounds().top; } boolean shiftPulsingWithFirst = mNumHeadsUp <= 1 && (mAmbientState.isDozing() || (mKeyguardBypassEnabledProvider.getBypassEnabled() && onKeyguard)); && (mAmbientState.isDozing() || (mKeyguardBypassEnabled && onKeyguard)); for (NotificationSection section : mSections) { int minBottomPosition = minTopPosition; if (section == lastSection) { Loading Loading @@ -2528,7 +2532,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } else { mTopPaddingOverflow = 0; } setTopPadding(topPadding, animate && !mKeyguardBypassEnabledProvider.getBypassEnabled()); setTopPadding(topPadding, animate && !mKeyguardBypassEnabled); setExpandedHeight(mExpandedHeight); } Loading Loading @@ -3092,7 +3096,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable boolean performDisappearAnimation = !mIsExpanded // Only animate if we still have pinned heads up, otherwise we just have the // regular collapse animation of the lock screen || (mKeyguardBypassEnabledProvider.getBypassEnabled() && onKeyguard() || (mKeyguardBypassEnabled && onKeyguard() && mInHeadsUpPinnedMode); if (performDisappearAnimation && !isHeadsUp) { type = row.wasJustClicked() Loading Loading @@ -4315,7 +4319,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable // Since we are clipping to the outline we need to make sure that the shadows aren't // clipped when pulsing float ownTranslationZ = 0; if (mKeyguardBypassEnabledProvider.getBypassEnabled() && mAmbientState.isHiddenAtAll()) { if (mKeyguardBypassEnabled && mAmbientState.isHiddenAtAll()) { ExpandableView firstChildNotGone = getFirstChildNotGone(); if (firstChildNotGone != null && firstChildNotGone.showingPulsing()) { ownTranslationZ = firstChildNotGone.getTranslationZ(); Loading Loading @@ -5138,7 +5142,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable */ public float setPulseHeight(float height) { mAmbientState.setPulseHeight(height); if (mKeyguardBypassEnabledProvider.getBypassEnabled()) { if (mKeyguardBypassEnabled) { notifyAppearChangedListeners(); } requestChildrenUpdate(); Loading Loading @@ -6069,10 +6073,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable /** Only rows where entry.isHighPriority() is false. */ public static final int ROWS_GENTLE = 2; interface KeyguardBypassEnabledProvider { boolean getBypassEnabled(); } interface DismissListener { void onDismiss(@SelectedRows int selectedRows); } Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +4 −2 Original line number Diff line number Diff line Loading @@ -708,8 +708,10 @@ public class NotificationStackScrollLayoutController { }); } mView.initView(mView.getContext(), mKeyguardBypassController::getBypassEnabled, mSwipeHelper); mView.initView(mView.getContext(), mSwipeHelper); mView.setKeyguardBypassEnabled(mKeyguardBypassController.getBypassEnabled()); mKeyguardBypassController .registerOnBypassStateChangedListener(mView::setKeyguardBypassEnabled); mHeadsUpManager.addListener(mOnHeadsUpChangedListener); mHeadsUpManager.setAnimationStateHandler(mView::setHeadsUpGoingAwayAnimationsAllowed); Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt +37 −1 Original line number Diff line number Diff line Loading @@ -43,6 +43,11 @@ open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassContr @BypassOverride private val bypassOverride: Int private var hasFaceFeature: Boolean private var pendingUnlock: PendingUnlock? = null private val listeners = mutableListOf<OnBypassStateChangedListener>() private val faceAuthEnabledChangedCallback = object : KeyguardStateController.Callback { override fun onFaceAuthEnabledChanged() = notifyListeners() } @IntDef( FACE_UNLOCK_BYPASS_NO_OVERRIDE, Loading Loading @@ -83,7 +88,10 @@ open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassContr } return enabled && mKeyguardStateController.isFaceAuthEnabled } private set private set(value) { field = value notifyListeners() } var bouncerShowing: Boolean = false var altBouncerShowing: Boolean = false Loading Loading @@ -140,6 +148,8 @@ open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassContr }) } private fun notifyListeners() = listeners.forEach { it.onBypassStateChanged(bypassEnabled) } /** * Notify that the biometric unlock has happened. * Loading Loading @@ -223,6 +233,32 @@ open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassContr pw.println(" hasFaceFeature: $hasFaceFeature") } /** Registers a listener for bypass state changes. */ fun registerOnBypassStateChangedListener(listener: OnBypassStateChangedListener) { val start = listeners.isEmpty() listeners.add(listener) if (start) { mKeyguardStateController.addCallback(faceAuthEnabledChangedCallback) } } /** * Unregisters a listener for bypass state changes, previous registered with * [registerOnBypassStateChangedListener] */ fun unregisterOnBypassStateChangedListener(listener: OnBypassStateChangedListener) { listeners.remove(listener) if (listeners.isEmpty()) { mKeyguardStateController.removeCallback(faceAuthEnabledChangedCallback) } } /** Listener for bypass state change events. */ interface OnBypassStateChangedListener { /** Invoked when bypass becomes enabled or disabled. */ fun onBypassStateChanged(isEnabled: Boolean) } companion object { const val BYPASS_FADE_DURATION = 67 Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java +6 −0 Original line number Diff line number Diff line Loading @@ -245,5 +245,11 @@ public interface KeyguardStateController extends CallbackController<Callback> { * animation. */ default void onKeyguardDismissAmountChanged() {} /** * Triggered when face auth becomes available or unavailable. Value should be queried with * {@link KeyguardStateController#isFaceAuthEnabled()}. */ default void onFaceAuthEnabledChanged() {} } } packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +1 −4 Original line number Diff line number Diff line Loading @@ -63,7 +63,6 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; 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; Loading Loading @@ -101,7 +100,6 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { @Mock private NotificationRemoteInputManager mRemoteInputManager; @Mock private RemoteInputController mRemoteInputController; @Mock private NotificationRoundnessManager mNotificationRoundnessManager; @Mock private KeyguardBypassEnabledProvider mKeyguardBypassEnabledProvider; @Mock private KeyguardBypassController mBypassController; @Mock private NotificationSectionsManager mNotificationSectionsManager; @Mock private NotificationSection mNotificationSection; Loading Loading @@ -150,8 +148,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { mAmbientState, mFeatureFlags, mUnlockedScreenOffAnimationController); mStackScrollerInternal.initView(getContext(), mKeyguardBypassEnabledProvider, mNotificationSwipeHelper); mStackScrollerInternal.initView(getContext(), mNotificationSwipeHelper); mStackScroller = spy(mStackScrollerInternal); mStackScroller.setShelfController(notificationShelfController); mStackScroller.setStatusBar(mBar); Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +19 −19 Original line number Diff line number Diff line Loading @@ -155,7 +155,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable * gap is drawn between them). In this case we don't want to round their corners. */ private static final int DISTANCE_BETWEEN_ADJACENT_SECTIONS_PX = 1; private KeyguardBypassEnabledProvider mKeyguardBypassEnabledProvider; private boolean mKeyguardBypassEnabled; private ExpandHelper mExpandHelper; private NotificationSwipeHelper mSwipeHelper; Loading Loading @@ -649,13 +649,21 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable inflateFooterView(); } /** * Sets whether keyguard bypass is enabled. If true, this layout will be rendered in bypass * mode when it is on the keyguard. */ public void setKeyguardBypassEnabled(boolean isEnabled) { mKeyguardBypassEnabled = isEnabled; } /** * @return the height at which we will wake up when pulsing */ public float getWakeUpHeight() { ExpandableView firstChild = getFirstChildWithBackground(); if (firstChild != null) { if (mKeyguardBypassEnabledProvider.getBypassEnabled()) { if (mKeyguardBypassEnabled) { return firstChild.getHeadsUpHeightWithoutHeader(); } else { return firstChild.getCollapsedHeight(); Loading Loading @@ -783,7 +791,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } } boolean shouldDrawBackground; if (mKeyguardBypassEnabledProvider.getBypassEnabled() && onKeyguard()) { if (mKeyguardBypassEnabled && onKeyguard()) { shouldDrawBackground = isPulseExpanding(); } else { shouldDrawBackground = !mAmbientState.isDozing() || anySectionHasVisibleChild; Loading Loading @@ -898,15 +906,12 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } private void reinitView() { initView(getContext(), mKeyguardBypassEnabledProvider, mSwipeHelper); initView(getContext(), mSwipeHelper); } @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) void initView(Context context, KeyguardBypassEnabledProvider keyguardBypassEnabledProvider, NotificationSwipeHelper swipeHelper) { void initView(Context context, NotificationSwipeHelper swipeHelper) { mScroller = new OverScroller(getContext()); mKeyguardBypassEnabledProvider = keyguardBypassEnabledProvider; mSwipeHelper = swipeHelper; setDescendantFocusability(FOCUS_AFTER_DESCENDANTS); Loading Loading @@ -1346,7 +1351,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private void notifyAppearChangedListeners() { float appear; float expandAmount; if (mKeyguardBypassEnabledProvider.getBypassEnabled() && onKeyguard()) { if (mKeyguardBypassEnabled && onKeyguard()) { appear = calculateAppearFractionBypass(); expandAmount = getPulseHeight(); } else { Loading Loading @@ -2384,8 +2389,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable minTopPosition = firstVisibleSection.getBounds().top; } boolean shiftPulsingWithFirst = mNumHeadsUp <= 1 && (mAmbientState.isDozing() || (mKeyguardBypassEnabledProvider.getBypassEnabled() && onKeyguard)); && (mAmbientState.isDozing() || (mKeyguardBypassEnabled && onKeyguard)); for (NotificationSection section : mSections) { int minBottomPosition = minTopPosition; if (section == lastSection) { Loading Loading @@ -2528,7 +2532,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } else { mTopPaddingOverflow = 0; } setTopPadding(topPadding, animate && !mKeyguardBypassEnabledProvider.getBypassEnabled()); setTopPadding(topPadding, animate && !mKeyguardBypassEnabled); setExpandedHeight(mExpandedHeight); } Loading Loading @@ -3092,7 +3096,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable boolean performDisappearAnimation = !mIsExpanded // Only animate if we still have pinned heads up, otherwise we just have the // regular collapse animation of the lock screen || (mKeyguardBypassEnabledProvider.getBypassEnabled() && onKeyguard() || (mKeyguardBypassEnabled && onKeyguard() && mInHeadsUpPinnedMode); if (performDisappearAnimation && !isHeadsUp) { type = row.wasJustClicked() Loading Loading @@ -4315,7 +4319,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable // Since we are clipping to the outline we need to make sure that the shadows aren't // clipped when pulsing float ownTranslationZ = 0; if (mKeyguardBypassEnabledProvider.getBypassEnabled() && mAmbientState.isHiddenAtAll()) { if (mKeyguardBypassEnabled && mAmbientState.isHiddenAtAll()) { ExpandableView firstChildNotGone = getFirstChildNotGone(); if (firstChildNotGone != null && firstChildNotGone.showingPulsing()) { ownTranslationZ = firstChildNotGone.getTranslationZ(); Loading Loading @@ -5138,7 +5142,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable */ public float setPulseHeight(float height) { mAmbientState.setPulseHeight(height); if (mKeyguardBypassEnabledProvider.getBypassEnabled()) { if (mKeyguardBypassEnabled) { notifyAppearChangedListeners(); } requestChildrenUpdate(); Loading Loading @@ -6069,10 +6073,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable /** Only rows where entry.isHighPriority() is false. */ public static final int ROWS_GENTLE = 2; interface KeyguardBypassEnabledProvider { boolean getBypassEnabled(); } interface DismissListener { void onDismiss(@SelectedRows int selectedRows); } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +4 −2 Original line number Diff line number Diff line Loading @@ -708,8 +708,10 @@ public class NotificationStackScrollLayoutController { }); } mView.initView(mView.getContext(), mKeyguardBypassController::getBypassEnabled, mSwipeHelper); mView.initView(mView.getContext(), mSwipeHelper); mView.setKeyguardBypassEnabled(mKeyguardBypassController.getBypassEnabled()); mKeyguardBypassController .registerOnBypassStateChangedListener(mView::setKeyguardBypassEnabled); mHeadsUpManager.addListener(mOnHeadsUpChangedListener); mHeadsUpManager.setAnimationStateHandler(mView::setHeadsUpGoingAwayAnimationsAllowed); Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt +37 −1 Original line number Diff line number Diff line Loading @@ -43,6 +43,11 @@ open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassContr @BypassOverride private val bypassOverride: Int private var hasFaceFeature: Boolean private var pendingUnlock: PendingUnlock? = null private val listeners = mutableListOf<OnBypassStateChangedListener>() private val faceAuthEnabledChangedCallback = object : KeyguardStateController.Callback { override fun onFaceAuthEnabledChanged() = notifyListeners() } @IntDef( FACE_UNLOCK_BYPASS_NO_OVERRIDE, Loading Loading @@ -83,7 +88,10 @@ open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassContr } return enabled && mKeyguardStateController.isFaceAuthEnabled } private set private set(value) { field = value notifyListeners() } var bouncerShowing: Boolean = false var altBouncerShowing: Boolean = false Loading Loading @@ -140,6 +148,8 @@ open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassContr }) } private fun notifyListeners() = listeners.forEach { it.onBypassStateChanged(bypassEnabled) } /** * Notify that the biometric unlock has happened. * Loading Loading @@ -223,6 +233,32 @@ open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassContr pw.println(" hasFaceFeature: $hasFaceFeature") } /** Registers a listener for bypass state changes. */ fun registerOnBypassStateChangedListener(listener: OnBypassStateChangedListener) { val start = listeners.isEmpty() listeners.add(listener) if (start) { mKeyguardStateController.addCallback(faceAuthEnabledChangedCallback) } } /** * Unregisters a listener for bypass state changes, previous registered with * [registerOnBypassStateChangedListener] */ fun unregisterOnBypassStateChangedListener(listener: OnBypassStateChangedListener) { listeners.remove(listener) if (listeners.isEmpty()) { mKeyguardStateController.removeCallback(faceAuthEnabledChangedCallback) } } /** Listener for bypass state change events. */ interface OnBypassStateChangedListener { /** Invoked when bypass becomes enabled or disabled. */ fun onBypassStateChanged(isEnabled: Boolean) } companion object { const val BYPASS_FADE_DURATION = 67 Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java +6 −0 Original line number Diff line number Diff line Loading @@ -245,5 +245,11 @@ public interface KeyguardStateController extends CallbackController<Callback> { * animation. */ default void onKeyguardDismissAmountChanged() {} /** * Triggered when face auth becomes available or unavailable. Value should be queried with * {@link KeyguardStateController#isFaceAuthEnabled()}. */ default void onFaceAuthEnabledChanged() {} } }
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +1 −4 Original line number Diff line number Diff line Loading @@ -63,7 +63,6 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; 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; Loading Loading @@ -101,7 +100,6 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { @Mock private NotificationRemoteInputManager mRemoteInputManager; @Mock private RemoteInputController mRemoteInputController; @Mock private NotificationRoundnessManager mNotificationRoundnessManager; @Mock private KeyguardBypassEnabledProvider mKeyguardBypassEnabledProvider; @Mock private KeyguardBypassController mBypassController; @Mock private NotificationSectionsManager mNotificationSectionsManager; @Mock private NotificationSection mNotificationSection; Loading Loading @@ -150,8 +148,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { mAmbientState, mFeatureFlags, mUnlockedScreenOffAnimationController); mStackScrollerInternal.initView(getContext(), mKeyguardBypassEnabledProvider, mNotificationSwipeHelper); mStackScrollerInternal.initView(getContext(), mNotificationSwipeHelper); mStackScroller = spy(mStackScrollerInternal); mStackScroller.setShelfController(notificationShelfController); mStackScroller.setStatusBar(mBar); Loading