summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2025-02-05 12:31:27 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2025-02-05 12:31:27 -0800
commitefb5ce49be646961a84eaded74cef3272ddf6f37 (patch)
tree6f0c3ed8800935f031d4a41c2ead196f2227b7ce
parentd8a84756d1079a78fc0b7b067637a534e029ebc6 (diff)
parent7b27cbe7dc466b14e111b4aff5f26e43143c90b7 (diff)
Merge changes Id2553666,I5fd86e53 into main
* changes: Fix config change race in (legacy) shade window Propagate shade config changes from WindowContext ComponentCallback
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerBaseSceneContainerTest.kt10
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java20
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerTest.kt3
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt5
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt9
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java87
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeStateTraceLogger.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeTraceLogger.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java25
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorKosmos.kt2
16 files changed, 158 insertions, 69 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerBaseSceneContainerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerBaseSceneContainerTest.kt
index 32e5fa1a8d59..5c560caaae04 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerBaseSceneContainerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerBaseSceneContainerTest.kt
@@ -36,6 +36,7 @@ import com.android.systemui.lifecycle.InstantTaskExecutorRule
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.qs.customize.QSCustomizerController
import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.SplitShadeStateController
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -80,6 +81,7 @@ class QSPanelControllerBaseSceneContainerTest : SysuiTestCase() {
private val configuration = Configuration()
@Mock private lateinit var viewTreeObserver: ViewTreeObserver
@Mock private lateinit var mediaHost: MediaHost
+ @Mock private lateinit var configurationController: ConfigurationController
private var isSplitShade = false
private val splitShadeStateController =
@@ -258,6 +260,7 @@ class QSPanelControllerBaseSceneContainerTest : SysuiTestCase() {
splitShadeStateController,
longPressEffectProvider,
mediaVisible,
+ configurationController,
)
}
@@ -272,7 +275,8 @@ class QSPanelControllerBaseSceneContainerTest : SysuiTestCase() {
dumpManager: DumpManager,
splitShadeStateController: SplitShadeStateController,
longPressEffectProvider: Provider<QSLongPressEffect>,
- private val mediaVisibleFlow: StateFlow<Boolean>
+ private val mediaVisibleFlow: StateFlow<Boolean>,
+ configurationController: ConfigurationController,
) :
QSPanelControllerBase<QSPanel>(
view,
@@ -285,12 +289,14 @@ class QSPanelControllerBaseSceneContainerTest : SysuiTestCase() {
qsLogger,
dumpManager,
splitShadeStateController,
- longPressEffectProvider
+ longPressEffectProvider,
+ configurationController,
) {
init {
whenever(view.dumpableTag).thenReturn(hashCode().toString())
}
+
override fun getMediaVisibleFlow(): StateFlow<Boolean> {
return mediaVisibleFlow
}
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 ff005c2b767a..0846b06cce03 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
@@ -40,6 +40,7 @@ import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.FlagsParameterization;
import android.testing.TestableLooper.RunWithLooper;
import android.view.ContextThemeWrapper;
@@ -51,6 +52,7 @@ import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.logging.testing.UiEventLoggerFake;
+import com.android.systemui.Flags;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.DisableSceneContainer;
@@ -64,6 +66,7 @@ import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.res.R;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController;
import com.android.systemui.util.animation.DisappearParameters;
@@ -134,6 +137,8 @@ public class QSPanelControllerBaseTest extends SysuiTestCase {
Runnable mHorizontalLayoutListener;
@Mock
private ViewTreeObserver mViewTreeObserver;
+ @Mock
+ ConfigurationController mConfigurationController;
private boolean mPagedTileLayoutListening = false;
@@ -151,7 +156,7 @@ public class QSPanelControllerBaseTest extends SysuiTestCase {
super(view, host, qsCustomizerController, usingMediaPlayer(),
mediaHost, metricsLogger, uiEventLogger,
qsLogger, dumpManager, new ResourcesSplitShadeStateController(),
- mLongPressEffectProvider);
+ mLongPressEffectProvider, mConfigurationController);
}
private MutableStateFlow<Boolean> mMediaVisible = MutableStateFlow(false);
@@ -633,6 +638,19 @@ public class QSPanelControllerBaseTest extends SysuiTestCase {
);
}
+ @Test
+ @EnableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND)
+ public void onViewAttached_registersConfigListener() {
+ reset(mConfigurationController);
+ mController.onViewAttached();
+
+ verify(mConfigurationController).addCallback(any());
+
+ mController.onViewDetached();
+
+ verify(mConfigurationController).removeCallback(any());
+ }
+
private boolean usingMediaPlayer() {
return !SceneContainerFlag.isEnabled();
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerTest.kt
index 96f6a622e2f3..0d4bc8c7a4e1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSPanelControllerTest.kt
@@ -22,6 +22,7 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.settings.brightness.BrightnessController
import com.android.systemui.settings.brightness.BrightnessSliderController
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
+import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.tuner.TunerService
import com.google.common.truth.Truth.assertThat
@@ -66,6 +67,7 @@ class QSPanelControllerTest : SysuiTestCase() {
@Mock private lateinit var pagedTileLayout: PagedTileLayout
@Mock private lateinit var longPressEffectProvider: Provider<QSLongPressEffect>
@Mock private lateinit var mediaCarouselInteractor: MediaCarouselInteractor
+ @Mock private lateinit var configurationController: ConfigurationController
private val usingMediaPlayer: Boolean by lazy { !SceneContainerFlag.isEnabled }
@@ -108,6 +110,7 @@ class QSPanelControllerTest : SysuiTestCase() {
ResourcesSplitShadeStateController(),
longPressEffectProvider,
mediaCarouselInteractor,
+ configurationController,
)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
index 7880aceb53be..896ca26e3e79 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
@@ -32,6 +32,7 @@ import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.qs.customize.QSCustomizerController
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.res.R
+import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.util.leak.RotationUtils
import javax.inject.Provider
@@ -64,6 +65,7 @@ class QuickQSPanelControllerTest : SysuiTestCase() {
@Captor private lateinit var captor: ArgumentCaptor<QSPanel.OnConfigurationChangedListener>
@Mock private lateinit var longPressEffectProvider: Provider<QSLongPressEffect>
@Mock private lateinit var mediaCarouselInteractor: MediaCarouselInteractor
+ @Mock private lateinit var configurationController: ConfigurationController
private val usingMediaPlayer: Boolean
get() = false
@@ -100,6 +102,7 @@ class QuickQSPanelControllerTest : SysuiTestCase() {
dumpManager,
longPressEffectProvider,
mediaCarouselInteractor,
+ configurationController,
)
controller.init()
@@ -171,6 +174,7 @@ class QuickQSPanelControllerTest : SysuiTestCase() {
dumpManager: DumpManager,
longPressEffectProvider: Provider<QSLongPressEffect>,
mediaCarouselInteractor: MediaCarouselInteractor,
+ configurationController: ConfigurationController,
) :
QuickQSPanelController(
view,
@@ -186,6 +190,7 @@ class QuickQSPanelControllerTest : SysuiTestCase() {
ResourcesSplitShadeStateController(),
longPressEffectProvider,
mediaCarouselInteractor,
+ configurationController,
) {
private var rotation = RotationUtils.ROTATION_NONE
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
index 72a57831e61a..a8b48363fe07 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
@@ -249,15 +249,6 @@ class NotificationShadeWindowViewTest : SysuiTestCase() {
@Test
@EnableFlags(AConfigFlags.FLAG_SHADE_WINDOW_GOES_AROUND)
- fun onConfigurationChanged_configForwarderSet_propagatesConfig() {
- val config = Configuration()
- underTest.onConfigurationChanged(config)
-
- verify(configurationForwarder).onConfigurationChanged(eq(config))
- }
-
- @Test
- @EnableFlags(AConfigFlags.FLAG_SHADE_WINDOW_GOES_AROUND)
fun onMovedToDisplay_configForwarderSet_propagatesConfig() {
val config = Configuration()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
index 246283c236fe..0ad60b617194 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
@@ -184,4 +184,11 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
verify(notificationStackRebindingHider).setVisible(eq(true), eq(true))
}
+
+ @Test
+ fun start_registersConfigChangeListener() {
+ underTest.start()
+
+ verify(shadeContext).registerComponentCallbacks(any())
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index d5cd8dc55045..b8971d1fa797 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -43,7 +43,9 @@ import com.android.systemui.settings.brightness.BrightnessController;
import com.android.systemui.settings.brightness.BrightnessMirrorHandler;
import com.android.systemui.settings.brightness.BrightnessSliderController;
import com.android.systemui.settings.brightness.MirrorController;
+import com.android.systemui.shade.ShadeDisplayAware;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.SplitShadeStateController;
import com.android.systemui.tuner.TunerService;
@@ -101,10 +103,11 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
SplitShadeStateController splitShadeStateController,
Provider<QSLongPressEffect> longPRessEffectProvider,
- MediaCarouselInteractor mediaCarouselInteractor) {
+ MediaCarouselInteractor mediaCarouselInteractor,
+ @ShadeDisplayAware ConfigurationController configurationController) {
super(view, qsHost, qsCustomizerController, usingMediaPlayer, mediaHost,
metricsLogger, uiEventLogger, qsLogger, dumpManager, splitShadeStateController,
- longPRessEffectProvider);
+ longPRessEffectProvider, configurationController);
mTunerService = tunerService;
mQsCustomizerController = qsCustomizerController;
mQsTileRevealControllerFactory = qsTileRevealControllerFactory;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index c8f7be6d80b2..b0b02fa28390 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -41,6 +41,10 @@ import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileViewImpl;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
+import com.android.systemui.shade.ShadeDisplayAware;
+import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
import com.android.systemui.statusbar.policy.SplitShadeStateController;
import com.android.systemui.util.ViewController;
import com.android.systemui.util.animation.DisappearParameters;
@@ -95,6 +99,7 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr
private final QSHost.Callback mQSHostCallback = this::setTiles;
private SplitShadeStateController mSplitShadeStateController;
+ private final ConfigurationController mConfigurationController;
private final Provider<QSLongPressEffect> mLongPressEffectProvider;
@@ -111,39 +116,42 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr
private boolean mLastListening;
+ private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
+ @Override
+ public void onConfigChanged(Configuration newConfig) {
+ final boolean previousSplitShadeState = mShouldUseSplitNotificationShade;
+ final int previousOrientation = mLastOrientation;
+ final int previousScreenLayout = mLastScreenLayout;
+ mShouldUseSplitNotificationShade = mSplitShadeStateController
+ .shouldUseSplitNotificationShade(getResources());
+ mLastOrientation = newConfig.orientation;
+ mLastScreenLayout = newConfig.screenLayout;
+
+ mQSLogger.logOnConfigurationChanged(
+ /* oldOrientation= */ previousOrientation,
+ /* newOrientation= */ mLastOrientation,
+ /* oldShouldUseSplitShade= */ previousSplitShadeState,
+ /* newShouldUseSplitShade= */ mShouldUseSplitNotificationShade,
+ /* oldScreenLayout= */ previousScreenLayout,
+ /* newScreenLayout= */ mLastScreenLayout,
+ /* containerName= */ mView.getDumpableTag());
+
+ if (SceneContainerFlag.isEnabled()) {
+ setLayoutForMediaInScene();
+ } else {
+ switchTileLayoutIfNeeded();
+ }
+ onConfigurationChanged();
+ if (previousSplitShadeState != mShouldUseSplitNotificationShade) {
+ onSplitShadeChanged(mShouldUseSplitNotificationShade);
+ }
+ }
+ };
+ /** When {@link ShadeWindowGoesAround} is enabled, this listener is not used anymore.*/
@VisibleForTesting
+ @Deprecated
protected final QSPanel.OnConfigurationChangedListener mOnConfigurationChangedListener =
- new QSPanel.OnConfigurationChangedListener() {
- @Override
- public void onConfigurationChange(Configuration newConfig) {
- final boolean previousSplitShadeState = mShouldUseSplitNotificationShade;
- final int previousOrientation = mLastOrientation;
- final int previousScreenLayout = mLastScreenLayout;
- mShouldUseSplitNotificationShade = mSplitShadeStateController
- .shouldUseSplitNotificationShade(getResources());
- mLastOrientation = newConfig.orientation;
- mLastScreenLayout = newConfig.screenLayout;
-
- mQSLogger.logOnConfigurationChanged(
- /* oldOrientation= */ previousOrientation,
- /* newOrientation= */ mLastOrientation,
- /* oldShouldUseSplitShade= */ previousSplitShadeState,
- /* newShouldUseSplitShade= */ mShouldUseSplitNotificationShade,
- /* oldScreenLayout= */ previousScreenLayout,
- /* newScreenLayout= */ mLastScreenLayout,
- /* containerName= */ mView.getDumpableTag());
-
- if (SceneContainerFlag.isEnabled()) {
- setLayoutForMediaInScene();
- } else {
- switchTileLayoutIfNeeded();
- }
- onConfigurationChanged();
- if (previousSplitShadeState != mShouldUseSplitNotificationShade) {
- onSplitShadeChanged(mShouldUseSplitNotificationShade);
- }
- }
- };
+ newConfig -> mConfigurationListener.onConfigChanged(newConfig);
protected void onConfigurationChanged() { }
@@ -173,7 +181,8 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr
QSLogger qsLogger,
DumpManager dumpManager,
SplitShadeStateController splitShadeStateController,
- Provider<QSLongPressEffect> longPressEffectProvider
+ Provider<QSLongPressEffect> longPressEffectProvider,
+ @ShadeDisplayAware ConfigurationController configurationController
) {
super(view);
mHost = host;
@@ -185,6 +194,7 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr
mQSLogger = qsLogger;
mDumpManager = dumpManager;
mSplitShadeStateController = splitShadeStateController;
+ mConfigurationController = configurationController;
mShouldUseSplitNotificationShade =
mSplitShadeStateController.shouldUseSplitNotificationShade(getResources());
mLongPressEffectProvider = longPressEffectProvider;
@@ -238,7 +248,11 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr
if (!SceneContainerFlag.isEnabled()) {
mMediaHost.addVisibilityChangeListener(mMediaHostVisibilityListener);
}
- mView.addOnConfigurationChangedListener(mOnConfigurationChangedListener);
+ if (ShadeWindowGoesAround.isEnabled()) {
+ mConfigurationController.addCallback(mConfigurationListener);
+ } else {
+ mView.addOnConfigurationChangedListener(mOnConfigurationChangedListener);
+ }
// We were not attached and the configuration may have changed, trigger the listener.
if (mView.hadConfigurationChangeWhileDetached()) {
mOnConfigurationChangedListener.onConfigurationChange(
@@ -272,8 +286,11 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr
@Override
protected void onViewDetached() {
mQSLogger.logOnViewDetached(mLastOrientation, mView.getDumpableTag());
- mView.removeOnConfigurationChangedListener(mOnConfigurationChangedListener);
-
+ if (ShadeWindowGoesAround.isEnabled()) {
+ mConfigurationController.removeCallback(mConfigurationListener);
+ } else {
+ mView.removeOnConfigurationChangedListener(mOnConfigurationChangedListener);
+ }
// Call directly so mLastListening is not modified. We want that to have the last actual
// value.
mView.getTileLayout().setListening(false, mUiEventLogger);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
index bc695bdd4e05..75628a0e487c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
@@ -35,6 +35,8 @@ import com.android.systemui.qs.dagger.QSScope;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.res.R;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
+import com.android.systemui.shade.ShadeDisplayAware;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.SplitShadeStateController;
import com.android.systemui.util.leak.RotationUtils;
@@ -66,11 +68,12 @@ public class QuickQSPanelController extends QSPanelControllerBase<QuickQSPanel>
MetricsLogger metricsLogger, UiEventLogger uiEventLogger, QSLogger qsLogger,
DumpManager dumpManager, SplitShadeStateController splitShadeStateController,
Provider<QSLongPressEffect> longPressEffectProvider,
- MediaCarouselInteractor mediaCarouselInteractor
+ MediaCarouselInteractor mediaCarouselInteractor,
+ @ShadeDisplayAware ConfigurationController configurationController
) {
super(view, qsHost, qsCustomizerController, usingMediaPlayer, mediaHost, metricsLogger,
uiEventLogger, qsLogger, dumpManager, splitShadeStateController,
- longPressEffectProvider);
+ longPressEffectProvider, configurationController);
mUsingCollapsedLandscapeMediaProvider = usingCollapsedLandscapeMediaProvider;
mMediaCarouselInteractor = mediaCarouselInteractor;
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 10d76fbd13a1..d0632d1fd2fb 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -49,6 +49,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Insets;
@@ -3377,6 +3378,13 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
private final class ConfigurationListener implements
ConfigurationController.ConfigurationListener {
@Override
+ public void onConfigChanged(Configuration newConfig) {
+ if (ShadeWindowGoesAround.isEnabled()) {
+ updateResources();
+ }
+ }
+
+ @Override
public void onThemeChanged() {
debugLog("onThemeChanged");
reInflateViews();
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
index 48e374746bf5..1721700d2aaf 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
@@ -187,10 +187,6 @@ public class NotificationShadeWindowView extends WindowRootView {
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
ShadeTraceLogger.logOnConfigChanged(newConfig);
- if (mConfigurationForwarder != null) {
- ShadeWindowGoesAround.isUnexpectedlyInLegacyMode();
- mConfigurationForwarder.onConfigurationChanged(newConfig);
- }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeStateTraceLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeStateTraceLogger.kt
index 6b183acbf9c2..bd7796118038 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeStateTraceLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeStateTraceLogger.kt
@@ -21,6 +21,7 @@ import com.android.app.tracing.TrackGroupUtils.trackGroup
import com.android.app.tracing.coroutines.TrackTracer.Companion.instantForGroup
import com.android.app.tracing.coroutines.launchTraced
import com.android.systemui.CoreStartable
+import com.android.systemui.common.ui.data.repository.ConfigurationRepository
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.shade.data.repository.ShadeDisplaysRepository
@@ -39,6 +40,7 @@ constructor(
private val shadeInteractor: ShadeInteractor,
private val shadeModeInteractor: ShadeModeInteractor,
private val shadeDisplaysRepository: Lazy<ShadeDisplaysRepository>,
+ @ShadeDisplayAware private val configurationRepository: ConfigurationRepository,
@Application private val scope: CoroutineScope,
) : CoreStartable {
override fun start() {
@@ -63,6 +65,15 @@ constructor(
}
}
}
+ launch {
+ configurationRepository.configurationValues.collect {
+ instantForGroup(
+ TRACK_GROUP_NAME,
+ "configurationChange#smallestScreenWidthDp",
+ it.smallestScreenWidthDp,
+ )
+ }
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeTraceLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeTraceLogger.kt
index 9a9fc467c53f..ed36204977f8 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeTraceLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeTraceLogger.kt
@@ -36,7 +36,10 @@ object ShadeTraceLogger {
@JvmStatic
fun logOnConfigChanged(config: Configuration) {
- t.instant { "onConfigurationChanged(dpi=${config.densityDpi})" }
+ t.instant {
+ "NotificationShadeWindowView#onConfigurationChanged(dpi=${config.densityDpi}, " +
+ "smallestWidthDp=${config.smallestScreenWidthDp})"
+ }
}
@JvmStatic
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
index b045db464674..e746274a39c1 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
@@ -16,6 +16,8 @@
package com.android.systemui.shade.domain.interactor
+import android.content.ComponentCallbacks
+import android.content.res.Configuration
import android.util.Log
import android.window.WindowContext
import androidx.annotation.UiThread
@@ -36,6 +38,7 @@ import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
import com.android.systemui.statusbar.notification.row.NotificationRebindingTracker
import com.android.systemui.statusbar.notification.stack.NotificationStackRebindingHider
+import com.android.systemui.statusbar.phone.ConfigurationForwarder
import com.android.systemui.util.kotlin.getOrNull
import com.android.window.flags.Flags
import java.util.Optional
@@ -65,6 +68,7 @@ constructor(
private val activeNotificationsInteractor: ActiveNotificationsInteractor,
private val notificationRebindingTracker: NotificationRebindingTracker,
notificationStackRebindingHider: Optional<NotificationStackRebindingHider>,
+ @ShadeDisplayAware private val configForwarder: ConfigurationForwarder,
) : CoreStartable {
private val shadeExpandedInteractor = requireOptional(shadeExpandedInteractor)
@@ -75,6 +79,7 @@ constructor(
override fun start() {
ShadeWindowGoesAround.isUnexpectedlyInLegacyMode()
+ listenForWindowContextConfigChanges()
bgScope.launchTraced(TAG) {
shadePositionRepository.displayId.collectLatest { displayId ->
moveShadeWindowTo(displayId)
@@ -82,6 +87,18 @@ constructor(
}
}
+ private fun listenForWindowContextConfigChanges() {
+ shadeContext.registerComponentCallbacks(
+ object : ComponentCallbacks {
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ configForwarder.onConfigurationChanged(newConfig)
+ }
+
+ override fun onLowMemory() {}
+ }
+ )
+ }
+
/** Tries to move the shade. If anything wrong happens, fails gracefully without crashing. */
private suspend fun moveShadeWindowTo(destinationId: Int) {
Log.d(TAG, "Trying to move shade window to display with id $destinationId")
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index b146b92ed110..a9b3753b42cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -21,15 +21,14 @@ import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.StatusBarManager.WindowVisibleState;
import static android.app.StatusBarManager.windowStateToString;
+import static android.service.quickaccesswallet.Flags.launchWalletOptionOnPowerDoubleTap;
+import static android.service.quickaccesswallet.Flags.launchWalletViaSysuiCallbacks;
import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO;
import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS;
import static androidx.lifecycle.Lifecycle.State.RESUMED;
-import static android.service.quickaccesswallet.Flags.launchWalletOptionOnPowerDoubleTap;
-import static android.service.quickaccesswallet.Flags.launchWalletViaSysuiCallbacks;
-
import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME;
import static com.android.systemui.Flags.keyboardShortcutHelperRewrite;
import static com.android.systemui.Flags.lightRevealMigration;
@@ -38,6 +37,7 @@ import static com.android.systemui.Flags.statusBarSignalPolicyRefactor;
import static com.android.systemui.charging.WirelessChargingAnimation.UNKNOWN_BATTERY_LEVEL;
import static com.android.systemui.flags.Flags.SHORTCUT_LIST_SEARCH_LAYOUT;
import static com.android.systemui.statusbar.StatusBarState.SHADE;
+
import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.app.IWallpaperManager;
@@ -176,6 +176,7 @@ import com.android.systemui.shade.ShadeExpansionStateManager;
import com.android.systemui.shade.ShadeLogger;
import com.android.systemui.shade.ShadeSurface;
import com.android.systemui.shade.ShadeViewController;
+import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround;
import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.shared.statusbar.phone.BarTransitions;
import com.android.systemui.statusbar.AutoHideUiElement;
@@ -1974,17 +1975,15 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
* meantime, just update the things that we know change.
*/
void updateResources() {
- // TODO: b/374267505 - we shouldn't propagate this from here. Each class should be
- // listening at the correct configuration change. For example, shade window classes should
- // be listening at @ShadeDisplayAware configurations (as it can be on a different display.
-
- // Update the quick setting tiles
- if (mQSPanelController != null) {
- mQSPanelController.updateResources();
- }
+ if (!ShadeWindowGoesAround.isEnabled()) {
+ // Each class now subscribes to configuration changes by themselves.
+ if (mQSPanelController != null) {
+ mQSPanelController.updateResources();
+ }
- if (mShadeSurface != null) {
- mShadeSurface.updateResources();
+ if (mShadeSurface != null) {
+ mShadeSurface.updateResources();
+ }
}
if (mBrightnessMirrorController != null) {
mBrightnessMirrorController.updateResources();
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorKosmos.kt
index 170d067b5c0c..46314135c574 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorKosmos.kt
@@ -28,6 +28,7 @@ import com.android.systemui.shade.data.repository.shadeExpansionIntent
import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
import com.android.systemui.statusbar.notification.row.notificationRebindingTracker
import com.android.systemui.statusbar.notification.stack.notificationStackRebindingHider
+import com.android.systemui.statusbar.policy.configurationController
import java.util.Optional
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
@@ -59,5 +60,6 @@ val Kosmos.shadeDisplaysInteractor by
activeNotificationsInteractor,
notificationRebindingTracker,
Optional.of(notificationStackRebindingHider),
+ configurationController,
)
}