diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml index 532e1b7ff17d6..539aabf2c0a40 100644 --- a/packages/SystemUI/res/layout/super_status_bar.xml +++ b/packages/SystemUI/res/layout/super_status_bar.xml @@ -46,6 +46,13 @@ android:layout_height="match_parent" android:importantForAccessibility="no" /> + + diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index f9504fb819a47..9e084a0109f64 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -330,6 +330,7 @@ keyguard_clock_height_fraction_* for the difference between min and max.--> 24dp 36dp + 250dp 110dp diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml index 3fc75d2404b6d..6d84727c2656b 100644 --- a/packages/SystemUI/res/values/ids.xml +++ b/packages/SystemUI/res/values/ids.xml @@ -37,6 +37,8 @@ + + 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 ade1a33cf60e0..e101197fab4ff 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -1176,8 +1176,8 @@ public class NotificationPanelView extends PanelView implements updateEmptyShadeView(); mQsNavbarScrim.setVisibility(mStatusBarState == StatusBarState.SHADE && mQsExpanded && !mStackScrollerOverscrolling && mQsScrimEnabled - ? View.VISIBLE - : View.INVISIBLE); + ? View.VISIBLE + : View.INVISIBLE); if (mKeyguardUserSwitcher != null && mQsExpanded && !mStackScrollerOverscrolling) { mKeyguardUserSwitcher.hideIfNotSimple(true /* animate */); } @@ -1520,6 +1520,9 @@ public class NotificationPanelView extends PanelView implements float alpha; if (mExpandingFromHeadsUp || mHeadsUpManager.hasPinnedHeadsUp()) { alpha = 1f; + if (mNotificationStackScroller.getLayerType() == LAYER_TYPE_HARDWARE) { + mNotificationStackScroller.setLayerType(LAYER_TYPE_NONE, null); + } } else { alpha = (getNotificationsTopY() + mNotificationStackScroller.getItemHeight()) / (mQsMinExpansionHeight + mNotificationStackScroller.getBottomStackPeekSize() @@ -2155,8 +2158,10 @@ public class NotificationPanelView extends PanelView implements } @Override - public void OnHeadsUpPinned(ExpandableNotificationRow headsUp) { - mNotificationStackScroller.generateHeadsUpAnimation(headsUp, true); + public void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp) { + if (isHeadsUp) { + mNotificationStackScroller.generateHeadsUpAnimation(headsUp, true); + } } @Override 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 f832fb99eee4d..61e679afd426d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -73,7 +73,6 @@ import android.util.DisplayMetrics; import android.util.EventLog; import android.util.Log; import android.view.Display; -import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -101,13 +100,13 @@ import com.android.systemui.EventLogConstants; import com.android.systemui.EventLogTags; import com.android.systemui.Prefs; import com.android.systemui.R; +import com.android.systemui.assist.AssistGestureManager; import com.android.systemui.doze.DozeHost; import com.android.systemui.doze.DozeLog; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.qs.QSPanel; import com.android.systemui.recents.ScreenPinningRequest; import com.android.systemui.statusbar.ActivatableNotificationView; -import com.android.systemui.assist.AssistGestureManager; import com.android.systemui.statusbar.BackDropView; import com.android.systemui.statusbar.BaseStatusBar; import com.android.systemui.statusbar.CommandQueue; @@ -702,7 +701,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, ScrimView scrimBehind = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_behind); ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front); - mScrimController = new ScrimController(scrimBehind, scrimInFront, mScrimSrcModeEnabled); + View headsUpScrim = mStatusBarWindow.findViewById(R.id.heads_up_scrim); + mScrimController = new ScrimController(scrimBehind, scrimInFront, headsUpScrim, + mScrimSrcModeEnabled); + mHeadsUpManager.addListener(mScrimController); + mStackScroller.setScrimController(mScrimController); mScrimController.setBackDropView(mBackdrop); mStatusBarView.setScrimController(mScrimController); mDozeScrimController = new DozeScrimController(mScrimController, context); @@ -1846,7 +1849,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override - public void OnHeadsUpPinned(ExpandableNotificationRow headsUp) { + public void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp) { } @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 0e8a7942d1b3b..e70178350e713 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Color; @@ -29,13 +30,18 @@ import android.view.animation.Interpolator; import com.android.systemui.R; import com.android.systemui.statusbar.BackDropView; +import com.android.systemui.statusbar.ExpandableNotificationRow; +import com.android.systemui.statusbar.NotificationData; import com.android.systemui.statusbar.ScrimView; +import com.android.systemui.statusbar.policy.HeadsUpManager; +import com.android.systemui.statusbar.stack.StackStateAnimator; /** * Controls both the scrim behind the notifications and in front of the notifications (when a * security method gets shown). */ -public class ScrimController implements ViewTreeObserver.OnPreDrawListener { +public class ScrimController implements ViewTreeObserver.OnPreDrawListener, + HeadsUpManager.OnHeadsUpChangedListener { public static final long ANIMATION_DURATION = 220; private static final float SCRIM_BEHIND_ALPHA = 0.62f; @@ -43,10 +49,13 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { private static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f; private static final float SCRIM_IN_FRONT_ALPHA = 0.75f; private static final int TAG_KEY_ANIM = R.id.scrim; + private static final int TAG_HUN_START_ALPHA = R.id.hun_scrim_alpha_start; + private static final int TAG_HUN_END_ALPHA = R.id.hun_scrim_alpha_end; private final ScrimView mScrimBehind; private final ScrimView mScrimInFront; private final UnlockMethodCache mUnlockMethodCache; + private final View mHeadsUpScrim; private boolean mKeyguardShowing; private float mFraction; @@ -70,15 +79,22 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { private float mDozeBehindAlpha; private float mCurrentInFrontAlpha; private float mCurrentBehindAlpha; + private float mCurrentHeadsUpAlpha = 1; + private int mAmountOfPinnedHeadsUps; + private float mTopHeadsUpDragAmount; + private View mDraggedHeadsUpView; - public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront, boolean scrimSrcEnabled) { + public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront, View headsUpScrim, + boolean scrimSrcEnabled) { mScrimBehind = scrimBehind; mScrimInFront = scrimInFront; + mHeadsUpScrim = headsUpScrim; final Context context = scrimBehind.getContext(); mUnlockMethodCache = UnlockMethodCache.getInstance(context); mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in); mScrimSrcEnabled = scrimSrcEnabled; + updateHeadsUpScrim(false); } public void setKeyguardShowing(boolean showing) { @@ -217,7 +233,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { } } - private void setScrimColor(ScrimView scrim, float alpha) { + private void setScrimColor(View scrim, float alpha) { Object runningAnim = scrim.getTag(TAG_KEY_ANIM); if (runningAnim instanceof ValueAnimator) { ((ValueAnimator) runningAnim).cancel(); @@ -236,25 +252,34 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { } private float getCurrentScrimAlpha(View scrim) { - return scrim == mScrimBehind ? mCurrentBehindAlpha : mCurrentInFrontAlpha; + return scrim == mScrimBehind ? mCurrentBehindAlpha + : scrim == mScrimInFront ? mCurrentInFrontAlpha + : mCurrentHeadsUpAlpha; } private void setCurrentScrimAlpha(View scrim, float alpha) { if (scrim == mScrimBehind) { mCurrentBehindAlpha = alpha; - } else { + } else if (scrim == mScrimInFront) { mCurrentInFrontAlpha = alpha; + } else { + alpha = Math.max(0.0f, Math.min(1.0f, alpha)); + mCurrentHeadsUpAlpha = alpha; } } - private void updateScrimColor(ScrimView scrim) { + private void updateScrimColor(View scrim) { float alpha1 = getCurrentScrimAlpha(scrim); - float alpha2 = getDozeAlpha(scrim); - float alpha = 1 - (1 - alpha1) * (1 - alpha2); - scrim.setScrimColor(Color.argb((int) (alpha * 255), 0, 0, 0)); + if (scrim instanceof ScrimView) { + float alpha2 = getDozeAlpha(scrim); + float alpha = 1 - (1 - alpha1) * (1 - alpha2); + ((ScrimView) scrim).setScrimColor(Color.argb((int) (alpha * 255), 0, 0, 0)); + } else { + scrim.setAlpha(alpha1); + } } - private void startScrimAnimation(final ScrimView scrim, float target) { + private void startScrimAnimation(final View scrim, float target) { float current = getCurrentScrimAlpha(scrim); ValueAnimator anim = ValueAnimator.ofFloat(current, target); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @@ -320,4 +345,84 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { boolean asSrc = mBackDropView.getVisibility() != View.VISIBLE && mScrimSrcEnabled; mScrimBehind.setDrawAsSrc(asSrc); } + + @Override + public void OnPinnedHeadsUpExistChanged(boolean exist, boolean changeImmediatly) { + } + + @Override + public void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp) { + if (isHeadsUp) { + mAmountOfPinnedHeadsUps++; + } else { + mAmountOfPinnedHeadsUps--; + if (headsUp == mDraggedHeadsUpView) { + mDraggedHeadsUpView = null; + mTopHeadsUpDragAmount = 0.0f; + } + } + updateHeadsUpScrim(true); + } + + @Override + public void OnHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) { + } + + private void updateHeadsUpScrim(boolean animate) { + float alpha = calculateHeadsUpAlpha(); + ValueAnimator previousAnimator = StackStateAnimator.getChildTag(mHeadsUpScrim, + TAG_KEY_ANIM); + float animEndValue = -1; + if (previousAnimator != null) { + if ((animate || alpha == mCurrentHeadsUpAlpha)) { + // lets cancel any running animators + previousAnimator.cancel(); + } + animEndValue = StackStateAnimator.getChildTag(mHeadsUpScrim, + TAG_HUN_START_ALPHA); + } + if (alpha != mCurrentHeadsUpAlpha && alpha != animEndValue) { + if (animate) { + startScrimAnimation(mHeadsUpScrim, alpha); + mHeadsUpScrim.setTag(TAG_HUN_START_ALPHA, mCurrentHeadsUpAlpha); + mHeadsUpScrim.setTag(TAG_HUN_END_ALPHA, alpha); + } else { + if (previousAnimator != null) { + float previousStartValue = StackStateAnimator.getChildTag(mHeadsUpScrim, + TAG_HUN_START_ALPHA); + float previousEndValue = StackStateAnimator.getChildTag(mHeadsUpScrim, + TAG_HUN_END_ALPHA); + // we need to increase all animation keyframes of the previous animator by the + // relative change to the end value + PropertyValuesHolder[] values = previousAnimator.getValues(); + float relativeDiff = alpha - previousEndValue; + float newStartValue = previousStartValue + relativeDiff; + values[0].setFloatValues(newStartValue, alpha); + mHeadsUpScrim.setTag(TAG_HUN_START_ALPHA, newStartValue); + mHeadsUpScrim.setTag(TAG_HUN_END_ALPHA, alpha); + previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime()); + } else { + // update the alpha directly + setCurrentScrimAlpha(mHeadsUpScrim, alpha); + updateScrimColor(mHeadsUpScrim); + } + } + } + } + + public void setTopHeadsUpDragAmount(View draggedHeadsUpView, float topHeadsUpDragAmount) { + mTopHeadsUpDragAmount = topHeadsUpDragAmount; + mDraggedHeadsUpView = draggedHeadsUpView; + updateHeadsUpScrim(false); + } + + private float calculateHeadsUpAlpha() { + if (mAmountOfPinnedHeadsUps >= 2) { + return 1.0f; + } else if (mAmountOfPinnedHeadsUps == 0) { + return 0.0f; + } else { + return 1.0f - mTopHeadsUpDragAmount; + } + } } 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 e072521e36e76..920a0a15c2617 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java @@ -25,7 +25,6 @@ import android.provider.Settings; import android.util.ArrayMap; import android.util.Log; import android.util.Pools; -import android.view.View; import android.view.ViewTreeObserver; import android.view.accessibility.AccessibilityEvent; @@ -100,7 +99,6 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL mMinimumDisplayTime = resources.getInteger(R.integer.heads_up_notification_minimum_time); mHeadsUpNotificationDecay = resources.getInteger(R.integer.heads_up_notification_decay); mClock = new Clock(); - // TODO: shadow mSwipeHelper.setMaxSwipeProgress(mMaxAlpha); mSnoozeLengthMs = Settings.Global.getInt(context.getContentResolver(), SETTING_HEADS_UP_SNOOZE_LENGTH_MS, mDefaultSnoozeLengthMs); @@ -156,7 +154,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL if (alert) { HeadsUpEntry headsUpEntry = mHeadsUpEntries.get(headsUp.key); headsUpEntry.updateEntry(); - setEntryToShade(headsUpEntry, mIsExpanded); + setEntryToShade(headsUpEntry, mIsExpanded, false /* justAdded */, false); } } @@ -167,24 +165,22 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL headsUpEntry.setEntry(entry); mHeadsUpEntries.put(entry.key, headsUpEntry); entry.row.setHeadsUp(true); - if (!entry.row.isInShade() && mIsExpanded) { - setEntryToShade(headsUpEntry, true); - } - updatePinnedHeadsUpState(false /*forceImmediate */); + setEntryToShade(headsUpEntry, mIsExpanded /* inShade */, true /* justAdded */, false); for (OnHeadsUpChangedListener listener : mListeners) { listener.OnHeadsUpStateChanged(entry, true); } entry.row.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); } - private void setEntryToShade(HeadsUpEntry headsUpEntry, boolean inShade) { + private void setEntryToShade(HeadsUpEntry headsUpEntry, boolean inShade, boolean justAdded, + boolean forceImmediate) { ExpandableNotificationRow row = headsUpEntry.entry.row; - if (row.isInShade() != inShade) { + if (row.isInShade() != inShade || justAdded) { row.setInShade(inShade); - updatePinnedHeadsUpState(false /* forceImmediate */); - if (!inShade) { - for (OnHeadsUpChangedListener listener :mListeners) { - listener.OnHeadsUpPinned(row); + if (!justAdded || !inShade) { + updatePinnedHeadsUpState(forceImmediate); + for (OnHeadsUpChangedListener listener : mListeners) { + listener.OnHeadsUpPinnedChanged(row, !inShade); } } } @@ -196,7 +192,8 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL mEntryPool.release(remove); entry.row.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); entry.row.setHeadsUp(false); - updatePinnedHeadsUpState(false /* forceImmediate */); + setEntryToShade(remove, true /* inShade */, false /* justAdded */, + false /* forceImmediate */); for (OnHeadsUpChangedListener listener : mListeners) { listener.OnHeadsUpStateChanged(entry, false); } @@ -323,12 +320,6 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL return false; } - public boolean updateSwipeProgress(View animView, boolean dismissable, float swipeProgress) { - // TODO: handle the shadow - //getBackground().setAlpha((int) (255 * swipeProgress)); - return false; - } - public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) { if (!mIsExpanded && mHasPinnedHeadsUp) { int minX = Integer.MAX_VALUE; @@ -403,9 +394,9 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL public void releaseAllToShade() { for (String key: mHeadsUpEntries.keySet()) { HeadsUpEntry entry = mHeadsUpEntries.get(key); - entry.entry.row.setInShade(true); + setEntryToShade(entry, true /* toShade */, false /* justAdded */, + true /* forceImmediate */); } - updatePinnedHeadsUpState(true /* forceImmediate */); } public void onExpandingFinished() { @@ -522,7 +513,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL public interface OnHeadsUpChangedListener { void OnPinnedHeadsUpExistChanged(boolean exist, boolean changeImmediatly); - void OnHeadsUpPinned(ExpandableNotificationRow headsUp); + void OnHeadsUpPinnedChanged(ExpandableNotificationRow headsUp, boolean isHeadsUp); void OnHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp); } } 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 f61e9ae2b269b..f247488e87d9b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -48,6 +48,7 @@ import com.android.systemui.statusbar.StackScrollerDecorView; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.phone.PhoneStatusBar; +import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.ScrollAdapter; @@ -225,6 +226,7 @@ public class NotificationStackScrollLayout extends ViewGroup = new HashSet<>(); private HeadsUpManager mHeadsUpManager; private boolean mTrackingHeadsUp; + private ScrimController mScrimController; public NotificationStackScrollLayout(Context context) { this(context, null); @@ -608,6 +610,10 @@ public class NotificationStackScrollLayout extends ViewGroup @Override public boolean updateSwipeProgress(View animView, boolean dismissable, float swipeProgress) { + if (isPinnedHeadsUp(animView) && canChildBeDismissed(animView)) { + mScrimController.setTopHeadsUpDragAmount(animView, + Math.min(Math.abs(swipeProgress - 1.0f), 1.0f)); + } return false; } @@ -1870,7 +1876,7 @@ public class NotificationStackScrollLayout extends ViewGroup boolean isHeadsUp = eventPair.second; int type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_OTHER; boolean onBottom = false; - if (!row.isInShade() && !isHeadsUp) { + if (!mIsExpanded && !isHeadsUp) { type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR; } else if (mAddedHeadsUpChildren.contains(row) || (!row.isInShade() && !mIsExpanded)) { if (!row.isInShade() || shouldHunAppearFromBottom(row)) { @@ -2714,6 +2720,10 @@ public class NotificationStackScrollLayout extends ViewGroup mTrackingHeadsUp = trackingHeadsUp; } + public void setScrimController(ScrimController scrimController) { + mScrimController = scrimController; + } + /** * A listener that is notified when some child locations might have changed. */ 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 4a705b5e4b983..f5d94c887c825 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java @@ -789,7 +789,7 @@ public class StackStateAnimator { }; } - private static T getChildTag(View child, int tag) { + public static T getChildTag(View child, int tag) { return (T) child.getTag(tag); }