Loading packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +30 −7 Original line number Original line Diff line number Diff line Loading @@ -625,7 +625,6 @@ public final class NotificationPanelViewController implements Dumpable { private float mLastGesturedOverExpansion = -1; private float mLastGesturedOverExpansion = -1; /** Whether the current animator is the spring back animation. */ /** Whether the current animator is the spring back animation. */ private boolean mIsSpringBackAnimation; private boolean mIsSpringBackAnimation; private boolean mInSplitShade; private float mHintDistance; private float mHintDistance; private float mInitialOffsetOnTouch; private float mInitialOffsetOnTouch; private boolean mCollapsedAndHeadsUpOnDown; private boolean mCollapsedAndHeadsUpOnDown; Loading Loading @@ -1061,7 +1060,6 @@ public final class NotificationPanelViewController implements Dumpable { mSlopMultiplier = configuration.getScaledAmbiguousGestureMultiplier(); mSlopMultiplier = configuration.getScaledAmbiguousGestureMultiplier(); mHintDistance = mResources.getDimension(R.dimen.hint_move_distance); mHintDistance = mResources.getDimension(R.dimen.hint_move_distance); mPanelFlingOvershootAmount = mResources.getDimension(R.dimen.panel_overshoot_amount); mPanelFlingOvershootAmount = mResources.getDimension(R.dimen.panel_overshoot_amount); mInSplitShade = mResources.getBoolean(R.bool.config_use_split_notification_shade); mFlingAnimationUtils = mFlingAnimationUtilsBuilder.get() mFlingAnimationUtils = mFlingAnimationUtilsBuilder.get() .setMaxLengthSeconds(0.4f).build(); .setMaxLengthSeconds(0.4f).build(); mStatusBarMinHeight = SystemBarUtils.getStatusBarHeight(mView.getContext()); mStatusBarMinHeight = SystemBarUtils.getStatusBarHeight(mView.getContext()); Loading Loading @@ -1836,6 +1834,10 @@ public final class NotificationPanelViewController implements Dumpable { public void closeQs() { public void closeQs() { cancelQsAnimation(); cancelQsAnimation(); setQsExpansionHeight(mQsMinExpansionHeight); setQsExpansionHeight(mQsMinExpansionHeight); // qsExpandImmediate is a safety latch in case we're calling closeQS while we're in the // middle of animation - we need to make sure that value is always false when shade if // fully collapsed or expanded setQsExpandImmediate(false); } } @VisibleForTesting @VisibleForTesting Loading Loading @@ -1938,7 +1940,7 @@ public final class NotificationPanelViewController implements Dumpable { // we want to perform an overshoot animation when flinging open // we want to perform an overshoot animation when flinging open final boolean addOverscroll = final boolean addOverscroll = expand expand && !mInSplitShade // Split shade has its own overscroll logic && !mSplitShadeEnabled // Split shade has its own overscroll logic && mStatusBarStateController.getState() != KEYGUARD && mStatusBarStateController.getState() != KEYGUARD && mOverExpansion == 0.0f && mOverExpansion == 0.0f && vel >= 0; && vel >= 0; Loading Loading @@ -2727,8 +2729,10 @@ public final class NotificationPanelViewController implements Dumpable { * as well based on the bounds of the shade and QS state. * as well based on the bounds of the shade and QS state. */ */ private void setQSClippingBounds() { private void setQSClippingBounds() { final int qsPanelBottomY = calculateQsBottomPosition(computeQsExpansionFraction()); float qsExpansionFraction = computeQsExpansionFraction(); final boolean qsVisible = (computeQsExpansionFraction() > 0 || qsPanelBottomY > 0); final int qsPanelBottomY = calculateQsBottomPosition(qsExpansionFraction); final boolean qsVisible = (qsExpansionFraction > 0 || qsPanelBottomY > 0); checkCorrectScrimVisibility(qsExpansionFraction); int top = calculateTopQsClippingBound(qsPanelBottomY); int top = calculateTopQsClippingBound(qsPanelBottomY); int bottom = calculateBottomQsClippingBound(top); int bottom = calculateBottomQsClippingBound(top); Loading @@ -2739,6 +2743,19 @@ public final class NotificationPanelViewController implements Dumpable { applyQSClippingBounds(left, top, right, bottom, qsVisible); applyQSClippingBounds(left, top, right, bottom, qsVisible); } } private void checkCorrectScrimVisibility(float expansionFraction) { // issues with scrims visible on keyguard occur only in split shade if (mSplitShadeEnabled) { boolean keyguardViewsVisible = mBarState == KEYGUARD && mKeyguardOnlyContentAlpha == 1; // expansionFraction == 1 means scrims are fully visible as their size/visibility depend // on QS expansion if (expansionFraction == 1 && keyguardViewsVisible) { Log.wtf(TAG, "Incorrect state, scrim is visible at the same time when clock is visible"); } } } private int calculateTopQsClippingBound(int qsPanelBottomY) { private int calculateTopQsClippingBound(int qsPanelBottomY) { int top; int top; if (mSplitShadeEnabled) { if (mSplitShadeEnabled) { Loading Loading @@ -4393,7 +4410,7 @@ public final class NotificationPanelViewController implements Dumpable { ipw.print("mPanelFlingOvershootAmount="); ipw.println(mPanelFlingOvershootAmount); ipw.print("mPanelFlingOvershootAmount="); ipw.println(mPanelFlingOvershootAmount); ipw.print("mLastGesturedOverExpansion="); ipw.println(mLastGesturedOverExpansion); ipw.print("mLastGesturedOverExpansion="); ipw.println(mLastGesturedOverExpansion); ipw.print("mIsSpringBackAnimation="); ipw.println(mIsSpringBackAnimation); ipw.print("mIsSpringBackAnimation="); ipw.println(mIsSpringBackAnimation); ipw.print("mInSplitShade="); ipw.println(mInSplitShade); ipw.print("mSplitShadeEnabled="); ipw.println(mSplitShadeEnabled); ipw.print("mHintDistance="); ipw.println(mHintDistance); ipw.print("mHintDistance="); ipw.println(mHintDistance); ipw.print("mInitialOffsetOnTouch="); ipw.println(mInitialOffsetOnTouch); ipw.print("mInitialOffsetOnTouch="); ipw.println(mInitialOffsetOnTouch); ipw.print("mCollapsedAndHeadsUpOnDown="); ipw.println(mCollapsedAndHeadsUpOnDown); ipw.print("mCollapsedAndHeadsUpOnDown="); ipw.println(mCollapsedAndHeadsUpOnDown); Loading Loading @@ -4911,7 +4928,7 @@ public final class NotificationPanelViewController implements Dumpable { float maxPanelHeight = getMaxPanelTransitionDistance(); float maxPanelHeight = getMaxPanelTransitionDistance(); if (mHeightAnimator == null) { if (mHeightAnimator == null) { // Split shade has its own overscroll logic // Split shade has its own overscroll logic if (mTracking && !mInSplitShade) { if (mTracking && !mSplitShadeEnabled) { float overExpansionPixels = Math.max(0, h - maxPanelHeight); float overExpansionPixels = Math.max(0, h - maxPanelHeight); setOverExpansionInternal(overExpansionPixels, true /* isFromGesture */); setOverExpansionInternal(overExpansionPixels, true /* isFromGesture */); } } Loading Loading @@ -5459,6 +5476,12 @@ public final class NotificationPanelViewController implements Dumpable { // - from SHADE to KEYGUARD // - from SHADE to KEYGUARD // - from SHADE_LOCKED to SHADE // - from SHADE_LOCKED to SHADE // - getting notified again about the current SHADE or KEYGUARD state // - getting notified again about the current SHADE or KEYGUARD state if (mSplitShadeEnabled && oldState == SHADE && statusBarState == KEYGUARD) { // user can go to keyguard from different shade states and closing animation // may not fully run - we always want to make sure we close QS when that happens // as we never need QS open in fresh keyguard state closeQs(); } final boolean animatingUnlockedShadeToKeyguard = oldState == SHADE final boolean animatingUnlockedShadeToKeyguard = oldState == SHADE && statusBarState == KEYGUARD && statusBarState == KEYGUARD && mScreenOffAnimationController.isKeyguardShowDelayed(); && mScreenOffAnimationController.isKeyguardShowDelayed(); Loading packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java +13 −0 Original line number Original line Diff line number Diff line Loading @@ -1118,6 +1118,19 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { assertThat(mStatusBarStateController.getState()).isEqualTo(SHADE_LOCKED); assertThat(mStatusBarStateController.getState()).isEqualTo(SHADE_LOCKED); } } @Test public void testUnlockedSplitShadeTransitioningToKeyguard_closesQS() { enableSplitShade(true); mStatusBarStateController.setState(SHADE); mNotificationPanelViewController.setQsExpanded(true); mStatusBarStateController.setState(KEYGUARD); assertThat(mNotificationPanelViewController.isQsExpanded()).isEqualTo(false); assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isEqualTo(false); } @Test @Test public void testSwitchesToCorrectClockInSinglePaneShade() { public void testSwitchesToCorrectClockInSinglePaneShade() { mStatusBarStateController.setState(KEYGUARD); mStatusBarStateController.setState(KEYGUARD); Loading Loading
packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +30 −7 Original line number Original line Diff line number Diff line Loading @@ -625,7 +625,6 @@ public final class NotificationPanelViewController implements Dumpable { private float mLastGesturedOverExpansion = -1; private float mLastGesturedOverExpansion = -1; /** Whether the current animator is the spring back animation. */ /** Whether the current animator is the spring back animation. */ private boolean mIsSpringBackAnimation; private boolean mIsSpringBackAnimation; private boolean mInSplitShade; private float mHintDistance; private float mHintDistance; private float mInitialOffsetOnTouch; private float mInitialOffsetOnTouch; private boolean mCollapsedAndHeadsUpOnDown; private boolean mCollapsedAndHeadsUpOnDown; Loading Loading @@ -1061,7 +1060,6 @@ public final class NotificationPanelViewController implements Dumpable { mSlopMultiplier = configuration.getScaledAmbiguousGestureMultiplier(); mSlopMultiplier = configuration.getScaledAmbiguousGestureMultiplier(); mHintDistance = mResources.getDimension(R.dimen.hint_move_distance); mHintDistance = mResources.getDimension(R.dimen.hint_move_distance); mPanelFlingOvershootAmount = mResources.getDimension(R.dimen.panel_overshoot_amount); mPanelFlingOvershootAmount = mResources.getDimension(R.dimen.panel_overshoot_amount); mInSplitShade = mResources.getBoolean(R.bool.config_use_split_notification_shade); mFlingAnimationUtils = mFlingAnimationUtilsBuilder.get() mFlingAnimationUtils = mFlingAnimationUtilsBuilder.get() .setMaxLengthSeconds(0.4f).build(); .setMaxLengthSeconds(0.4f).build(); mStatusBarMinHeight = SystemBarUtils.getStatusBarHeight(mView.getContext()); mStatusBarMinHeight = SystemBarUtils.getStatusBarHeight(mView.getContext()); Loading Loading @@ -1836,6 +1834,10 @@ public final class NotificationPanelViewController implements Dumpable { public void closeQs() { public void closeQs() { cancelQsAnimation(); cancelQsAnimation(); setQsExpansionHeight(mQsMinExpansionHeight); setQsExpansionHeight(mQsMinExpansionHeight); // qsExpandImmediate is a safety latch in case we're calling closeQS while we're in the // middle of animation - we need to make sure that value is always false when shade if // fully collapsed or expanded setQsExpandImmediate(false); } } @VisibleForTesting @VisibleForTesting Loading Loading @@ -1938,7 +1940,7 @@ public final class NotificationPanelViewController implements Dumpable { // we want to perform an overshoot animation when flinging open // we want to perform an overshoot animation when flinging open final boolean addOverscroll = final boolean addOverscroll = expand expand && !mInSplitShade // Split shade has its own overscroll logic && !mSplitShadeEnabled // Split shade has its own overscroll logic && mStatusBarStateController.getState() != KEYGUARD && mStatusBarStateController.getState() != KEYGUARD && mOverExpansion == 0.0f && mOverExpansion == 0.0f && vel >= 0; && vel >= 0; Loading Loading @@ -2727,8 +2729,10 @@ public final class NotificationPanelViewController implements Dumpable { * as well based on the bounds of the shade and QS state. * as well based on the bounds of the shade and QS state. */ */ private void setQSClippingBounds() { private void setQSClippingBounds() { final int qsPanelBottomY = calculateQsBottomPosition(computeQsExpansionFraction()); float qsExpansionFraction = computeQsExpansionFraction(); final boolean qsVisible = (computeQsExpansionFraction() > 0 || qsPanelBottomY > 0); final int qsPanelBottomY = calculateQsBottomPosition(qsExpansionFraction); final boolean qsVisible = (qsExpansionFraction > 0 || qsPanelBottomY > 0); checkCorrectScrimVisibility(qsExpansionFraction); int top = calculateTopQsClippingBound(qsPanelBottomY); int top = calculateTopQsClippingBound(qsPanelBottomY); int bottom = calculateBottomQsClippingBound(top); int bottom = calculateBottomQsClippingBound(top); Loading @@ -2739,6 +2743,19 @@ public final class NotificationPanelViewController implements Dumpable { applyQSClippingBounds(left, top, right, bottom, qsVisible); applyQSClippingBounds(left, top, right, bottom, qsVisible); } } private void checkCorrectScrimVisibility(float expansionFraction) { // issues with scrims visible on keyguard occur only in split shade if (mSplitShadeEnabled) { boolean keyguardViewsVisible = mBarState == KEYGUARD && mKeyguardOnlyContentAlpha == 1; // expansionFraction == 1 means scrims are fully visible as their size/visibility depend // on QS expansion if (expansionFraction == 1 && keyguardViewsVisible) { Log.wtf(TAG, "Incorrect state, scrim is visible at the same time when clock is visible"); } } } private int calculateTopQsClippingBound(int qsPanelBottomY) { private int calculateTopQsClippingBound(int qsPanelBottomY) { int top; int top; if (mSplitShadeEnabled) { if (mSplitShadeEnabled) { Loading Loading @@ -4393,7 +4410,7 @@ public final class NotificationPanelViewController implements Dumpable { ipw.print("mPanelFlingOvershootAmount="); ipw.println(mPanelFlingOvershootAmount); ipw.print("mPanelFlingOvershootAmount="); ipw.println(mPanelFlingOvershootAmount); ipw.print("mLastGesturedOverExpansion="); ipw.println(mLastGesturedOverExpansion); ipw.print("mLastGesturedOverExpansion="); ipw.println(mLastGesturedOverExpansion); ipw.print("mIsSpringBackAnimation="); ipw.println(mIsSpringBackAnimation); ipw.print("mIsSpringBackAnimation="); ipw.println(mIsSpringBackAnimation); ipw.print("mInSplitShade="); ipw.println(mInSplitShade); ipw.print("mSplitShadeEnabled="); ipw.println(mSplitShadeEnabled); ipw.print("mHintDistance="); ipw.println(mHintDistance); ipw.print("mHintDistance="); ipw.println(mHintDistance); ipw.print("mInitialOffsetOnTouch="); ipw.println(mInitialOffsetOnTouch); ipw.print("mInitialOffsetOnTouch="); ipw.println(mInitialOffsetOnTouch); ipw.print("mCollapsedAndHeadsUpOnDown="); ipw.println(mCollapsedAndHeadsUpOnDown); ipw.print("mCollapsedAndHeadsUpOnDown="); ipw.println(mCollapsedAndHeadsUpOnDown); Loading Loading @@ -4911,7 +4928,7 @@ public final class NotificationPanelViewController implements Dumpable { float maxPanelHeight = getMaxPanelTransitionDistance(); float maxPanelHeight = getMaxPanelTransitionDistance(); if (mHeightAnimator == null) { if (mHeightAnimator == null) { // Split shade has its own overscroll logic // Split shade has its own overscroll logic if (mTracking && !mInSplitShade) { if (mTracking && !mSplitShadeEnabled) { float overExpansionPixels = Math.max(0, h - maxPanelHeight); float overExpansionPixels = Math.max(0, h - maxPanelHeight); setOverExpansionInternal(overExpansionPixels, true /* isFromGesture */); setOverExpansionInternal(overExpansionPixels, true /* isFromGesture */); } } Loading Loading @@ -5459,6 +5476,12 @@ public final class NotificationPanelViewController implements Dumpable { // - from SHADE to KEYGUARD // - from SHADE to KEYGUARD // - from SHADE_LOCKED to SHADE // - from SHADE_LOCKED to SHADE // - getting notified again about the current SHADE or KEYGUARD state // - getting notified again about the current SHADE or KEYGUARD state if (mSplitShadeEnabled && oldState == SHADE && statusBarState == KEYGUARD) { // user can go to keyguard from different shade states and closing animation // may not fully run - we always want to make sure we close QS when that happens // as we never need QS open in fresh keyguard state closeQs(); } final boolean animatingUnlockedShadeToKeyguard = oldState == SHADE final boolean animatingUnlockedShadeToKeyguard = oldState == SHADE && statusBarState == KEYGUARD && statusBarState == KEYGUARD && mScreenOffAnimationController.isKeyguardShowDelayed(); && mScreenOffAnimationController.isKeyguardShowDelayed(); Loading
packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java +13 −0 Original line number Original line Diff line number Diff line Loading @@ -1118,6 +1118,19 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { assertThat(mStatusBarStateController.getState()).isEqualTo(SHADE_LOCKED); assertThat(mStatusBarStateController.getState()).isEqualTo(SHADE_LOCKED); } } @Test public void testUnlockedSplitShadeTransitioningToKeyguard_closesQS() { enableSplitShade(true); mStatusBarStateController.setState(SHADE); mNotificationPanelViewController.setQsExpanded(true); mStatusBarStateController.setState(KEYGUARD); assertThat(mNotificationPanelViewController.isQsExpanded()).isEqualTo(false); assertThat(mNotificationPanelViewController.isQsExpandImmediate()).isEqualTo(false); } @Test @Test public void testSwitchesToCorrectClockInSinglePaneShade() { public void testSwitchesToCorrectClockInSinglePaneShade() { mStatusBarStateController.setState(KEYGUARD); mStatusBarStateController.setState(KEYGUARD); Loading