Treating headsUpViews now as real notification citizen

Previously headsUpViews simply were replacing the content
views, now they have their seperate space.

Change-Id: I6b094975cdfdf5e082d546dd7a0bf633335f4ef8
This commit is contained in:
Selim Cinek
2015-04-10 00:05:50 -07:00
parent a59ecc3401
commit 8d490d427c
6 changed files with 251 additions and 104 deletions

View File

@@ -751,8 +751,7 @@ public abstract class BaseStatusBar extends SystemUI implements
protected View updateNotificationVetoButton(View row, StatusBarNotification n) {
View vetoButton = row.findViewById(R.id.veto);
// TODO: make headsup non-clearable if it is in the shade
if (n.isClearable() || (mHeadsUpManager.isHeadsUp(n.getKey()))) {
if (n.isClearable()) {
final String _pkg = n.getPackageName();
final String _tag = n.getTag();
final int _id = n.getId();
@@ -1225,8 +1224,7 @@ public abstract class BaseStatusBar extends SystemUI implements
protected void workAroundBadLayerDrawableOpacity(View v) {
}
protected boolean inflateViews(NotificationData.Entry entry, ViewGroup parent,
boolean isHeadsUp) {
protected boolean inflateViews(Entry entry, ViewGroup parent) {
PackageManager pmUser = getPackageManagerForUser(
entry.notification.getUser().getIdentifier());
@@ -1234,12 +1232,7 @@ public abstract class BaseStatusBar extends SystemUI implements
final StatusBarNotification sbn = entry.notification;
RemoteViews contentView = sbn.getNotification().contentView;
RemoteViews bigContentView = sbn.getNotification().bigContentView;
if (isHeadsUp) {
maxHeight =
mContext.getResources().getDimensionPixelSize(R.dimen.notification_mid_height);
bigContentView = sbn.getNotification().headsUpContentView;
}
RemoteViews headsUpContentView = sbn.getNotification().headsUpContentView;
if (contentView == null) {
return false;
@@ -1286,10 +1279,8 @@ public abstract class BaseStatusBar extends SystemUI implements
// NB: the large icon is now handled entirely by the template
// bind the click event to the content area
NotificationContentView expanded =
(NotificationContentView) row.findViewById(R.id.expanded);
NotificationContentView expandedPublic =
(NotificationContentView) row.findViewById(R.id.expandedPublic);
NotificationContentView contentContainer = row.getPrivateLayout();
NotificationContentView contentContainerPublic = row.getPublicLayout();
row.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
if (ENABLE_REMOTE_INPUT) {
@@ -1307,11 +1298,16 @@ public abstract class BaseStatusBar extends SystemUI implements
// set up the adaptive layout
View contentViewLocal = null;
View bigContentViewLocal = null;
View headsUpContentViewLocal = null;
try {
contentViewLocal = contentView.apply(mContext, expanded,
contentViewLocal = contentView.apply(mContext, contentContainer,
mOnClickHandler);
if (bigContentView != null) {
bigContentViewLocal = bigContentView.apply(mContext, expanded,
bigContentViewLocal = bigContentView.apply(mContext, contentContainer,
mOnClickHandler);
}
if (headsUpContentView != null) {
headsUpContentViewLocal = headsUpContentView.apply(mContext, contentContainer,
mOnClickHandler);
}
}
@@ -1323,23 +1319,27 @@ public abstract class BaseStatusBar extends SystemUI implements
if (contentViewLocal != null) {
contentViewLocal.setIsRootNamespace(true);
expanded.setContractedChild(contentViewLocal);
contentContainer.setContractedChild(contentViewLocal);
}
if (bigContentViewLocal != null) {
bigContentViewLocal.setIsRootNamespace(true);
expanded.setExpandedChild(bigContentViewLocal);
contentContainer.setExpandedChild(bigContentViewLocal);
}
if (headsUpContentViewLocal != null) {
headsUpContentViewLocal.setIsRootNamespace(true);
contentContainer.setHeadsUpChild(headsUpContentViewLocal);
}
// now the public version
View publicViewLocal = null;
if (publicNotification != null) {
try {
publicViewLocal = publicNotification.contentView.apply(mContext, expandedPublic,
publicViewLocal = publicNotification.contentView.apply(mContext, contentContainerPublic,
mOnClickHandler);
if (publicViewLocal != null) {
publicViewLocal.setIsRootNamespace(true);
expandedPublic.setContractedChild(publicViewLocal);
contentContainerPublic.setContractedChild(publicViewLocal);
}
}
catch (RuntimeException e) {
@@ -1361,9 +1361,9 @@ public abstract class BaseStatusBar extends SystemUI implements
// Add a basic notification template
publicViewLocal = LayoutInflater.from(mContext).inflate(
R.layout.notification_public_default,
expandedPublic, false);
contentContainerPublic, false);
publicViewLocal.setIsRootNamespace(true);
expandedPublic.setContractedChild(publicViewLocal);
contentContainerPublic.setContractedChild(publicViewLocal);
final TextView title = (TextView) publicViewLocal.findViewById(R.id.title);
try {
@@ -1499,13 +1499,8 @@ public abstract class BaseStatusBar extends SystemUI implements
stripped.contentView = null;
stripped.extras.putBoolean("android.rebuild.bigView", true);
stripped.bigContentView = null;
// Don't create the HUN input view for now because input doesn't work there yet.
// TODO: Enable once HUNs can take remote input correctly.
if (false) {
stripped.extras.putBoolean("android.rebuild.hudView", true);
stripped.headsUpContentView = null;
}
stripped.extras.putBoolean("android.rebuild.hudView", true);
stripped.headsUpContentView = null;
Notification rebuilt = Notification.Builder.rebuild(mContext, stripped);
@@ -1537,16 +1532,23 @@ public abstract class BaseStatusBar extends SystemUI implements
}
// See if we have somewhere to put that remote input
ViewGroup actionContainer = null;
if (remoteInput != null && entry.expandedBig != null) {
View actionContainerCandidate = entry.expandedBig
.findViewById(com.android.internal.R.id.actions);
if (actionContainerCandidate instanceof ViewGroup) {
actionContainer = (ViewGroup) actionContainerCandidate;
if (remoteInput != null) {
if (entry.expandedBig != null) {
inflateRemoteInput(entry.expandedBig, remoteInput, actions);
}
View headsUpChild = entry.row.getPrivateLayout().getHeadsUpChild();
if (headsUpChild != null) {
inflateRemoteInput(headsUpChild, remoteInput, actions);
}
}
if (actionContainer != null) {
}
private void inflateRemoteInput(View view, RemoteInput remoteInput,
Notification.Action[] actions) {
View actionContainerCandidate = view.findViewById(com.android.internal.R.id.actions);
if (actionContainerCandidate instanceof ViewGroup) {
ViewGroup actionContainer = (ViewGroup) actionContainerCandidate;
actionContainer.removeAllViews();
actionContainer.addView(
RemoteInputView.inflate(mContext, actionContainer, actions[0], remoteInput));
@@ -1719,8 +1721,7 @@ public abstract class BaseStatusBar extends SystemUI implements
return entry.notification;
}
protected NotificationData.Entry createNotificationViews(StatusBarNotification sbn,
boolean isHeadsUp) {
protected NotificationData.Entry createNotificationViews(StatusBarNotification sbn) {
if (DEBUG) {
Log.d(TAG, "createNotificationViews(notification=" + sbn);
}
@@ -1731,7 +1732,7 @@ public abstract class BaseStatusBar extends SystemUI implements
// Construct the expanded view.
NotificationData.Entry entry = new NotificationData.Entry(sbn, iconView);
if (!inflateViews(entry, mStackScroller, isHeadsUp)) {
if (!inflateViews(entry, mStackScroller)) {
handleNotificationError(sbn, "Couldn't expand RemoteViews for: " + sbn);
return null;
}
@@ -1881,7 +1882,6 @@ public abstract class BaseStatusBar extends SystemUI implements
boolean applyInPlace = shouldApplyInPlace(entry, n);
final boolean shouldInterrupt = shouldInterrupt(notification);
final boolean alertAgain = alertAgain(entry, n);
boolean isHeadsUp = shouldInterrupt && alertAgain;
entry.notification = notification;
mGroupManager.onEntryUpdated(entry, entry.notification);
@@ -1905,7 +1905,7 @@ public abstract class BaseStatusBar extends SystemUI implements
return;
}
}
updateNotificationViews(entry, notification, isHeadsUp);
updateNotificationViews(entry, notification);
updateSuccessful = true;
}
catch (RuntimeException e) {
@@ -1923,7 +1923,7 @@ public abstract class BaseStatusBar extends SystemUI implements
n.tickerText);
entry.icon.setNotification(n);
entry.icon.set(ic);
inflateViews(entry, mStackScroller, isHeadsUp);
inflateViews(entry, mStackScroller);
}
mNotificationData.updateRanking(ranking);
updateNotifications();
@@ -2022,12 +2022,10 @@ public abstract class BaseStatusBar extends SystemUI implements
&& publicUnchanged;
}
private void updateNotificationViews(NotificationData.Entry entry,
StatusBarNotification notification, boolean isHeadsUp) {
private void updateNotificationViews(Entry entry, StatusBarNotification notification) {
final RemoteViews contentView = notification.getNotification().contentView;
final RemoteViews bigContentView = isHeadsUp
? notification.getNotification().headsUpContentView
: notification.getNotification().bigContentView;
final RemoteViews bigContentView = notification.getNotification().bigContentView;
final RemoteViews headsUpContentView = notification.getNotification().headsUpContentView;
final Notification publicVersion = notification.getNotification().publicVersion;
final RemoteViews publicContentView = publicVersion != null ? publicVersion.contentView
: null;
@@ -2038,6 +2036,10 @@ public abstract class BaseStatusBar extends SystemUI implements
bigContentView.reapply(mContext, entry.getBigContentView(),
mOnClickHandler);
}
View headsUpChild = entry.row.getPrivateLayout().getHeadsUpChild();
if (headsUpContentView != null && headsUpChild != null) {
headsUpContentView.reapply(mContext, headsUpChild, mOnClickHandler);
}
if (publicContentView != null && entry.getPublicContentView() != null) {
publicContentView.reapply(mContext, entry.getPublicContentView(), mOnClickHandler);
}

View File

@@ -78,13 +78,14 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
private NotificationContentView mPublicLayout;
private NotificationContentView mPrivateLayout;
private int mMaxExpandHeight;
private int mHeadsUpHeight;
private View mVetoButton;
private boolean mClearable;
private ExpansionLogger mLogger;
private String mLoggingKey;
private boolean mWasReset;
private NotificationGuts mGuts;
private NotificationGuts mGuts;
private StatusBarNotification mStatusBarNotification;
private boolean mIsHeadsUp;
private View mExpandButton;
@@ -110,6 +111,14 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
};
private boolean mInShade;
public NotificationContentView getPrivateLayout() {
return mPrivateLayout;
}
public NotificationContentView getPublicLayout() {
return mPublicLayout;
}
public void setIconAnimationRunning(boolean running) {
setIconAnimationRunning(running, mPublicLayout);
setIconAnimationRunning(running, mPrivateLayout);
@@ -119,8 +128,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
if (layout != null) {
View contractedChild = layout.getContractedChild();
View expandedChild = layout.getExpandedChild();
View headsUpChild = layout.getHeadsUpChild();
setIconAnimationRunningForChild(running, contractedChild);
setIconAnimationRunningForChild(running, expandedChild);
setIconAnimationRunningForChild(running, headsUpChild);
}
}
@@ -171,6 +182,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
public void setHeadsUp(boolean isHeadsUp) {
mIsHeadsUp = isHeadsUp;
mPrivateLayout.setHeadsUp(isHeadsUp);
}
public void setGroupManager(NotificationGroupManager groupManager) {
@@ -277,8 +289,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
}
public int getHeadsUpHeight() {
// TODO: improve this logic
return getIntrinsicHeight();
return mHeadsUpHeight;
}
public interface ExpansionLogger {
@@ -317,6 +328,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
resetActualHeight();
}
mMaxExpandHeight = 0;
mHeadsUpHeight = 0;
mWasReset = true;
onHeightReset();
requestLayout();
@@ -554,7 +566,13 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
}
boolean inExpansionState = isExpanded();
int maxContentHeight;
if ((!inExpansionState && !mChildrenExpanded) || mShowingPublicForIntrinsicHeight) {
if (mIsHeadsUp) {
if (inExpansionState) {
maxContentHeight = Math.max(mMaxExpandHeight, mHeadsUpHeight);
} else {
maxContentHeight = Math.max(mRowMinHeight, mHeadsUpHeight);
}
} else if ((!inExpansionState && !mChildrenExpanded) || mShowingPublicForIntrinsicHeight) {
maxContentHeight = mRowMinHeight;
} else if (mChildrenExpanded) {
maxContentHeight = mChildrenContainer.getIntrinsicHeight();
@@ -601,7 +619,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
boolean updateExpandHeight = mMaxExpandHeight == 0 && !mWasReset;
updateMaxExpandHeight();
updateMaxHeights();
if (updateExpandHeight) {
applyExpansionToLayout();
}
@@ -617,9 +635,17 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
return super.isChildInvisible(child) || isInvisibleChildContainer;
}
private void updateMaxExpandHeight() {
private void updateMaxHeights() {
int intrinsicBefore = getIntrinsicHeight();
mMaxExpandHeight = mPrivateLayout.getMaxHeight();
View expandedChild = mPrivateLayout.getExpandedChild();
if (expandedChild == null) {
expandedChild = mPrivateLayout.getContractedChild();
}
mMaxExpandHeight = expandedChild.getHeight();
View headsUpChild = mPrivateLayout.getHeadsUpChild();
if (headsUpChild != null) {
mHeadsUpHeight = headsUpChild.getHeight();
}
if (intrinsicBefore != getIntrinsicHeight()) {
notifyHeightChanged(false /* needsAnimation */);
}

View File

@@ -23,10 +23,12 @@ import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.widget.FrameLayout;
import com.android.systemui.R;
/**
@@ -37,23 +39,28 @@ import com.android.systemui.R;
public class NotificationContentView extends FrameLayout {
private static final long ANIMATION_DURATION_LENGTH = 170;
private static final int CONTRACTED = 1;
private static final int EXPANDED = 2;
private static final int HEADSUP = 3;
private final Rect mClipBounds = new Rect();
private View mContractedChild;
private View mExpandedChild;
private View mHeadsUpChild;
private NotificationViewWrapper mContractedWrapper;
private int mSmallHeight;
private int mHeadsUpHeight;
private int mClipTopAmount;
private int mContentHeight;
private final Interpolator mLinearInterpolator = new LinearInterpolator();
private int mVisibleView = CONTRACTED;
private boolean mContractedVisible = true;
private boolean mDark;
private final Paint mFadePaint = new Paint();
private boolean mAnimate;
private ViewTreeObserver.OnPreDrawListener mEnableAnimationPredrawListener
@@ -65,6 +72,7 @@ public class NotificationContentView extends FrameLayout {
return true;
}
};
private boolean mIsHeadsUp;
public NotificationContentView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -72,6 +80,51 @@ public class NotificationContentView extends FrameLayout {
reset(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
boolean hasFixedHeight = heightMode == MeasureSpec.EXACTLY;
boolean isHeightLimited = heightMode == MeasureSpec.AT_MOST;
int maxSize = Integer.MAX_VALUE;
if (hasFixedHeight || isHeightLimited) {
maxSize = MeasureSpec.getSize(heightMeasureSpec);
}
int maxChildHeight = 0;
if (mContractedChild != null) {
int size = Math.min(maxSize, mSmallHeight);
mContractedChild.measure(widthMeasureSpec,
MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST));
maxChildHeight = Math.max(maxChildHeight, mContractedChild.getMeasuredHeight());
}
if (mExpandedChild != null) {
int size = maxSize;
ViewGroup.LayoutParams layoutParams = mExpandedChild.getLayoutParams();
if (layoutParams.height >= 0) {
// An actual height is set
size = Math.min(maxSize, layoutParams.height);
}
int spec = size == Integer.MAX_VALUE ?
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED) :
MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST);
mExpandedChild.measure(widthMeasureSpec, spec);
maxChildHeight = Math.max(maxChildHeight, mExpandedChild.getMeasuredHeight());
}
if (mHeadsUpChild != null) {
int size = Math.min(maxSize, mHeadsUpHeight);
ViewGroup.LayoutParams layoutParams = mHeadsUpChild.getLayoutParams();
if (layoutParams.height >= 0) {
// An actual height is set
size = Math.min(maxSize, layoutParams.height);
}
mHeadsUpChild.measure(widthMeasureSpec,
MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST));
maxChildHeight = Math.max(maxChildHeight, mHeadsUpChild.getMeasuredHeight());
}
int ownHeight = Math.min(maxChildHeight, maxSize);
int width = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(width, ownHeight);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
@@ -91,11 +144,15 @@ public class NotificationContentView extends FrameLayout {
if (mExpandedChild != null) {
mExpandedChild.animate().cancel();
}
if (mHeadsUpChild != null) {
mHeadsUpChild.animate().cancel();
}
removeAllViews();
mContractedChild = null;
mExpandedChild = null;
mSmallHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height);
mContractedVisible = true;
mHeadsUpHeight = getResources().getDimensionPixelSize(R.dimen.notification_mid_height);
mVisibleView = CONTRACTED;
if (resetActualHeight) {
mContentHeight = mSmallHeight;
}
@@ -109,12 +166,16 @@ public class NotificationContentView extends FrameLayout {
return mExpandedChild;
}
public View getHeadsUpChild() {
return mHeadsUpChild;
}
public void setContractedChild(View child) {
if (mContractedChild != null) {
mContractedChild.animate().cancel();
removeView(mContractedChild);
}
sanitizeContractedLayoutParams(child);
sanitizeLayoutParams(child, mSmallHeight);
addView(child);
mContractedChild = child;
mContractedWrapper = NotificationViewWrapper.wrap(getContext(), child);
@@ -132,6 +193,16 @@ public class NotificationContentView extends FrameLayout {
selectLayout(false /* animate */, true /* force */);
}
public void setHeadsUpChild(View child) {
if (mHeadsUpChild != null) {
mHeadsUpChild.animate().cancel();
removeView(mHeadsUpChild);
}
addView(child);
mHeadsUpChild = child;
selectLayout(false /* animate */, true /* force */);
}
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
@@ -166,9 +237,12 @@ public class NotificationContentView extends FrameLayout {
}
public int getMaxHeight() {
// The maximum height is just the laid out height.
return getHeight();
if (mIsHeadsUp && mHeadsUpChild != null) {
return mHeadsUpChild.getHeight();
} else if (mExpandedChild != null) {
return mExpandedChild.getHeight();
}
return mSmallHeight;
}
public int getMinHeight() {
@@ -185,9 +259,9 @@ public class NotificationContentView extends FrameLayout {
setClipBounds(mClipBounds);
}
private void sanitizeContractedLayoutParams(View contractedChild) {
private void sanitizeLayoutParams(View contractedChild, int height) {
LayoutParams lp = (LayoutParams) contractedChild.getLayoutParams();
lp.height = mSmallHeight;
lp.height = height;
contractedChild.setLayoutParams(lp);
}
@@ -195,52 +269,87 @@ public class NotificationContentView extends FrameLayout {
if (mContractedChild == null) {
return;
}
boolean showContractedChild = showContractedChild();
if (showContractedChild != mContractedVisible || force) {
int visibleView = calculateVisibleView();
if (visibleView != mVisibleView || force) {
if (animate && mExpandedChild != null) {
runSwitchAnimation(showContractedChild);
} else if (mExpandedChild != null) {
mContractedChild.setVisibility(showContractedChild ? View.VISIBLE : View.INVISIBLE);
mContractedChild.setAlpha(showContractedChild ? 1f : 0f);
mExpandedChild.setVisibility(showContractedChild ? View.INVISIBLE : View.VISIBLE);
mExpandedChild.setAlpha(showContractedChild ? 0f : 1f);
runSwitchAnimation(visibleView);
} else {
updateViewVisibilities(visibleView);
}
mVisibleView = visibleView;
}
mContractedVisible = showContractedChild;
}
private void runSwitchAnimation(final boolean showContractedChild) {
mContractedChild.setVisibility(View.VISIBLE);
mExpandedChild.setVisibility(View.VISIBLE);
mContractedChild.setLayerType(LAYER_TYPE_HARDWARE, mFadePaint);
mExpandedChild.setLayerType(LAYER_TYPE_HARDWARE, mFadePaint);
private void updateViewVisibilities(int visibleView) {
boolean contractedVisible = visibleView == CONTRACTED;
mContractedChild.setVisibility(contractedVisible ? View.VISIBLE : View.INVISIBLE);
mContractedChild.setAlpha(contractedVisible ? 1f : 0f);
mContractedChild.setLayerType(LAYER_TYPE_NONE, null);
if (mExpandedChild != null) {
boolean expandedVisible = visibleView == EXPANDED;
mExpandedChild.setVisibility(expandedVisible ? View.VISIBLE : View.INVISIBLE);
mExpandedChild.setAlpha(expandedVisible ? 1f : 0f);
mExpandedChild.setLayerType(LAYER_TYPE_NONE, null);
}
if (mHeadsUpChild != null) {
boolean headsUpVisible = visibleView == HEADSUP;
mHeadsUpChild.setVisibility(headsUpVisible ? View.VISIBLE : View.INVISIBLE);
mHeadsUpChild.setAlpha(headsUpVisible ? 1f : 0f);
mHeadsUpChild.setLayerType(LAYER_TYPE_NONE, null);
}
setLayerType(LAYER_TYPE_NONE, null);
}
private void runSwitchAnimation(int visibleView) {
View shownView = getViewFromFlag(visibleView);
View hiddenView = getViewFromFlag(mVisibleView);
shownView.setVisibility(View.VISIBLE);
hiddenView.setVisibility(View.VISIBLE);
shownView.setLayerType(LAYER_TYPE_HARDWARE, mFadePaint);
hiddenView.setLayerType(LAYER_TYPE_HARDWARE, mFadePaint);
setLayerType(LAYER_TYPE_HARDWARE, null);
mContractedChild.animate()
.alpha(showContractedChild ? 1f : 0f)
hiddenView.animate()
.alpha(0f)
.setDuration(ANIMATION_DURATION_LENGTH)
.setInterpolator(mLinearInterpolator);
mExpandedChild.animate()
.alpha(showContractedChild ? 0f : 1f)
.setInterpolator(mLinearInterpolator)
.withEndAction(null); // In case we have multiple changes in one frame.
shownView.animate()
.alpha(1f)
.setDuration(ANIMATION_DURATION_LENGTH)
.setInterpolator(mLinearInterpolator)
.withEndAction(new Runnable() {
@Override
public void run() {
mContractedChild.setLayerType(LAYER_TYPE_NONE, null);
mExpandedChild.setLayerType(LAYER_TYPE_NONE, null);
setLayerType(LAYER_TYPE_NONE, null);
mContractedChild.setVisibility(showContractedChild
? View.VISIBLE
: View.INVISIBLE);
mExpandedChild.setVisibility(showContractedChild
? View.INVISIBLE
: View.VISIBLE);
updateViewVisibilities(mVisibleView);
}
});
}
private boolean showContractedChild() {
return mContentHeight <= mSmallHeight || mExpandedChild == null;
private View getViewFromFlag(int visibleView) {
switch (visibleView) {
case EXPANDED:
return mExpandedChild;
case HEADSUP:
return mHeadsUpChild;
}
return mContractedChild;
}
private int calculateVisibleView() {
boolean noExpandedChild = mExpandedChild == null;
if (mIsHeadsUp) {
if (mContentHeight <= mHeadsUpHeight || noExpandedChild) {
return HEADSUP;
} else {
return EXPANDED;
}
} else {
if (mContentHeight <= mSmallHeight || noExpandedChild) {
return CONTRACTED;
} else {
return EXPANDED;
}
}
}
public void notifyContentUpdated() {
@@ -261,6 +370,11 @@ public class NotificationContentView extends FrameLayout {
mContractedWrapper.setDark(dark, fade, delay);
}
public void setHeadsUp(boolean headsUp) {
mIsHeadsUp = headsUp;
selectLayout(false /* animate */, true /* force */);
}
@Override
public boolean hasOverlappingRendering() {

View File

@@ -176,7 +176,8 @@ import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARE
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener, HeadsUpManager.OnHeadsUpChangedListener {
DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
HeadsUpManager.OnHeadsUpChangedListener {
static final String TAG = "PhoneStatusBar";
public static final boolean DEBUG = BaseStatusBar.DEBUG;
public static final boolean SPEW = false;
@@ -1106,13 +1107,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
public void addNotification(StatusBarNotification notification, RankingMap ranking,
Entry oldEntry) {
if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());
boolean isHeadsUp = mUseHeadsUp && shouldInterrupt(notification);
Entry shadeEntry = createNotificationViews(notification, isHeadsUp);
Entry shadeEntry = createNotificationViews(notification);
if (shadeEntry == null) {
return;
}
if (isHeadsUp) {
if (mUseHeadsUp && shouldInterrupt(notification)) {
mHeadsUpManager.showNotification(shadeEntry);
}

View File

@@ -720,7 +720,8 @@ public class NotificationStackScrollLayout extends ViewGroup
public boolean canChildBeExpanded(View v) {
return v instanceof ExpandableNotificationRow
&& ((ExpandableNotificationRow) v).isExpandable();
&& ((ExpandableNotificationRow) v).isExpandable()
&& !((ExpandableNotificationRow) v).isHeadsUp();
}
public void setUserExpandedChild(View v, boolean userExpanded) {
@@ -1766,16 +1767,17 @@ public class NotificationStackScrollLayout extends ViewGroup
}
private void updateNotificationAnimationStates() {
boolean running = mIsExpanded && mAnimationsEnabled;
boolean running = mAnimationsEnabled;
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
running &= mIsExpanded || isPinnedHeadsUp(child);
updateAnimationState(running, child);
}
}
private void updateAnimationState(View child) {
updateAnimationState(mAnimationsEnabled && mIsExpanded, child);
updateAnimationState((mAnimationsEnabled || isPinnedHeadsUp(child)) && mIsExpanded, child);
}

View File

@@ -506,11 +506,10 @@ public class StackScrollAlgorithm {
childViewState.yTranslation += ambientState.getTopPadding()
+ ambientState.getStackTranslation();
}
updateHeadsUpStates(resultState, algorithmState, ambientState);
updateHeadsUpStates(resultState, ambientState);
}
private void updateHeadsUpStates(StackScrollState resultState,
StackScrollAlgorithmState algorithmState, AmbientState ambientState) {
private void updateHeadsUpStates(StackScrollState resultState, AmbientState ambientState) {
TreeSet<HeadsUpManager.HeadsUpEntry> headsUpEntries = ambientState.getSortedHeadsUpEntries();
for (HeadsUpManager.HeadsUpEntry entry: headsUpEntries) {
ExpandableNotificationRow row = entry.entry.row;
@@ -518,6 +517,9 @@ public class StackScrollAlgorithm {
if (!row.isInShade()) {
childState.yTranslation = 0;
}
if (ambientState.getTopHeadsUpEntry() == row) {
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
@@ -569,7 +571,8 @@ public class StackScrollAlgorithm {
if (child instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) child;
if (ambientState != null && ambientState.getTopHeadsUpEntry() == child) {
return mCollapsedSize;
int extraSize = row.getIntrinsicHeight() - row.getHeadsUpHeight();
return mCollapsedSize + extraSize;
}
return row.getIntrinsicHeight();
} else if (child instanceof ExpandableView) {