summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI
diff options
context:
space:
mode:
authorJorim Jaggi <jjaggi@google.com>2015-01-20 16:45:05 +0100
committerJorim Jaggi <jjaggi@google.com>2015-01-27 16:07:22 +0100
commit1cf6e101263e17c9469c12b4befe36280c109de0 (patch)
tree2125f9686fe2322989a591bb992d64f4e69c26ae /packages/SystemUI
parent318bc929a5732f1ee614ca6ab441f9970bcce091 (diff)
downloadframeworks_base-1cf6e101263e17c9469c12b4befe36280c109de0.zip
frameworks_base-1cf6e101263e17c9469c12b4befe36280c109de0.tar.gz
frameworks_base-1cf6e101263e17c9469c12b4befe36280c109de0.tar.bz2
Show status bar header in SHADE_LOCKED
Makes SHADE_LOCKED more consistent with SHADE in order to avoid confusion about this special state. Add animations between these states for smooth transitions. Bug: 17446409 Change-Id: I410f0ac255abd0f453b77f42c948e814c5dfd838
Diffstat (limited to 'packages/SystemUI')
-rw-r--r--packages/SystemUI/res/layout/keyguard_bottom_area.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java170
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java28
3 files changed, 127 insertions, 74 deletions
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 4cf4f52d..01b2713 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -21,7 +21,8 @@
android:id="@+id/keyguard_bottom_area"
android:layout_height="match_parent"
android:layout_width="match_parent"
- >
+ android:outlineProvider="none"
+ android:elevation="5dp" > <!-- Put it above the status bar header -->
<com.android.systemui.statusbar.phone.KeyguardIndicationTextView
android:id="@+id/keyguard_indication_text"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index a2ff64a..b12b90e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -112,6 +112,7 @@ public class NotificationPanelView extends PanelView implements
private boolean mQsFullyExpanded;
private boolean mKeyguardShowing;
private boolean mDozing;
+ private boolean mDozingOnDown;
private int mStatusBarState;
private float mInitialHeightOnTouch;
private float mInitialTouchX;
@@ -162,7 +163,7 @@ public class NotificationPanelView extends PanelView implements
private Runnable mLaunchAnimationEndRunnable;
private boolean mOnlyAffordanceInThisMotion;
private boolean mKeyguardStatusViewAnimating;
- private boolean mHeaderAnimatingIn;
+ private boolean mHeaderAnimating;
private ObjectAnimator mQsContainerAnimator;
private ValueAnimator mQsSizeChangeAnimator;
@@ -221,9 +222,8 @@ public class NotificationPanelView extends PanelView implements
// recompute internal state when qspanel height changes
mQsContainer.addOnLayoutChangeListener(new OnLayoutChangeListener() {
@Override
- public void onLayoutChange(View v, int left, int top, int right,
- int bottom, int oldLeft, int oldTop, int oldRight,
- int oldBottom) {
+ public void onLayoutChange(View v, int left, int top, int right, int bottom,
+ int oldLeft, int oldTop, int oldRight, int oldBottom) {
final int height = bottom - top;
final int oldHeight = oldBottom - oldTop;
if (height != oldHeight) {
@@ -500,7 +500,7 @@ public class NotificationPanelView extends PanelView implements
if (mBlockTouches) {
return false;
}
- resetDownStates(event);
+ initDownStates(event);
int pointerIndex = event.findPointerIndex(mTrackingPointer);
if (pointerIndex < 0) {
pointerIndex = 0;
@@ -586,10 +586,11 @@ public class NotificationPanelView extends PanelView implements
&& x < stackScrollerX + mNotificationStackScroller.getWidth();
}
- private void resetDownStates(MotionEvent event) {
+ private void initDownStates(MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
mOnlyAffordanceInThisMotion = false;
mQsTouchAboveFalsingThreshold = mQsFullyExpanded;
+ mDozingOnDown = isDozing();
}
}
@@ -634,7 +635,7 @@ public class NotificationPanelView extends PanelView implements
if (mBlockTouches) {
return false;
}
- resetDownStates(event);
+ initDownStates(event);
if ((!mIsExpanding || mHintAnimationRunning)
&& !mQsExpanded
&& mStatusBar.getBarState() != StatusBarState.SHADE) {
@@ -865,26 +866,28 @@ public class NotificationPanelView extends PanelView implements
public void setBarState(int statusBarState, boolean keyguardFadingAway,
boolean goingToFullShade) {
- boolean keyguardShowing = statusBarState == StatusBarState.KEYGUARD
- || statusBarState == StatusBarState.SHADE_LOCKED;
- if (!mKeyguardShowing && keyguardShowing) {
- setQsTranslation(mQsExpansionHeight);
- mHeader.setTranslationY(0f);
- }
+ int oldState = mStatusBarState;
+ boolean keyguardShowing = statusBarState == StatusBarState.KEYGUARD;
setKeyguardStatusViewVisibility(statusBarState, keyguardFadingAway, goingToFullShade);
setKeyguardBottomAreaVisibility(statusBarState, goingToFullShade);
- if (goingToFullShade) {
+
+ mStatusBarState = statusBarState;
+ mKeyguardShowing = keyguardShowing;
+
+ if (goingToFullShade || (oldState == StatusBarState.KEYGUARD
+ && statusBarState == StatusBarState.SHADE_LOCKED)) {
animateKeyguardStatusBarOut();
+ animateHeaderSlidingIn();
+ } else if (oldState == StatusBarState.SHADE_LOCKED
+ && statusBarState == StatusBarState.KEYGUARD) {
+ animateKeyguardStatusBarIn(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+ animateHeaderSlidingOut();
} else {
mKeyguardStatusBar.setAlpha(1f);
mKeyguardStatusBar.setVisibility(keyguardShowing ? View.VISIBLE : View.INVISIBLE);
}
- mStatusBarState = statusBarState;
- mKeyguardShowing = keyguardShowing;
+
updateQsState();
- if (goingToFullShade) {
- animateHeaderSlidingIn();
- }
}
private final Runnable mAnimateKeyguardStatusViewInvisibleEndRunnable = new Runnable() {
@@ -906,7 +909,7 @@ public class NotificationPanelView extends PanelView implements
= new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- mHeaderAnimatingIn = false;
+ mHeaderAnimating = false;
mQsContainerAnimator = null;
mQsContainer.removeOnLayoutChangeListener(mQsContainerAnimatorUpdater);
}
@@ -934,10 +937,13 @@ public class NotificationPanelView extends PanelView implements
@Override
public boolean onPreDraw() {
getViewTreeObserver().removeOnPreDrawListener(this);
+ long delay = mStatusBarState == StatusBarState.SHADE_LOCKED
+ ? 0
+ : mStatusBar.calculateGoingToFullShadeDelay();
mHeader.setTranslationY(-mHeader.getCollapsedHeight() - mQsPeekHeight);
mHeader.animate()
.translationY(0f)
- .setStartDelay(mStatusBar.calculateGoingToFullShadeDelay())
+ .setStartDelay(delay)
.setDuration(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE)
.setInterpolator(mFastOutSlowInInterpolator)
.start();
@@ -946,7 +952,7 @@ public class NotificationPanelView extends PanelView implements
mQsContainer.getTranslationY(),
mHeader.getCollapsedHeight() + mQsPeekHeight - mQsContainer.getHeight()
- mQsContainer.getTop());
- mQsContainerAnimator.setStartDelay(mStatusBar.calculateGoingToFullShadeDelay());
+ mQsContainerAnimator.setStartDelay(delay);
mQsContainerAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
mQsContainerAnimator.setInterpolator(mFastOutSlowInInterpolator);
mQsContainerAnimator.addListener(mAnimateHeaderSlidingInListener);
@@ -955,11 +961,33 @@ public class NotificationPanelView extends PanelView implements
return true;
}
};
-
+
private void animateHeaderSlidingIn() {
- mHeaderAnimatingIn = true;
+ mHeaderAnimating = true;
getViewTreeObserver().addOnPreDrawListener(mStartHeaderSlidingIn);
+ }
+ private void animateHeaderSlidingOut() {
+ mHeaderAnimating = true;
+ mHeader.animate().y(-mHeader.getHeight())
+ .setStartDelay(0)
+ .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD)
+ .setInterpolator(mFastOutSlowInInterpolator)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mHeader.animate().setListener(null);
+ mHeaderAnimating = false;
+ updateQsState();
+ }
+ })
+ .start();
+ mQsContainer.animate()
+ .y(-mQsContainer.getHeight())
+ .setStartDelay(0)
+ .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD)
+ .setInterpolator(mFastOutSlowInInterpolator)
+ .start();
}
private final Runnable mAnimateKeyguardStatusBarInvisibleEndRunnable = new Runnable() {
@@ -974,8 +1002,12 @@ public class NotificationPanelView extends PanelView implements
private void animateKeyguardStatusBarOut() {
mKeyguardStatusBar.animate()
.alpha(0f)
- .setStartDelay(mStatusBar.getKeyguardFadingAwayDelay())
- .setDuration(mStatusBar.getKeyguardFadingAwayDuration()/2)
+ .setStartDelay(mStatusBar.isKeyguardFadingAway()
+ ? mStatusBar.getKeyguardFadingAwayDelay()
+ : 0)
+ .setDuration(mStatusBar.isKeyguardFadingAway()
+ ? mStatusBar.getKeyguardFadingAwayDuration() / 2
+ : StackStateAnimator.ANIMATION_DURATION_STANDARD)
.setInterpolator(PhoneStatusBar.ALPHA_OUT)
.setUpdateListener(mStatusBarAnimateAlphaListener)
.withEndAction(mAnimateKeyguardStatusBarInvisibleEndRunnable)
@@ -990,13 +1022,13 @@ public class NotificationPanelView extends PanelView implements
}
};
- private void animateKeyguardStatusBarIn() {
+ private void animateKeyguardStatusBarIn(long duration) {
mKeyguardStatusBar.setVisibility(View.VISIBLE);
mKeyguardStatusBar.setAlpha(0f);
mKeyguardStatusBar.animate()
.alpha(1f)
.setStartDelay(0)
- .setDuration(DOZE_ANIMATION_DURATION)
+ .setDuration(duration)
.setInterpolator(mDozeAnimationInterpolator)
.setUpdateListener(mStatusBarAnimateAlphaListener)
.start();
@@ -1076,9 +1108,12 @@ public class NotificationPanelView extends PanelView implements
}
private void updateQsState() {
- boolean expandVisually = mQsExpanded || mStackScrollerOverscrolling;
- mHeader.setVisibility((mQsExpanded || !mKeyguardShowing) ? View.VISIBLE : View.INVISIBLE);
- mHeader.setExpanded(mKeyguardShowing || (mQsExpanded && !mStackScrollerOverscrolling));
+ boolean expandVisually = mQsExpanded || mStackScrollerOverscrolling || mHeaderAnimating;
+ mHeader.setVisibility((mQsExpanded || !mKeyguardShowing || mHeaderAnimating)
+ ? View.VISIBLE
+ : View.INVISIBLE);
+ mHeader.setExpanded((mKeyguardShowing && !mHeaderAnimating)
+ || (mQsExpanded && !mStackScrollerOverscrolling));
mNotificationStackScroller.setScrollingEnabled(
mStatusBarState != StatusBarState.KEYGUARD && (!mQsExpanded
|| mQsExpansionFromOverscroll));
@@ -1116,6 +1151,10 @@ public class NotificationPanelView extends PanelView implements
if (mKeyguardShowing) {
updateHeaderKeyguard();
}
+ if (mStatusBarState == StatusBarState.SHADE_LOCKED
+ || mStatusBarState == StatusBarState.KEYGUARD) {
+ updateKeyguardBottomAreaAlpha();
+ }
if (mStatusBarState == StatusBarState.SHADE && mQsExpanded
&& !mStackScrollerOverscrolling && mQsScrimEnabled) {
mQsNavbarScrim.setAlpha(getQsExpansionFraction());
@@ -1156,10 +1195,10 @@ public class NotificationPanelView extends PanelView implements
}
private void setQsTranslation(float height) {
- if (!mHeaderAnimatingIn) {
+ if (!mHeaderAnimating) {
mQsContainer.setY(height - mQsContainer.getDesiredHeight() + getHeaderTranslation());
}
- if (mKeyguardShowing) {
+ if (mKeyguardShowing && !mHeaderAnimating) {
mHeader.setY(interpolate(getQsExpansionFraction(), -mHeader.getHeight(), 0));
}
}
@@ -1471,8 +1510,7 @@ public class NotificationPanelView extends PanelView implements
* Hides the header when notifications are colliding with it.
*/
private void updateHeader() {
- if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
- || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
+ if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
updateHeaderKeyguard();
} else {
updateHeaderShade();
@@ -1481,15 +1519,14 @@ public class NotificationPanelView extends PanelView implements
}
private void updateHeaderShade() {
- if (!mHeaderAnimatingIn) {
+ if (!mHeaderAnimating) {
mHeader.setTranslationY(getHeaderTranslation());
}
setQsTranslation(mQsExpansionHeight);
}
private float getHeaderTranslation() {
- if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
- || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
+ if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
return 0;
}
if (mNotificationStackScroller.getNotGoneChildCount() == 0) {
@@ -1502,30 +1539,42 @@ public class NotificationPanelView extends PanelView implements
return Math.min(0, mNotificationStackScroller.getTranslationY()) / HEADER_RUBBERBAND_FACTOR;
}
- private void updateHeaderKeyguard() {
- float alphaNotifications;
+ /**
+ * @return the alpha to be used to fade out the contents on Keyguard (status bar, bottom area)
+ * during swiping up
+ */
+ private float getKeyguardContentsAlpha() {
+ float alpha;
if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
// When on Keyguard, we hide the header as soon as the top card of the notification
// stack scroller is close enough (collision distance) to the bottom of the header.
- alphaNotifications = getNotificationsTopY()
+ alpha = getNotificationsTopY()
/
(mKeyguardStatusBar.getHeight() + mNotificationsHeaderCollideDistance);
} else {
// In SHADE_LOCKED, the top card is already really close to the header. Hide it as
// soon as we start translating the stack.
- alphaNotifications = getNotificationsTopY() / mKeyguardStatusBar.getHeight();
+ alpha = getNotificationsTopY() / mKeyguardStatusBar.getHeight();
}
- alphaNotifications = MathUtils.constrain(alphaNotifications, 0, 1);
- alphaNotifications = (float) Math.pow(alphaNotifications, 0.75);
+ alpha = MathUtils.constrain(alpha, 0, 1);
+ alpha = (float) Math.pow(alpha, 0.75);
+ return alpha;
+ }
+
+ private void updateHeaderKeyguard() {
float alphaQsExpansion = 1 - Math.min(1, getQsExpansionFraction() * 2);
- mKeyguardStatusBar.setAlpha(Math.min(alphaNotifications, alphaQsExpansion)
+ mKeyguardStatusBar.setAlpha(Math.min(getKeyguardContentsAlpha(), alphaQsExpansion)
* mKeyguardStatusBarAnimateAlpha);
- mKeyguardBottomArea.setAlpha(Math.min(1 - getQsExpansionFraction(), alphaNotifications));
setQsTranslation(mQsExpansionHeight);
}
+ private void updateKeyguardBottomAreaAlpha() {
+ mKeyguardBottomArea.setAlpha(
+ Math.min(getKeyguardContentsAlpha(), 1 - getQsExpansionFraction()));
+ }
+
private float getNotificationsTopY() {
if (mNotificationStackScroller.getNotGoneChildCount() == 0) {
return getExpandedHeight();
@@ -1756,6 +1805,7 @@ public class NotificationPanelView extends PanelView implements
mSecureCameraLaunchManager.onSwipingStarted();
requestDisallowInterceptTouchEvent(true);
mOnlyAffordanceInThisMotion = true;
+ mQsTracking = false;
}
@Override
@@ -1897,7 +1947,7 @@ public class NotificationPanelView extends PanelView implements
mKeyguardBottomArea.setVisibility(View.VISIBLE);
mKeyguardStatusBar.setVisibility(View.VISIBLE);
if (animate) {
- animateKeyguardStatusBarIn();
+ animateKeyguardStatusBarIn(DOZE_ANIMATION_DURATION);
mKeyguardBottomArea.startFinishDozeAnimation();
}
}
@@ -1947,6 +1997,32 @@ public class NotificationPanelView extends PanelView implements
onEmptySpaceClick(x);
}
+ protected boolean onMiddleClicked() {
+ switch (mStatusBar.getBarState()) {
+ case StatusBarState.KEYGUARD:
+ if (!mDozingOnDown) {
+ EventLogTags.writeSysuiLockscreenGesture(
+ EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT,
+ 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
+ startUnlockHintAnimation();
+ }
+ return true;
+ case StatusBarState.SHADE_LOCKED:
+ if (!mQsExpanded) {
+ mStatusBar.goToKeyguard();
+ }
+ return true;
+ case StatusBarState.SHADE:
+
+ // This gets called in the middle of the touch handling, where the state is still
+ // that we are tracking the panel. Collapse the panel after this is done.
+ post(mPostCollapseRunnable);
+ return false;
+ default:
+ return true;
+ }
+ }
+
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index d86ccee..47034e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -100,7 +100,6 @@ public abstract class PanelView extends FrameLayout {
private boolean mCollapseAfterPeek;
private boolean mExpanding;
private boolean mGestureWaitForTouchSlop;
- private boolean mDozingOnDown;
private Runnable mPeekRunnable = new Runnable() {
@Override
public void run() {
@@ -247,7 +246,6 @@ public abstract class PanelView extends FrameLayout {
mUpdateFlingOnLayout = false;
mPeekTouching = mPanelClosedOnDown;
mTouchAboveFalsingThreshold = false;
- mDozingOnDown = isDozing();
if (mVelocityTracker == null) {
initVelocityTracker();
}
@@ -431,7 +429,6 @@ public abstract class PanelView extends FrameLayout {
mHasLayoutedSinceDown = false;
mUpdateFlingOnLayout = false;
mTouchAboveFalsingThreshold = false;
- mDozingOnDown = isDozing();
initVelocityTracker();
trackMovement(event);
break;
@@ -942,35 +939,14 @@ public abstract class PanelView extends FrameLayout {
}
}
- private final Runnable mPostCollapseRunnable = new Runnable() {
+ protected final Runnable mPostCollapseRunnable = new Runnable() {
@Override
public void run() {
collapse(false /* delayed */);
}
};
- private boolean onMiddleClicked() {
- switch (mStatusBar.getBarState()) {
- case StatusBarState.KEYGUARD:
- if (!mDozingOnDown) {
- EventLogTags.writeSysuiLockscreenGesture(
- EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT,
- 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
- startUnlockHintAnimation();
- }
- return true;
- case StatusBarState.SHADE_LOCKED:
- mStatusBar.goToKeyguard();
- return true;
- case StatusBarState.SHADE:
- // This gets called in the middle of the touch handling, where the state is still
- // that we are tracking the panel. Collapse the panel after this is done.
- post(mPostCollapseRunnable);
- return false;
- default:
- return true;
- }
- }
+ protected abstract boolean onMiddleClicked();
protected abstract void onEdgeClicked(boolean right);