diff options
| author | 2023-06-13 15:39:53 -0400 | |
|---|---|---|
| committer | 2023-06-13 15:55:50 -0400 | |
| commit | bd04a0160f7a0c165e4b5d7fbeeb4c5f180a2ede (patch) | |
| tree | abb2fd11b3d20c25d86e6da7234e1ad4cd7debb2 | |
| parent | aaaf84c811682f67cb40826d3c8d15fe12331af9 (diff) | |
Fix some QSFragment leaks
* QSIconViewImpl will clear registered animator callbacks from the
previous drawable.
* InternetDialogController will clear the callback when the dialog is
stopped.
Test: atest QSIconViewImplTest InternetDialogControllerTest
Test: manual: heapdump
Fixes: 285012720
Change-Id: Ic37f65b19319d43eb07063e6e1532ca9cec09187
4 files changed, 38 insertions, 3 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java index cd69f4edff63..e54168162de6 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java @@ -130,6 +130,11 @@ public class QSIconViewImpl extends QSIconView { d.setLayoutDirection(getLayoutDirection()); } + final Drawable lastDrawable = iv.getDrawable(); + if (lastDrawable instanceof Animatable2) { + ((Animatable2) lastDrawable).clearAnimationCallbacks(); + } + if (iv instanceof SlashImageView) { ((SlashImageView) iv).setAnimationEnabled(shouldAnimate); ((SlashImageView) iv).setState(null, d); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java index abeb5af352fc..9d2c8acd9522 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java @@ -172,7 +172,8 @@ public class InternetDialogController implements AccessPointController.AccessPoi private Executor mExecutor; private AccessPointController mAccessPointController; private IntentFilter mConnectionStateFilter; - private InternetDialogCallback mCallback; + @VisibleForTesting + InternetDialogCallback mCallback; private UiEventLogger mUiEventLogger; private BroadcastDispatcher mBroadcastDispatcher; private KeyguardUpdateMonitor mKeyguardUpdateMonitor; @@ -215,12 +216,16 @@ public class InternetDialogController implements AccessPointController.AccessPoi new KeyguardUpdateMonitorCallback() { @Override public void onRefreshCarrierInfo() { - mCallback.onRefreshCarrierInfo(); + if (mCallback != null) { + mCallback.onRefreshCarrierInfo(); + } } @Override public void onSimStateChanged(int subId, int slotId, int simState) { - mCallback.onSimStateChanged(); + if (mCallback != null) { + mCallback.onSimStateChanged(); + } } }; @@ -331,6 +336,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateCallback); mConnectivityManager.unregisterNetworkCallback(mConnectivityManagerNetworkCallback); mConnectedWifiInternetMonitor.unregisterCallback(); + mCallback = null; } @VisibleForTesting diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java index f55d262cfc0d..180fed904d01 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java @@ -155,6 +155,28 @@ public class QSIconViewImplTest extends SysuiTestCase { inOrder.verify(d).stop(); } + @Test + public void testAnimatorCallbackRemovedOnOldDrawable() { + ImageView iv = new ImageView(mContext); + AnimatedVectorDrawable d1 = mock(AnimatedVectorDrawable.class); + when(d1.getConstantState()).thenReturn(fakeConstantState(d1)); + AnimatedVectorDrawable d2 = mock(AnimatedVectorDrawable.class); + when(d2.getConstantState()).thenReturn(fakeConstantState(d2)); + State s = new State(); + s.isTransient = true; + + // When set Animatable2 d1 + s.icon = new QSTileImpl.DrawableIcon(d1); + mIconView.updateIcon(iv, s, true); + + // And then set Animatable2 d2 + s.icon = new QSTileImpl.DrawableIcon(d2); + mIconView.updateIcon(iv, s, true); + + // Then d1 has its callback cleared + verify(d1).clearAnimationCallbacks(); + } + private static Drawable.ConstantState fakeConstantState(Drawable otherDrawable) { return new Drawable.ConstantState() { @Override diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java index 66143923132b..5b3068744df0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java @@ -968,6 +968,7 @@ public class InternetDialogControllerTest extends SysuiTestCase { assertThat(mInternetDialogController.mSubIdTelephonyManagerMap.get(SUB_ID)).isEqualTo( mTelephonyManager); assertThat(mInternetDialogController.mSubIdTelephonyCallbackMap.get(SUB_ID)).isNotNull(); + assertThat(mInternetDialogController.mCallback).isNotNull(); mInternetDialogController.onStop(); @@ -980,6 +981,7 @@ public class InternetDialogControllerTest extends SysuiTestCase { verify(mAccessPointController).removeAccessPointCallback(mInternetDialogController); verify(mConnectivityManager).unregisterNetworkCallback( any(ConnectivityManager.NetworkCallback.class)); + assertThat(mInternetDialogController.mCallback).isNull(); } private String getResourcesString(String name) { |