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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 */);
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user