From f8b3ddfe4849449d2525d5b8590edab92f05824b Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Thu, 5 Nov 2020 12:16:48 -0500 Subject: [PATCH] Fix NPE when QSPanel not yet attached, The NotificationPanelViewController tries to use the QSPanelController before the QSPanel has been attached (sometimes). Handle the case where it tries to set the expansion pre-attachment and add a corresponding test. Fixes: 172520720 Test: atest SystemUITests Change-Id: Ib957201760de21561df59ec6e4f459ae7bcbf828 --- .../com/android/systemui/qs/QSFragment.java | 2 +- .../systemui/qs/QSPanelControllerBase.java | 13 ++++--- .../qs/QSPanelControllerBaseTest.java | 35 +++++++++++++++++++ 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java index e1bca4a42b895..f9eea174ff77d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java @@ -413,7 +413,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca } } mFooter.setExpansion(onKeyguardAndExpanded ? 1 : expansion); - mQSPanelController.getQsTileRevealController().setExpansion(expansion); + mQSPanelController.setRevealExpansion(expansion); mQSPanelController.getTileLayout().setExpansion(expansion); mQSPanelScrollView.setTranslationY(translationScaleY * heightDiff); if (fullyCollapsed) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java index 0a4151b382101..214904098670b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java @@ -56,7 +56,9 @@ public abstract class QSPanelControllerBase extends ViewContr protected final ArrayList mRecords = new ArrayList<>(); private int mLastOrientation; + private String mCachedSpecs = ""; private QSTileRevealController mQsTileRevealController; + private float mRevealExpansion; private final QSHost.Callback mQSHostCallback = this::setTiles; @@ -70,7 +72,6 @@ public abstract class QSPanelControllerBase extends ViewContr } } }; - private String mCachedSpecs = ""; protected QSPanelControllerBase(T view, QSTileHost host, QSCustomizerController qsCustomizerController, @@ -92,6 +93,7 @@ public abstract class QSPanelControllerBase extends ViewContr if (regularTileLayout instanceof PagedTileLayout) { mQsTileRevealController = mQsTileRevealControllerFactory.create( (PagedTileLayout) regularTileLayout); + mQsTileRevealController.setExpansion(mRevealExpansion); } mView.addOnConfigurationChangedListener(mOnConfigurationChangedListener); @@ -246,9 +248,12 @@ public abstract class QSPanelControllerBase extends ViewContr } } - /** */ - public QSTileRevealController getQsTileRevealController() { - return mQsTileRevealController; + /** Set the expansion on the associated {@link QSTileRevealController}. */ + public void setRevealExpansion(float expansion) { + mRevealExpansion = expansion; + if (mQsTileRevealController != null) { + mQsTileRevealController.setExpansion(expansion); + } } @Override diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java index 64ef6dd90fe17..9421cd0800ff5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java @@ -19,9 +19,12 @@ package com.android.systemui.qs; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -112,8 +115,40 @@ public class QSPanelControllerBaseTest extends SysuiTestCase { mUiEventLogger, mDumpManager); mController.init(); + reset(mQSTileRevealController); } + @Test + public void testSetRevealExpansion_preAttach() { + mController.onViewDetached(); + + QSPanelControllerBase controller = new TestableQSPanelControllerBase(mQSPanel, + mQSTileHost, mQSCustomizerController, mQSTileRevealControllerFactory, + mMetricsLogger, mUiEventLogger, mDumpManager); + + // Nothing happens until attached + controller.setRevealExpansion(0); + verify(mQSTileRevealController, never()).setExpansion(anyFloat()); + controller.setRevealExpansion(0.5f); + verify(mQSTileRevealController, never()).setExpansion(anyFloat()); + controller.setRevealExpansion(1); + verify(mQSTileRevealController, never()).setExpansion(anyFloat()); + + controller.init(); + verify(mQSTileRevealController).setExpansion(1); + } + + @Test + public void testSetRevealExpansion_postAttach() { + mController.setRevealExpansion(0); + verify(mQSTileRevealController).setExpansion(0); + mController.setRevealExpansion(0.5f); + verify(mQSTileRevealController).setExpansion(0.5f); + mController.setRevealExpansion(1); + verify(mQSTileRevealController).setExpansion(1); + } + + @Test public void testSetExpanded_Metrics() { mController.setExpanded(true);