diff options
| author | 2024-10-28 13:53:12 +0000 | |
|---|---|---|
| committer | 2024-10-28 13:53:12 +0000 | |
| commit | 3c6c3f7cad2b06279bdf03828cec0dd982a9541f (patch) | |
| tree | 4cc1c218e8991936a310a9963ddc646e4c1961a1 | |
| parent | cd37fee41fe8efd94b0450210f8c0d8b2f04bb86 (diff) | |
| parent | 8b782bd73bf7f4bb8fac9d083bb9274467e39f31 (diff) | |
Merge changes from topic "374107471" into main
* changes:
Trigger configuration listener after reattach
Fix crash when folding with open shade
5 files changed, 131 insertions, 9 deletions
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt index 58801e01d9d6..e725ce589f3e 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt @@ -128,10 +128,10 @@ private fun SceneScope.stateForQuickSettingsContent( QSSceneAdapter.State.QS } else -> - error( - "Bad transition for QuickSettings: fromContent=$fromContent," + - " toScene=$toContent" - ) + // We are not in a transition between states that have QS, so just make + // sure it's closed. This could be an issue if going from SplitShade to + // a folded device. + QSSceneAdapter.State.CLOSED } } is TransitionState.Transition.OverlayTransition -> diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java index 527aeaac426d..83f95eaf4cda 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java @@ -28,6 +28,8 @@ 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.anyInt; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; @@ -604,6 +606,46 @@ public class QSPanelControllerBaseTest extends SysuiTestCase { assertThat(mPagedTileLayoutListening).isFalse(); } + @Test + public void reAttach_configurationChangePending_triggersConfigurationListener() { + mController.onViewDetached(); + + when(mQSPanel.hadConfigurationChangeWhileDetached()).thenReturn(true); + clearInvocations(mQSLogger); + + mController.onViewAttached(); + + verify(mQSLogger).logOnConfigurationChanged( + anyInt(), + anyInt(), + anyBoolean(), + anyBoolean(), + anyInt(), + anyInt(), + anyString() + ); + } + + @Test + public void reAttach_noConfigurationChangePending_doesntTriggerConfigurationListener() { + mController.onViewDetached(); + + when(mQSPanel.hadConfigurationChangeWhileDetached()).thenReturn(false); + clearInvocations(mQSLogger); + + mController.onViewAttached(); + + verify(mQSLogger, never()).logOnConfigurationChanged( + anyInt(), + anyInt(), + anyBoolean(), + anyBoolean(), + anyInt(), + anyInt(), + anyString() + ); + } + private boolean usingMediaPlayer() { return !SceneContainerFlag.isEnabled(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index d3bed27ab2ab..602f593731c5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -116,6 +116,8 @@ public class QSPanel extends LinearLayout implements Tunable { @Nullable private View mMediaViewPlaceHolderForScene; + private boolean mHadConfigurationChangeWhileDetached; + public QSPanel(Context context, AttributeSet attrs) { super(context, attrs); mUsingMediaPlayer = useQsMediaPlayer(context); @@ -425,10 +427,23 @@ public class QSPanel extends LinearLayout implements Tunable { @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); + if (!isAttachedToWindow()) { + mHadConfigurationChangeWhileDetached = true; + } mOnConfigurationChangedListeners.forEach( listener -> listener.onConfigurationChange(newConfig)); } + final boolean hadConfigurationChangeWhileDetached() { + return mHadConfigurationChangeWhileDetached; + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + mHadConfigurationChangeWhileDetached = false; + } + @Override protected void onFinishInflate() { super.onFinishInflate(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java index 6cf5b32e469b..85bcc25e140c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java @@ -234,6 +234,12 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr mMediaHost.addVisibilityChangeListener(mMediaHostVisibilityListener); } mView.addOnConfigurationChangedListener(mOnConfigurationChangedListener); + // We were not attached and the configuration may have changed, trigger the listener. + if (mView.hadConfigurationChangeWhileDetached()) { + mOnConfigurationChangedListener.onConfigurationChange( + getContext().getResources().getConfiguration() + ); + } setTiles(); mLastOrientation = getResources().getConfiguration().orientation; mLastScreenLayout = getResources().getConfiguration().screenLayout; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt index 8aaa121640a3..3c922dcb4fd2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt @@ -13,6 +13,7 @@ */ package com.android.systemui.qs +import android.content.res.Configuration import android.graphics.Rect import android.platform.test.flag.junit.FlagsParameterization import android.testing.TestableContext @@ -91,7 +92,9 @@ class QSPanelTest(flags: FlagsParameterization) : SysuiTestCase() { @After fun tearDown() { - ViewUtils.detachView(qsPanel) + if (qsPanel.isAttachedToWindow) { + ViewUtils.detachView(qsPanel) + } } @Test @@ -119,7 +122,7 @@ class QSPanelTest(flags: FlagsParameterization) : SysuiTestCase() { qsPanel.tileLayout?.addTile( QSPanelControllerBase.TileRecord( mock(QSTile::class.java), - QSTileViewImpl(themedContext) + QSTileViewImpl(themedContext), ) ) @@ -129,7 +132,7 @@ class QSPanelTest(flags: FlagsParameterization) : SysuiTestCase() { qsPanel.setUsingHorizontalLayout(/* horizontal */ true, mediaView, /* force */ true) qsPanel.measure( /* width */ View.MeasureSpec.makeMeasureSpec(3000, View.MeasureSpec.EXACTLY), - /* height */ View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY) + /* height */ View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY), ) qsPanel.layout(0, 0, qsPanel.measuredWidth, qsPanel.measuredHeight) @@ -147,7 +150,7 @@ class QSPanelTest(flags: FlagsParameterization) : SysuiTestCase() { val padding = 10 themedContext.orCreateTestableResources.addOverride( R.dimen.qs_panel_padding_bottom, - padding + padding, ) qsPanel.updatePadding() assertThat(qsPanel.paddingBottom).isEqualTo(padding) @@ -160,7 +163,7 @@ class QSPanelTest(flags: FlagsParameterization) : SysuiTestCase() { themedContext.orCreateTestableResources.addOverride(R.dimen.qs_panel_padding_top, padding) themedContext.orCreateTestableResources.addOverride( R.dimen.qs_panel_padding_top, - paddingCombined + paddingCombined, ) qsPanel.updatePadding() @@ -267,6 +270,62 @@ class QSPanelTest(flags: FlagsParameterization) : SysuiTestCase() { assertThat(qsPanel.tileLayout!!.maxColumns).isEqualTo(2) } + @Test + fun noPendingConfigChangesAtBeginning() { + assertThat(qsPanel.hadConfigurationChangeWhileDetached()).isFalse() + } + + @Test + fun configChangesWhileDetached_pendingConfigChanges() { + ViewUtils.detachView(qsPanel) + + qsPanel.onConfigurationChanged(Configuration()) + + assertThat(qsPanel.hadConfigurationChangeWhileDetached()).isTrue() + } + + @Test + fun configChangesWhileDetached_reattach_pendingConfigChanges() { + ViewUtils.detachView(qsPanel) + + qsPanel.onConfigurationChanged(Configuration()) + testableLooper.runWithLooper { ViewUtils.attachView(qsPanel) } + + assertThat(qsPanel.hadConfigurationChangeWhileDetached()).isTrue() + } + + @Test + fun configChangesWhileDetached_reattach_detach_pendingConfigChanges_reset() { + ViewUtils.detachView(qsPanel) + + qsPanel.onConfigurationChanged(Configuration()) + + testableLooper.runWithLooper { ViewUtils.attachView(qsPanel) } + ViewUtils.detachView(qsPanel) + + assertThat(qsPanel.hadConfigurationChangeWhileDetached()).isFalse() + } + + @Test + fun configChangeWhileAttached_noPendingConfigChanges() { + qsPanel.onConfigurationChanged(Configuration()) + + assertThat(qsPanel.hadConfigurationChangeWhileDetached()).isFalse() + } + + @Test + fun configChangeWhileAttachedWithPending_doesntResetPending() { + ViewUtils.detachView(qsPanel) + + qsPanel.onConfigurationChanged(Configuration()) + + testableLooper.runWithLooper { ViewUtils.attachView(qsPanel) } + + qsPanel.onConfigurationChanged(Configuration()) + + assertThat(qsPanel.hadConfigurationChangeWhileDetached()).isTrue() + } + companion object { @Parameters(name = "{0}") @JvmStatic fun getParams() = parameterizeSceneContainerFlag() } |