summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI/src/com/android/systemui/statusbar
diff options
context:
space:
mode:
authorSelim Cinek <cinek@google.com>2015-04-10 00:05:50 -0700
committerSelim Cinek <cinek@google.com>2015-04-15 12:58:29 -0700
commit8d490d427c0b0cc321ae61987bb3cfc1c23ff930 (patch)
tree92047b903761fdde1fced4bd20f3fc6901bdae27 /packages/SystemUI/src/com/android/systemui/statusbar
parenta59ecc3401de0c4bf1e13665158f54669f22d06c (diff)
downloadframeworks_base-8d490d427c0b0cc321ae61987bb3cfc1c23ff930.zip
frameworks_base-8d490d427c0b0cc321ae61987bb3cfc1c23ff930.tar.gz
frameworks_base-8d490d427c0b0cc321ae61987bb3cfc1c23ff930.tar.bz2
Treating headsUpViews now as real notification citizen
Previously headsUpViews simply were replacing the content views, now they have their seperate space. Change-Id: I6b094975cdfdf5e082d546dd7a0bf633335f4ef8
Diffstat (limited to 'packages/SystemUI/src/com/android/systemui/statusbar')
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java96
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java192
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java11
6 files changed, 251 insertions, 104 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index dc0b0e4..33fa502 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -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);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 60093df..b759684 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -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 */);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 745e75d..7403f93 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -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);
@@ -73,6 +81,51 @@ public class NotificationContentView extends FrameLayout {
}
@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);
updateClipping();
@@ -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() {
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 ab4ac8b..c40a0c1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -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);
}
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 656f23a..57bbcfe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -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);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 1a42f45..1e3d6e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -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) {