summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Selim Cinek <cinek@google.com> 2016-11-29 15:42:34 -0800
committer Selim Cinek <cinek@google.com> 2016-12-07 15:57:44 -0800
commit65d418ec8957fb1af03a8cc68aed90744a5848ff (patch)
tree3392ad852f7ee61758def70351a7112726a8f434
parent5ea19572afe9955555f73a24f0b18f7eb5727bdf (diff)
Improved the performance of the notification shelf
The shelf had a few inefficiencies that were adding up when calculating the positions. Test: runtest systemui-jank -c android.platform.systemui.tests.jank.SystemUiJankTests -m testNotificationListPull_manyNotifications Bug: 32437839 Change-Id: Iac08a7c364a924f1d0c14258461383b431f0542b
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java68
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java1
6 files changed, 85 insertions, 60 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 173f160a70d7..d4b478a87451 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -103,7 +103,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
private boolean mDimmed;
private boolean mDark;
- private int mBgTint = 0;
+ private int mBgTint = NO_COLOR;
private float mBgAlpha = 1f;
/**
@@ -481,8 +481,10 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
* Sets the tint color of the background
*/
public void setTintColor(int color, boolean animated) {
- mBgTint = color;
- updateBackgroundTint(animated);
+ if (color != mBgTint) {
+ mBgTint = color;
+ updateBackgroundTint(animated);
+ }
}
/**
@@ -541,13 +543,15 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
}
private void setBackgroundTintColor(int color) {
- mCurrentBackgroundTint = color;
- if (color == mNormalColor) {
- // We don't need to tint a normal notification
- color = 0;
+ if (color != mCurrentBackgroundTint) {
+ mCurrentBackgroundTint = color;
+ if (color == mNormalColor) {
+ // We don't need to tint a normal notification
+ color = 0;
+ }
+ mBackgroundDimmed.setTint(color);
+ mBackgroundNormal.setTint(color);
}
- mBackgroundDimmed.setTint(color);
- mBackgroundNormal.setTint(color);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index e4654e608d09..996e2ef587f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -1685,13 +1685,17 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
@Override
public void setClipBottomAmount(int clipBottomAmount) {
- super.setClipBottomAmount(clipBottomAmount);
- mPrivateLayout.setClipBottomAmount(clipBottomAmount);
- mPublicLayout.setClipBottomAmount(clipBottomAmount);
- if (mGuts != null) {
- mGuts.setClipBottomAmount(clipBottomAmount);
+ if (clipBottomAmount != mClipBottomAmount) {
+ super.setClipBottomAmount(clipBottomAmount);
+ mPrivateLayout.setClipBottomAmount(clipBottomAmount);
+ mPublicLayout.setClipBottomAmount(clipBottomAmount);
+ if (mGuts != null) {
+ mGuts.setClipBottomAmount(clipBottomAmount);
+ }
}
if (mChildrenContainer != null) {
+ // We have to update this even if it hasn't changed, since the children locations can
+ // have changed
mChildrenContainer.setClipBottomAmount(clipBottomAmount);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 0138ca86c3d3..80d41883066e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -37,8 +37,6 @@ import com.android.systemui.statusbar.stack.ExpandableViewState;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.StackScrollState;
-import java.util.WeakHashMap;
-
/**
* A notification shelf view that is placed inside the notification scroller. It manages the
* overflow icons that don't fit into the regular list anymore.
@@ -165,6 +163,7 @@ public class NotificationShelf extends ActivatableNotificationView {
mShelfState.notGoneIndex = Math.min(mShelfState.notGoneIndex, mNotGoneIndex);
}
mShelfState.hasItemsInStableShelf = lastViewState.inShelf;
+ mShelfState.hidden = !mAmbientState.isShadeExpanded();
} else {
mShelfState.hidden = true;
mShelfState.location = ExpandableViewState.LOCATION_GONE;
@@ -177,15 +176,15 @@ public class NotificationShelf extends ActivatableNotificationView {
* the icons from the notification area into the shelf.
*/
public void updateAppearance() {
- WeakHashMap<View, NotificationIconContainer.IconState> iconStates =
- mShelfIcons.resetViewStates();
+ mShelfIcons.resetViewStates();
+ float shelfStart = getTranslationY();
float numViewsInShelf = 0.0f;
View lastChild = mAmbientState.getLastVisibleBackgroundChild();
mNotGoneIndex = -1;
float interpolationStart = mMaxLayoutHeight - getIntrinsicHeight() * 2;
float expandAmount = 0.0f;
- if (getTranslationY() >= interpolationStart) {
- expandAmount = (getTranslationY() - interpolationStart) / getIntrinsicHeight();
+ if (shelfStart >= interpolationStart) {
+ expandAmount = (shelfStart - interpolationStart) / getIntrinsicHeight();
expandAmount = Math.min(1.0f, expandAmount);
}
// find the first view that doesn't overlap with the shelf
@@ -199,6 +198,7 @@ public class NotificationShelf extends ActivatableNotificationView {
int colorTwoBefore = NO_COLOR;
int previousColor = NO_COLOR;
float transitionAmount = 0.0f;
+ int baseZHeight = mAmbientState.getBaseZHeight();
while (notificationIndex < mHostLayout.getChildCount()) {
ExpandableView child = (ExpandableView) mHostLayout.getChildAt(notificationIndex);
notificationIndex++;
@@ -208,26 +208,26 @@ public class NotificationShelf extends ActivatableNotificationView {
}
ExpandableNotificationRow row = (ExpandableNotificationRow) child;
float notificationClipEnd;
- float shelfStart = getTranslationY();
- boolean aboveShelf = row.getTranslationZ() > mAmbientState.getBaseZHeight();
+ boolean aboveShelf = row.getTranslationZ() > baseZHeight;
boolean isLastChild = child == lastChild;
+ float rowTranslationY = row.getTranslationY();
if (isLastChild || aboveShelf || backgroundForceHidden) {
notificationClipEnd = shelfStart + getIntrinsicHeight();
} else {
notificationClipEnd = shelfStart - mPaddingBetweenElements;
- float height = notificationClipEnd - row.getTranslationY();
+ float height = notificationClipEnd - rowTranslationY;
if (!row.isBelowSpeedBump() && height <= getNotificationMergeSize()) {
// We want the gap to close when we reached the minimum size and only shrink
// before
notificationClipEnd = Math.min(shelfStart,
- row.getTranslationY() + getNotificationMergeSize());
+ rowTranslationY + getNotificationMergeSize());
}
}
updateNotificationClipHeight(row, notificationClipEnd);
float inShelfAmount = updateIconAppearance(row, expandAmount, isLastChild);
numViewsInShelf += inShelfAmount;
int ownColorUntinted = row.getBackgroundColorWithoutTint();
- if (row.getTranslationY() >= getTranslationY() && mNotGoneIndex == -1) {
+ if (rowTranslationY >= shelfStart && mNotGoneIndex == -1) {
mNotGoneIndex = notGoneIndex;
setTintColor(previousColor);
setOverrideTintColor(colorTwoBefore, transitionAmount);
@@ -250,9 +250,6 @@ public class NotificationShelf extends ActivatableNotificationView {
}
mShelfIcons.calculateIconTranslations();
mShelfIcons.applyIconStates();
- setVisibility(mAmbientState.isShadeExpanded()
- ? VISIBLE
- : INVISIBLE);
boolean hideBackground = numViewsInShelf < 1.0f;
setHideBackground(hideBackground || backgroundForceHidden);
if (mNotGoneIndex == -1) {
@@ -441,9 +438,11 @@ public class NotificationShelf extends ActivatableNotificationView {
}
private void setHideBackground(boolean hideBackground) {
- mHideBackground = hideBackground;
- updateBackground();
- updateOutline();
+ if (mHideBackground != hideBackground) {
+ mHideBackground = hideBackground;
+ updateBackground();
+ updateOutline();
+ }
}
public boolean hidesBackground() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 2621e4a50931..6650e7271b28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -455,6 +455,7 @@ public class StatusBarIconView extends AnimatedImageView {
}
public void setVisibleState(int visibleState, boolean animate, Runnable endRunnable) {
+ boolean runnableAdded = false;
if (visibleState != mVisibleState) {
mVisibleState = visibleState;
if (animate) {
@@ -467,20 +468,22 @@ public class StatusBarIconView extends AnimatedImageView {
targetAmount = 1.0f;
interpolator = Interpolators.LINEAR_OUT_SLOW_IN;
}
- mIconAppearAnimator = ObjectAnimator.ofFloat(this, ICON_APPEAR_AMOUNT,
- targetAmount);
- mIconAppearAnimator.setInterpolator(interpolator);
- mIconAppearAnimator.setDuration(100);
- mIconAppearAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mIconAppearAnimator = null;
- if (endRunnable != null) {
- endRunnable.run();
+ float currentAmount = getIconAppearAmount();
+ if (targetAmount != currentAmount) {
+ mIconAppearAnimator = ObjectAnimator.ofFloat(this, ICON_APPEAR_AMOUNT,
+ currentAmount, targetAmount);
+ mIconAppearAnimator.setInterpolator(interpolator);
+ mIconAppearAnimator.setDuration(100);
+ mIconAppearAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mIconAppearAnimator = null;
+ runRunnable(endRunnable);
}
- }
- });
- mIconAppearAnimator.start();
+ });
+ mIconAppearAnimator.start();
+ runnableAdded = true;
+ }
if (mDotAnimator != null) {
mDotAnimator.cancel();
@@ -491,22 +494,39 @@ public class StatusBarIconView extends AnimatedImageView {
targetAmount = 1.0f;
interpolator = Interpolators.LINEAR_OUT_SLOW_IN;
}
- mDotAnimator = ObjectAnimator.ofFloat(this, DOT_APPEAR_AMOUNT,
- targetAmount);
- mDotAnimator.setInterpolator(interpolator);
- mDotAnimator.setDuration(100);
- mDotAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mDotAnimator = null;
- }
- });
- mDotAnimator.start();
+ currentAmount = getDotAppearAmount();
+ if (targetAmount != currentAmount) {
+ mDotAnimator = ObjectAnimator.ofFloat(this, DOT_APPEAR_AMOUNT,
+ currentAmount, targetAmount);
+ mDotAnimator.setInterpolator(interpolator);
+ mDotAnimator.setDuration(100);
+ final boolean runRunnable = !runnableAdded;
+ mDotAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mDotAnimator = null;
+ if (runRunnable) {
+ runRunnable(endRunnable);
+ }
+ }
+ });
+ mDotAnimator.start();
+ runnableAdded = true;
+ }
} else {
setIconAppearAmount(visibleState == STATE_ICON ? 1.0f : 0.0f);
setDotAppearAmount(visibleState == STATE_DOT ? 1.0f : 0.0f);
}
}
+ if (!runnableAdded) {
+ runRunnable(endRunnable);
+ }
+ }
+
+ private void runRunnable(Runnable runnable) {
+ if (runnable != null) {
+ runnable.run();
+ }
}
public void setIconAppearAmount(float iconAppearAmount) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 160b23384740..294058474d15 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -31,7 +31,7 @@ import com.android.systemui.statusbar.stack.AnimationFilter;
import com.android.systemui.statusbar.stack.AnimationProperties;
import com.android.systemui.statusbar.stack.ViewState;
-import java.util.WeakHashMap;
+import java.util.HashMap;
/**
* A container for notification icons. It handles overflowing icons properly and positions them
@@ -80,7 +80,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
}.setDuration(200).setDelay(50);
private boolean mShowAllIcons = true;
- private WeakHashMap<View, IconState> mIconStates = new WeakHashMap<>();
+ private final HashMap<View, IconState> mIconStates = new HashMap<>();
private int mDotPadding;
private int mStaticDotRadius;
private int mActualLayoutWidth = -1;
@@ -200,14 +200,13 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
return getChildCount();
}
- public WeakHashMap<View, IconState> resetViewStates() {
+ public void resetViewStates() {
for (int i = 0; i < getChildCount(); i++) {
View view = getChildAt(i);
ViewState iconState = mIconStates.get(view);
iconState.initFrom(view);
iconState.alpha = 1.0f;
}
- return mIconStates;
}
/**
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 10d995ccadb5..4fb982b1f26b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -715,7 +715,6 @@ public class NotificationStackScrollLayout extends ViewGroup
requestChildrenUpdate();
}
setStackTranslation(translationY);
- requestChildrenUpdate();
}
private void setRequestedClipBounds(Rect clipRect) {