From f1614a6ec2d972c1a975777d7998615c8ed4d142 Mon Sep 17 00:00:00 2001 From: Selim Cinek Date: Thu, 26 May 2016 16:57:20 -0700 Subject: [PATCH] Fixed a few memory leaks in SystemUI Fist of all we made the statemap a weak hashmap in order never to leak any views anymore. Another leak could occur because predrawlisteners were added twice but removal only removes one. A view was then leaked in case it was detached before predraw. Also fixed a leak when transforming the header because a state wasn't nulled. Change-Id: I2573a506c307196ef60c905dc823ea8a95e91a16 Fixes: 28945863 --- .../systemui/statusbar/NotificationContentView.java | 4 +++- .../statusbar/notification/HeaderTransformState.java | 7 ++++--- .../android/systemui/statusbar/stack/StackScrollState.java | 7 +++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java index 32b61cd1fe0ba..06863ab8997c7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java @@ -359,7 +359,9 @@ public class NotificationContentView extends FrameLayout { private void setVisible(final boolean isVisible) { if (isVisible) { - + // This call can happen multiple times, but removing only removes a single one. + // We therefore need to remove the old one. + getViewTreeObserver().removeOnPreDrawListener(mEnableAnimationPredrawListener); // We only animate if we are drawn at least once, otherwise the view might animate when // it's shown the first time getViewTreeObserver().addOnPreDrawListener(mEnableAnimationPredrawListener); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HeaderTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HeaderTransformState.java index b66e9f313e9a6..8463e069abc1e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HeaderTransformState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HeaderTransformState.java @@ -109,9 +109,6 @@ public class HeaderTransformState extends TransformState { @Override public void recycle() { super.recycle(); - if (mWorkProfileState != null) { - mWorkProfileState.recycle(); - } sInstancePool.release(this); } @@ -120,6 +117,10 @@ public class HeaderTransformState extends TransformState { super.reset(); mExpandButton = null; mWorkProfileState = null; + if (mWorkProfileState != null) { + mWorkProfileState.recycle(); + mWorkProfileState = null; + } } public void setVisible(boolean visible) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java index d6c5506781744..8f0cd8e63ee0a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java @@ -26,9 +26,8 @@ import com.android.systemui.statusbar.EmptyShadeView; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.ExpandableView; -import java.util.HashMap; import java.util.List; -import java.util.Map; +import java.util.WeakHashMap; /** * A state of a {@link com.android.systemui.statusbar.stack.NotificationStackScrollLayout} which @@ -39,12 +38,12 @@ public class StackScrollState { private static final String CHILD_NOT_FOUND_TAG = "StackScrollStateNoSuchChild"; private final ViewGroup mHostView; - private Map mStateMap; + private WeakHashMap mStateMap; private final int mClearAllTopPadding; public StackScrollState(ViewGroup hostView) { mHostView = hostView; - mStateMap = new HashMap(); + mStateMap = new WeakHashMap<>(); mClearAllTopPadding = hostView.getContext().getResources().getDimensionPixelSize( R.dimen.clear_all_padding_top); }