Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d635960c authored by Nicolo' Mazzucato's avatar Nicolo' Mazzucato
Browse files

Propagate shade config changes from WindowContext ComponentCallback

When all the following are true:
- the shade window uses a WindowContext (so, com.android.systemui.shade_window_goes_around is on)
- The device is a foldable device
- The device state has been changed (e.g. from folded to unfolded or vice-versa)

The shade root view ends up receiving the wrong configuration (due to
b/394527409), as the configuration is sent before resources associated
with the window context are updated, resulting in it being the config
for the old display (e.g. after folding, the config received will still
be the one for the unfolded display)

This cl works around the issue by propagating the configuration from
WindowContext ComponentsCallback, which is guaranteed to propagate the
correct configuration after resources are updated.

This approach will fix the behaviour of all classes using
ConfigurationController/ConfigurationState/ConfigurationRepository, but
it doesn't fix the  issue of each View#onConfigurationChanged being
wrong after an unfold, that will be addressed as part of b/394527409.

Bug: 362719719
Bug: 391929792
Bug: 394527409
Test: ShadeDisplaysInteractorTest, NotificationShadeWindowViewTest, fold/unfold with flag on
Flag: com.android.systemui.shade_window_goes_around
Change-Id: I5fd86e5336ff17a0f9ce1ea1e2c99c4a1529cd3d
parent a708b619
Loading
Loading
Loading
Loading
+0 −9
Original line number Diff line number Diff line
@@ -247,15 +247,6 @@ class NotificationShadeWindowViewTest : SysuiTestCase() {
        verify(configurationForwarder, never()).onConfigurationChanged(any())
    }

    @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() {
+7 −0
Original line number Diff line number Diff line
@@ -184,4 +184,11 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {

            verify(notificationStackRebindingHider).setVisible(eq(true), eq(true))
        }

    @Test
    fun start_registersConfigChangeListener() {
        underTest.start()

        verify(shadeContext).registerComponentCallbacks(any())
    }
}
+0 −4
Original line number Diff line number Diff line
@@ -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
+4 −1
Original line number Diff line number Diff line
@@ -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
+17 −0
Original line number Diff line number Diff line
@@ -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")
Loading