summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt103
3 files changed, 85 insertions, 39 deletions
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 8ef1e568cd58..08a22a87c2ba 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
@@ -17,6 +17,7 @@
package com.android.systemui.shade.domain.interactor
import android.content.Context
+import android.content.MutableContextWrapper
import android.content.res.Configuration
import android.content.res.Resources
import android.view.Display
@@ -66,11 +67,12 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
ShadeDisplaysInteractor(
shadeRootview,
positionRepository,
- defaultContext,
+ MutableContextWrapper(defaultContext),
+ resources,
contextStore,
- testScope,
+ testScope.backgroundScope,
configurationForwarder,
- testScope.coroutineContext,
+ testScope.backgroundScope.coroutineContext,
)
@Before
@@ -79,7 +81,6 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
whenever(display.displayId).thenReturn(0)
whenever(resources.configuration).thenReturn(configuration)
- whenever(resources.configuration).thenReturn(configuration)
whenever(defaultContext.displayId).thenReturn(0)
whenever(defaultContext.getSystemService(any())).thenReturn(defaultWm)
@@ -124,7 +125,6 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
whenever(display.displayId).thenReturn(0)
positionRepository.setDisplayId(1)
interactor.start()
- testScope.advanceUntilIdle()
verify(defaultWm).removeView(eq(shadeRootview))
verify(secondaryWm).addView(eq(shadeRootview), any())
@@ -135,10 +135,8 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
whenever(display.displayId).thenReturn(0)
positionRepository.setDisplayId(0)
interactor.start()
- testScope.advanceUntilIdle()
positionRepository.setDisplayId(1)
- testScope.advanceUntilIdle()
verify(defaultWm).removeView(eq(shadeRootview))
verify(secondaryWm).addView(eq(shadeRootview), any())
@@ -149,10 +147,8 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
whenever(display.displayId).thenReturn(0)
positionRepository.setDisplayId(0)
interactor.start()
- testScope.advanceUntilIdle()
positionRepository.setDisplayId(1)
- testScope.advanceUntilIdle()
verify(configurationForwarder).onConfigurationChanged(eq(configuration))
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
index 4f73a3456cad..bf2ea56b0c67 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
@@ -17,9 +17,9 @@
package com.android.systemui.shade
import android.content.Context
+import android.content.MutableContextWrapper
import android.content.res.Resources
import android.view.LayoutInflater
-import android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
import com.android.systemui.CoreStartable
import com.android.systemui.common.ui.ConfigurationState
import com.android.systemui.common.ui.ConfigurationStateImpl
@@ -29,7 +29,6 @@ import com.android.systemui.common.ui.data.repository.ConfigurationRepositoryImp
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractorImpl
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.res.R
import com.android.systemui.shade.data.repository.ShadeDisplaysRepository
import com.android.systemui.shade.data.repository.ShadeDisplaysRepositoryImpl
import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
@@ -62,9 +61,7 @@ object ShadeDisplayAwareModule {
@SysUISingleton
fun provideShadeDisplayAwareContext(context: Context): Context {
return if (ShadeWindowGoesAround.isEnabled) {
- context
- .createWindowContext(context.display, TYPE_APPLICATION_OVERLAY, /* options= */ null)
- .apply { setTheme(R.style.Theme_SystemUI) }
+ MutableContextWrapper(context)
} else {
context
}
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 1055dcb55d5f..18dbba1d0d25 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,8 +16,13 @@
package com.android.systemui.shade.domain.interactor
+import android.content.ComponentCallbacks
import android.content.Context
+import android.content.MutableContextWrapper
+import android.content.res.Configuration
+import android.content.res.Resources
import android.util.Log
+import android.view.WindowManager
import android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE
import com.android.app.tracing.coroutines.launchTraced
import com.android.app.tracing.traceSection
@@ -46,12 +51,17 @@ constructor(
private val shadeRootView: WindowRootView,
private val shadePositionRepository: ShadeDisplaysRepository,
@ShadeDisplayAware private val shadeContext: Context,
+ @ShadeDisplayAware private val shadeResources: Resources,
private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository,
@Background private val bgScope: CoroutineScope,
- @ShadeDisplayAware private val configurationForwarder: ConfigurationForwarder,
- @Main private val mainContext: CoroutineContext,
+ @ShadeDisplayAware private val shadeConfigurationForwarder: ConfigurationForwarder,
+ @Main private val mainThreadContext: CoroutineContext,
) : CoreStartable {
+ // TODO: b/362719719 - Get rid of this callback as the root view should automatically get the
+ // correct configuration once it's moved to another window.
+ private var unregisterConfigChangedCallbacks: (() -> Unit)? = null
+
override fun start() {
ShadeWindowGoesAround.isUnexpectedlyInLegacyMode()
bgScope.launchTraced(TAG) {
@@ -60,43 +70,86 @@ constructor(
}
/** Tries to move the shade. If anything wrong happens, fails gracefully without crashing. */
- private suspend fun moveShadeWindowTo(destinationDisplayId: Int) {
- val currentId = shadeRootView.display.displayId
- if (currentId == destinationDisplayId) {
+ private suspend fun moveShadeWindowTo(destinationId: Int) {
+ Log.d(TAG, "Trying to move shade window to display with id $destinationId")
+ val currentDisplay = shadeRootView.display
+ if (currentDisplay == null) {
+ Log.w(TAG, "Current shade display is null")
+ return
+ }
+ val currentId = currentDisplay.displayId
+ if (currentId == destinationId) {
Log.w(TAG, "Trying to move the shade to a display it was already in")
return
}
try {
- moveShadeWindow(fromId = currentId, toId = destinationDisplayId)
+ moveShadeWindow(fromId = currentId, toId = destinationId)
} catch (e: IllegalStateException) {
Log.e(
TAG,
- "Unable to move the shade window from display $currentId to $destinationDisplayId",
+ "Unable to move the shade window from display $currentId to $destinationId",
e,
)
}
}
private suspend fun moveShadeWindow(fromId: Int, toId: Int) {
- val sourceProperties = getDisplayWindowProperties(fromId)
- val destinationProperties = getDisplayWindowProperties(toId)
- traceSection({ "MovingShadeWindow from $fromId to $toId" }) {
- withContext(mainContext) {
- traceSection("removeView") {
- sourceProperties.windowManager.removeView(shadeRootView)
- }
- traceSection("addView") {
- destinationProperties.windowManager.addView(
- shadeRootView,
- ShadeWindowLayoutParams.create(shadeContext),
- )
- }
+ val (_, _, _, sourceWm) = getDisplayWindowProperties(fromId)
+ val (_, _, destContext, destWm) = getDisplayWindowProperties(toId)
+ withContext(mainThreadContext) {
+ traceSection({ "MovingShadeWindow from $fromId to $toId" }) {
+ removeShade(sourceWm)
+ addShade(destWm)
+ overrideContextAndResources(newContext = destContext)
+ registerConfigurationChange(destContext)
+ }
+ traceSection("ShadeDisplaysInteractor#onConfigurationChanged") {
+ dispatchConfigurationChanged(destContext.resources.configuration)
}
}
- traceSection("SecondaryShadeInteractor#onConfigurationChanged") {
- configurationForwarder.onConfigurationChanged(
- destinationProperties.context.resources.configuration
- )
+ }
+
+ private fun removeShade(wm: WindowManager): Unit =
+ traceSection("removeView") { wm.removeView(shadeRootView) }
+
+ private fun addShade(wm: WindowManager): Unit =
+ traceSection("addView") {
+ wm.addView(shadeRootView, ShadeWindowLayoutParams.create(shadeContext))
+ }
+
+ private fun overrideContextAndResources(newContext: Context) {
+ val contextWrapper =
+ shadeContext as? MutableContextWrapper
+ ?: error("Shade context is not a MutableContextWrapper!")
+ contextWrapper.baseContext = newContext
+ // Override needed in case someone is keeping a reference to the resources from the old
+ // context.
+ // TODO: b/362719719 - This shouldn't be needed, as resources should be updated when the
+ // window is moved to the new display automatically.
+ shadeResources.impl = shadeContext.resources.impl
+ }
+
+ private fun dispatchConfigurationChanged(newConfig: Configuration) {
+ shadeConfigurationForwarder.onConfigurationChanged(newConfig)
+ shadeRootView.dispatchConfigurationChanged(newConfig)
+ shadeRootView.requestLayout()
+ }
+
+ private fun registerConfigurationChange(context: Context) {
+ // we should keep only one at the time.
+ unregisterConfigChangedCallbacks?.invoke()
+ val callback =
+ object : ComponentCallbacks {
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ dispatchConfigurationChanged(newConfig)
+ }
+
+ override fun onLowMemory() {}
+ }
+ context.registerComponentCallbacks(callback)
+ unregisterConfigChangedCallbacks = {
+ context.unregisterComponentCallbacks(callback)
+ unregisterConfigChangedCallbacks = null
}
}
@@ -105,6 +158,6 @@ constructor(
}
private companion object {
- const val TAG = "SecondaryShadeInteractor"
+ const val TAG = "ShadeDisplaysInteractor"
}
}