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
This commit is contained in:
Selim Cinek
2015-04-14 20:04:12 -07:00
parent e53e6bbb82
commit aac932591d
9 changed files with 167 additions and 43 deletions

View File

@@ -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" />

View File

@@ -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>

View File

@@ -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"/>

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}

View File

@@ -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.
*/

View File

@@ -789,7 +789,7 @@ public class StackStateAnimator {
};
}
private static <T> T getChildTag(View child, int tag) {
public static <T> T getChildTag(View child, int tag) {
return (T) child.getTag(tag);
}