Added the heads up scrim back
Also fixed a bug where the notification panel would
keep a hardware layer.
Also improved the interal structure of the HeadsUpManager
Change-Id: I635e4a89b0a32573c26515cc3e65e142d77593ec
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 532e1b7..539aabf 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" />
+ <com.android.systemui.statusbar.AlphaOptimizedView
+ android:id="@+id/heads_up_scrim"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/heads_up_scrim_height"
+ android:background="@drawable/heads_up_scrim"
+ android:importantForAccessibility="no"/>
+
<include layout="@layout/status_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/status_bar_height" />
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index f9504fb..9e084a0 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.-->
<dimen name="keyguard_clock_notifications_margin_min">24dp</dimen>
<dimen name="keyguard_clock_notifications_margin_max">36dp</dimen>
+ <dimen name="heads_up_scrim_height">250dp</dimen>
<!-- The minimum amount the user needs to swipe to go to the camera / phone. -->
<dimen name="keyguard_min_swipe_amount">110dp</dimen>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 3fc75d2..6d84727 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -37,6 +37,8 @@
<item type="id" name="doze_saved_filter_tag"/>
<item type="id" name="qs_icon_tag"/>
<item type="id" name="scrim"/>
+ <item type="id" name="hun_scrim_alpha_start"/>
+ <item type="id" name="hun_scrim_alpha_end"/>
<item type="id" name="notification_power"/>
<item type="id" name="notification_screenshot"/>
<item type="id" name="notification_hidden"/>
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 ade1a33..e101197 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 @@
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 @@
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 @@
}
@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 f832fb9..61e679a 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.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.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 @@
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 @@
}
@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 0e8a794..e701783 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 @@
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 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 @@
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 @@
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 @@
}
}
- 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 @@
}
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 @@
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 e072521..920a0a1 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.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 @@
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 @@
if (alert) {
HeadsUpEntry headsUpEntry = mHeadsUpEntries.get(headsUp.key);
headsUpEntry.updateEntry();
- setEntryToShade(headsUpEntry, mIsExpanded);
+ setEntryToShade(headsUpEntry, mIsExpanded, false /* justAdded */, false);
}
}
@@ -167,24 +165,22 @@
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 @@
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 @@
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 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 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 f61e9ae..f247488 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.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 @@
= new HashSet<>();
private HeadsUpManager mHeadsUpManager;
private boolean mTrackingHeadsUp;
+ private ScrimController mScrimController;
public NotificationStackScrollLayout(Context context) {
this(context, null);
@@ -608,6 +610,10 @@
@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 @@
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 @@
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 4a705b5..f5d94c8 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 @@
};
}
- private static <T> T getChildTag(View child, int tag) {
+ public static <T> T getChildTag(View child, int tag) {
return (T) child.getTag(tag);
}