diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java index 3eb6b13417a8b..e6da81e759d9b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java @@ -95,13 +95,15 @@ public class HeadsUpTouchHelper implements Gefingerpoken { case MotionEvent.ACTION_MOVE: final float h = y - mInitialTouchY; - if (Math.abs(h) > mTouchSlop && Math.abs(h) > Math.abs(x - mInitialTouchX)) { + if (mTouchingHeadsUpView && Math.abs(h) > mTouchSlop + && Math.abs(h) > Math.abs(x - mInitialTouchX)) { setTrackingHeadsUp(true); mCollapseSnoozes = h < 0; mInitialTouchX = x; mInitialTouchY = y; int expandedHeight = mPickedChild.getActualHeight(); mPanel.startExpandMotion(x, y, true /* startTracking */, expandedHeight); + mHeadsUpManager.unpinAll(); return true; } break; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index df0a95915b6c1..f983f58061c7a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -1602,9 +1602,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (DEBUG_MEDIA) { Log.v(TAG, "DEBUG_MEDIA: updating album art for notification " + mMediaNotificationKey - + " metadata=" + mMediaMetadata - + " metaDataChanged=" + metaDataChanged - + " state=" + mState); + + " metadata=" + mMediaMetadata + + " metaDataChanged=" + metaDataChanged + + " state=" + mState); } Bitmap artworkBitmap = null; @@ -1872,24 +1872,30 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, @Override public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) { if (inPinnedMode) { - // We need to ensure that the touchable region is updated before the window will be - // resized, in order to not catch any touches. A layout will ensure that - // onComputeInternalInsets will be called and after that we can resize the layout. Let's - // make sure that the window stays small for one frame until the touchableRegion is set. - mNotificationPanel.requestLayout(); mStatusBarWindowManager.setHeadsUpShowing(true); mStatusBarWindowManager.setForceStatusBarVisible(true); - mStatusBarWindowManager.setForceWindowCollapsed(true); - mNotificationPanel.post(new Runnable() { - @Override - public void run() { - mStatusBarWindowManager.setForceWindowCollapsed(false); - } - }); + if (mNotificationPanel.isFullyCollapsed()) { + // We need to ensure that the touchable region is updated before the window will be + // resized, in order to not catch any touches. A layout will ensure that + // onComputeInternalInsets will be called and after that we can resize the layout. Let's + // make sure that the window stays small for one frame until the touchableRegion is set. + mNotificationPanel.requestLayout(); + mStatusBarWindowManager.setForceWindowCollapsed(true); + mNotificationPanel.post(new Runnable() { + @Override + public void run() { + mStatusBarWindowManager.setForceWindowCollapsed(false); + } + }); + } } else { - if (!mNotificationPanel.isFullyCollapsed()) { + if (!mNotificationPanel.isFullyCollapsed() || mNotificationPanel.isTracking()) { + // We are currently tracking or is open and the shade doesn't need to be kept + // open artificially. mStatusBarWindowManager.setHeadsUpShowing(false); } else { + // we need to keep the panel open artificially, let's wait until the animation + // is finished. mHeadsUpManager.setHeadsUpGoingAway(true); mStackScroller.runAfterAnimationFinished(new Runnable() { @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index acf2f570e50bb..808f1ff2edf5c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -115,6 +115,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, if (mFraction != fraction) { mFraction = fraction; scheduleUpdate(); + if (mPinnedHeadsUpCount != 0) { + updateHeadsUpScrim(false); + } } } @@ -425,12 +428,16 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, } private float calculateHeadsUpAlpha() { + float alpha; if (mPinnedHeadsUpCount >= 2) { - return 1.0f; + alpha = 1.0f; } else if (mPinnedHeadsUpCount == 0) { - return 0.0f; + alpha = 0.0f; } else { - return 1.0f - mTopHeadsUpDragAmount; + alpha = 1.0f - mTopHeadsUpDragAmount; } + float expandFactor = (1.0f - mFraction); + expandFactor = Math.max(expandFactor, 0.0f); + return alpha * expandFactor; } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java index 98822a9392dc3..14060df6bf8c2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java @@ -179,7 +179,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL if (alert) { HeadsUpEntry headsUpEntry = mHeadsUpEntries.get(headsUp.key); headsUpEntry.updateEntry(); - setEntryPinned(headsUpEntry, !mIsExpanded /* isPinned */); + setEntryPinned(headsUpEntry, shouldHeadsUpBecomePinned(headsUp)); } } @@ -190,13 +190,21 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL headsUpEntry.setEntry(entry); mHeadsUpEntries.put(entry.key, headsUpEntry); entry.row.setHeadsUp(true); - setEntryPinned(headsUpEntry, !mIsExpanded /* isPinned */); + setEntryPinned(headsUpEntry, shouldHeadsUpBecomePinned(entry)); for (OnHeadsUpChangedListener listener : mListeners) { listener.onHeadsUpStateChanged(entry, true); } entry.row.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); } + private boolean shouldHeadsUpBecomePinned(NotificationData.Entry entry) { + return !mIsExpanded || hasFullScreenIntent(entry); + } + + private boolean hasFullScreenIntent(NotificationData.Entry entry) { + return entry.notification.getNotification().fullScreenIntent != null; + } + private void setEntryPinned(HeadsUpEntry headsUpEntry, boolean isPinned) { ExpandableNotificationRow row = headsUpEntry.entry.row; if (row.isPinned() != isPinned) { @@ -350,6 +358,10 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL } public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) { + if (mIsExpanded) { + // The touchable region is always the full area when expanded + return; + } if (mHasPinnedNotification) { int minX = Integer.MAX_VALUE; int maxX = 0; @@ -445,7 +457,6 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL if (isExpanded != mIsExpanded) { mIsExpanded = isExpanded; if (isExpanded) { - unpinAll(); // make sure our state is sane mWaitingOnCollapseWhenGoingAway = false; mHeadsUpGoingAway = false; @@ -542,7 +553,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL earliestRemovaltime = currentTime + mMinimumDisplayTime; postTime = Math.max(postTime, currentTime); removeAutoRemovalCallbacks(); - if (canEntryDecay()) { + if (!hasFullScreenIntent(entry)) { long finishTime = postTime + mHeadsUpNotificationDecay; long removeDelay = Math.max(finishTime - currentTime, mMinimumDisplayTime); mHandler.postDelayed(mRemoveHeadsUpRunnable, removeDelay); @@ -550,10 +561,6 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL updateSortOrder(HeadsUpEntry.this); } - private boolean canEntryDecay() { - return entry.notification.getNotification().fullScreenIntent == null; - } - @Override public int compareTo(HeadsUpEntry o) { return postTime < o.postTime ? 1 diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index a1b0caef9dfc2..bd3b9ebbd959d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -485,7 +485,7 @@ public class NotificationStackScrollLayout extends ViewGroup int minStackHeight = getMinStackHeight(); int stackHeight; float paddingOffset; - boolean trackingHeadsUp = mTrackingHeadsUp; + boolean trackingHeadsUp = mTrackingHeadsUp || mHeadsUpManager.hasPinnedHeadsUp(); int normalUnfoldPositionStart = trackingHeadsUp ? mHeadsUpManager.getTopHeadsUpHeight() : minStackHeight; if (newStackHeight - mTopPadding - mTopPaddingOverflow >= normalUnfoldPositionStart @@ -608,7 +608,7 @@ public class NotificationStackScrollLayout extends ViewGroup @Override public boolean updateSwipeProgress(View animView, boolean dismissable, float swipeProgress) { - if (isPinnedHeadsUp(animView) && canChildBeDismissed(animView)) { + if (!mIsExpanded && isPinnedHeadsUp(animView) && canChildBeDismissed(animView)) { mScrimController.setTopHeadsUpDragAmount(animView, Math.min(Math.abs(swipeProgress - 1.0f), 1.0f)); } @@ -618,7 +618,7 @@ public class NotificationStackScrollLayout extends ViewGroup public void onBeginDrag(View v) { setSwipingInProgress(true); mAmbientState.onBeginDrag(v); - if (mAnimationsEnabled && !isPinnedHeadsUp(v)) { + if (mAnimationsEnabled && (mIsExpanded || !isPinnedHeadsUp(v))) { mDragAnimPendingChildren.add(v); mNeedsAnimation = true; } @@ -710,7 +710,7 @@ public class NotificationStackScrollLayout extends ViewGroup if (touchY >= top && touchY <= bottom && touchX >= left && touchX <= right) { if (slidingChild instanceof ExpandableNotificationRow) { ExpandableNotificationRow row = (ExpandableNotificationRow) slidingChild; - if (row.isHeadsUp() && row.isPinned() + if (!mIsExpanded && row.isHeadsUp() && row.isPinned() && mHeadsUpManager.getTopEntry().entry.row != row) { continue; } @@ -1871,17 +1871,18 @@ public class NotificationStackScrollLayout extends ViewGroup boolean isHeadsUp = eventPair.second; int type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_OTHER; boolean onBottom = false; + boolean pinnedAndClosed = row.isPinned() && !mIsExpanded; if (!mIsExpanded && !isHeadsUp) { type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR; - } else if (mAddedHeadsUpChildren.contains(row) || (row.isPinned() && !mIsExpanded)) { - if (row.isPinned() || shouldHunAppearFromBottom(row)) { + } else if (isHeadsUp && (mAddedHeadsUpChildren.contains(row) || pinnedAndClosed)) { + if (pinnedAndClosed || shouldHunAppearFromBottom(row)) { // Our custom add animation type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_APPEAR; } else { // Normal add animation type = AnimationEvent.ANIMATION_TYPE_ADD; } - onBottom = !row.isPinned(); + onBottom = !pinnedAndClosed; } AnimationEvent event = new AnimationEvent(row, type); event.headsUpFromBottom = onBottom; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java index de28ac7aa41be..081a9c532c19a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java @@ -311,8 +311,7 @@ public class StackScrollAlgorithm { StackViewState viewState = resultState.getViewStateForView( nextChild); // The child below the dragged one must be fully visible - if (!NotificationStackScrollLayout.isPinnedHeadsUp(draggedView) - || NotificationStackScrollLayout.isPinnedHeadsUp(nextChild)) { + if (ambientState.isShadeExpanded()) { viewState.alpha = 1; } } @@ -508,8 +507,18 @@ public class StackScrollAlgorithm { } StackViewState childState = resultState.getViewStateForView(row); boolean isTopEntry = topHeadsUpEntry == row; + if (mIsExpanded) { + if (isTopEntry) { + childState.height += row.getHeadsUpHeight() - mCollapsedSize; + } + childState.height = Math.max(childState.height, row.getHeadsUpHeight()); + // Ensure that the heads up is always visible even when scrolled off from the bottom + float bottomPosition = ambientState.getMaxHeadsUpTranslation() - childState.height; + childState.yTranslation = Math.min(childState.yTranslation, + bottomPosition); + } if (row.isPinned()) { - childState.yTranslation = 0; + childState.yTranslation = Math.max(childState.yTranslation, 0); childState.height = row.getHeadsUpHeight(); if (!isTopEntry) { // Ensure that a headsUp doesn't vertically extend further than the heads-up at @@ -519,15 +528,6 @@ public class StackScrollAlgorithm { childState.yTranslation = topState.yTranslation + topState.height - childState.height; } - } else if (mIsExpanded) { - if (isTopEntry) { - childState.height += row.getHeadsUpHeight() - mCollapsedSize; - } - childState.height = Math.max(childState.height, row.getHeadsUpHeight()); - // Ensure that the heads up is always visible even when scrolled of from the bottom - float bottomPosition = ambientState.getMaxHeadsUpTranslation() - childState.height; - childState.yTranslation = Math.min(childState.yTranslation, - bottomPosition); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java index b9466d4dd1032..eac5e79960f3b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java @@ -163,7 +163,7 @@ public class StackStateAnimator { // This is a heads up animation return false; } - if (mHostLayout.isPinnedHeadsUp(child)) { + if (NotificationStackScrollLayout.isPinnedHeadsUp(child)) { // This is another headsUp which might move. Let's animate! return false; }