Loading packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java +28 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import static org.mockito.Mockito.when; import android.app.IActivityManager; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Rect; import android.platform.test.flag.junit.FlagsParameterization; import android.testing.TestableLooper.RunWithLooper; import android.view.View; Loading @@ -53,6 +54,7 @@ import com.android.systemui.biometrics.AuthController; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.communal.domain.interactor.CommunalInteractor; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.EnableSceneContainer; import com.android.systemui.flags.SceneContainerFlagParameterizationKt; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.kosmos.KosmosJavaAdapter; Loading Loading @@ -466,6 +468,32 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { assertThat(lp.preferredMinDisplayRefreshRate).isEqualTo(0); } @Test @EnableSceneContainer public void configChanged_boundsUpdate() { when(mNotificationShadeWindowView.getWidth()).thenReturn(1600); when(mNotificationShadeWindowView.getHeight()).thenReturn(800); when(mNotificationShadeWindowView.getVisibility()).thenReturn(View.INVISIBLE); Configuration newConfig = new Configuration(); // swap width and height in new bounds to simulate auto-rotate newConfig.windowConfiguration.setBounds(new Rect(0, 0, 800, 1600)); mNotificationShadeWindowController.onConfigChanged(newConfig); verify(mWindowManager, atLeastOnce()).updateViewLayout(any(), any()); } @Test @EnableSceneContainer public void configChanged_boundsDontUpdate() { when(mNotificationShadeWindowView.getWidth()).thenReturn(1600); when(mNotificationShadeWindowView.getHeight()).thenReturn(800); when(mNotificationShadeWindowView.getVisibility()).thenReturn(View.INVISIBLE); Configuration newConfig = new Configuration(); // same bounds as view's current bounds newConfig.windowConfiguration.setBounds(new Rect(0, 0, 1600, 800)); mNotificationShadeWindowController.onConfigChanged(newConfig); verify(mWindowManager, never()).updateViewLayout(any(), any()); } private void setKeyguardShowing() { mNotificationShadeWindowController.setKeyguardShowing(true); mNotificationShadeWindowController.setKeyguardGoingAway(false); Loading packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java +24 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.content.Context; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.Region; import android.os.Binder; import android.os.Build; Loading Loading @@ -987,6 +988,19 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW @Override public void onConfigChanged(Configuration newConfig) { // If the shade window is not visible, the bounds will not update until it becomes visible. // Touches that should invoke shade expansion but are not within those incorrect bounds // (because the shape of the shade window remains portrait after flipping to landscape) will // be dropped, causing the shade expansion to fail silently. Since the shade doesn't open, // it doesn't become visible, and the bounds will never update. Therefore, we must detect // the incorrect bounds here and force the update so that touches are routed correctly. if (SceneContainerFlag.isEnabled() && mWindowRootView.getVisibility() == View.INVISIBLE) { Rect bounds = newConfig.windowConfiguration.getBounds(); if (mWindowRootView.getWidth() != bounds.width()) { mLogger.logConfigChangeWidthAdjust(mWindowRootView.getWidth(), bounds.width()); updateRootViewBounds(bounds); } } final boolean newScreenRotationAllowed = mKeyguardStateController .isKeyguardScreenRotationAllowed(); Loading @@ -996,6 +1010,16 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW } } private void updateRootViewBounds(Rect bounds) { int originalMlpWidth = mLp.width; int originalMlpHeight = mLp.height; mLp.width = bounds.width(); mLp.height = bounds.height(); mWindowManager.updateViewLayout(mWindowRootView, mLp); mLp.width = originalMlpWidth; mLp.height = originalMlpHeight; } /** * When keyguard will be dismissed but didn't start animation yet. */ Loading packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt +23 −13 Original line number Diff line number Diff line Loading @@ -31,18 +31,13 @@ class ShadeWindowLogger @Inject constructor(@ShadeWindowLog private val buffer: ConstantStringsLogger by ConstantStringsLoggerImpl(buffer, TAG) { fun logNewState(state: Any) { buffer.log( TAG, DEBUG, { str1 = state.toString() }, { "Applying new state: $str1" } ) buffer.log(TAG, DEBUG, { str1 = state.toString() }, { "Applying new state: $str1" }) } private inline fun log( logLevel: LogLevel, initializer: LogMessage.() -> Unit, noinline printer: LogMessage.() -> String noinline printer: LogMessage.() -> String, ) { buffer.log(TAG, logLevel, initializer, printer) } Loading @@ -52,7 +47,8 @@ class ShadeWindowLogger @Inject constructor(@ShadeWindowLog private val buffer: TAG, DEBUG, { bool1 = visible }, { "Updating visibility, should be visible : $bool1" }) { "Updating visibility, should be visible : $bool1" }, ) } fun logIsExpanded( Loading @@ -65,7 +61,7 @@ class ShadeWindowLogger @Inject constructor(@ShadeWindowLog private val buffer: headsUpNotificationShowing: Boolean, scrimsVisibilityNotTransparent: Boolean, backgroundBlurRadius: Boolean, launchingActivityFromNotification: Boolean launchingActivityFromNotification: Boolean, ) { buffer.log( TAG, Loading @@ -82,11 +78,13 @@ class ShadeWindowLogger @Inject constructor(@ShadeWindowLog private val buffer: long2 = if (backgroundBlurRadius) 1 else 0 double1 = if (launchingActivityFromNotification) 1.0 else 0.0 }, { "Setting isExpanded to $str1: forceWindowCollapsed $bool1, " + { "Setting isExpanded to $str1: forceWindowCollapsed $bool1, " + "isKeyguardShowingAndNotOccluded $bool2, panelVisible $bool3, " + "keyguardFadingAway $bool4, bouncerShowing $int1," + "headsUpNotificationShowing $int2, scrimsVisibilityNotTransparent $long1," + "backgroundBlurRadius $long2, launchingActivityFromNotification $double1"} "backgroundBlurRadius $long2, launchingActivityFromNotification $double1" }, ) } Loading @@ -95,7 +93,7 @@ class ShadeWindowLogger @Inject constructor(@ShadeWindowLog private val buffer: TAG, DEBUG, { bool1 = visible }, { "Updating shade, should be visible and focusable: $bool1" } { "Updating shade, should be visible and focusable: $bool1" }, ) } Loading @@ -104,7 +102,19 @@ class ShadeWindowLogger @Inject constructor(@ShadeWindowLog private val buffer: TAG, DEBUG, { bool1 = focusable }, { "Updating shade, should be focusable : $bool1" } { "Updating shade, should be focusable : $bool1" }, ) } fun logConfigChangeWidthAdjust(originalWidth: Int, newWidth: Int) { buffer.log( TAG, DEBUG, { int1 = originalWidth int2 = newWidth }, { "Config changed. SceneWindowRootView width updating from $int1 to $int2." }, ) } } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java +28 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import static org.mockito.Mockito.when; import android.app.IActivityManager; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Rect; import android.platform.test.flag.junit.FlagsParameterization; import android.testing.TestableLooper.RunWithLooper; import android.view.View; Loading @@ -53,6 +54,7 @@ import com.android.systemui.biometrics.AuthController; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.communal.domain.interactor.CommunalInteractor; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.EnableSceneContainer; import com.android.systemui.flags.SceneContainerFlagParameterizationKt; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.kosmos.KosmosJavaAdapter; Loading Loading @@ -466,6 +468,32 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { assertThat(lp.preferredMinDisplayRefreshRate).isEqualTo(0); } @Test @EnableSceneContainer public void configChanged_boundsUpdate() { when(mNotificationShadeWindowView.getWidth()).thenReturn(1600); when(mNotificationShadeWindowView.getHeight()).thenReturn(800); when(mNotificationShadeWindowView.getVisibility()).thenReturn(View.INVISIBLE); Configuration newConfig = new Configuration(); // swap width and height in new bounds to simulate auto-rotate newConfig.windowConfiguration.setBounds(new Rect(0, 0, 800, 1600)); mNotificationShadeWindowController.onConfigChanged(newConfig); verify(mWindowManager, atLeastOnce()).updateViewLayout(any(), any()); } @Test @EnableSceneContainer public void configChanged_boundsDontUpdate() { when(mNotificationShadeWindowView.getWidth()).thenReturn(1600); when(mNotificationShadeWindowView.getHeight()).thenReturn(800); when(mNotificationShadeWindowView.getVisibility()).thenReturn(View.INVISIBLE); Configuration newConfig = new Configuration(); // same bounds as view's current bounds newConfig.windowConfiguration.setBounds(new Rect(0, 0, 1600, 800)); mNotificationShadeWindowController.onConfigChanged(newConfig); verify(mWindowManager, never()).updateViewLayout(any(), any()); } private void setKeyguardShowing() { mNotificationShadeWindowController.setKeyguardShowing(true); mNotificationShadeWindowController.setKeyguardGoingAway(false); Loading
packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java +24 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.content.Context; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.Region; import android.os.Binder; import android.os.Build; Loading Loading @@ -987,6 +988,19 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW @Override public void onConfigChanged(Configuration newConfig) { // If the shade window is not visible, the bounds will not update until it becomes visible. // Touches that should invoke shade expansion but are not within those incorrect bounds // (because the shape of the shade window remains portrait after flipping to landscape) will // be dropped, causing the shade expansion to fail silently. Since the shade doesn't open, // it doesn't become visible, and the bounds will never update. Therefore, we must detect // the incorrect bounds here and force the update so that touches are routed correctly. if (SceneContainerFlag.isEnabled() && mWindowRootView.getVisibility() == View.INVISIBLE) { Rect bounds = newConfig.windowConfiguration.getBounds(); if (mWindowRootView.getWidth() != bounds.width()) { mLogger.logConfigChangeWidthAdjust(mWindowRootView.getWidth(), bounds.width()); updateRootViewBounds(bounds); } } final boolean newScreenRotationAllowed = mKeyguardStateController .isKeyguardScreenRotationAllowed(); Loading @@ -996,6 +1010,16 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW } } private void updateRootViewBounds(Rect bounds) { int originalMlpWidth = mLp.width; int originalMlpHeight = mLp.height; mLp.width = bounds.width(); mLp.height = bounds.height(); mWindowManager.updateViewLayout(mWindowRootView, mLp); mLp.width = originalMlpWidth; mLp.height = originalMlpHeight; } /** * When keyguard will be dismissed but didn't start animation yet. */ Loading
packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLogger.kt +23 −13 Original line number Diff line number Diff line Loading @@ -31,18 +31,13 @@ class ShadeWindowLogger @Inject constructor(@ShadeWindowLog private val buffer: ConstantStringsLogger by ConstantStringsLoggerImpl(buffer, TAG) { fun logNewState(state: Any) { buffer.log( TAG, DEBUG, { str1 = state.toString() }, { "Applying new state: $str1" } ) buffer.log(TAG, DEBUG, { str1 = state.toString() }, { "Applying new state: $str1" }) } private inline fun log( logLevel: LogLevel, initializer: LogMessage.() -> Unit, noinline printer: LogMessage.() -> String noinline printer: LogMessage.() -> String, ) { buffer.log(TAG, logLevel, initializer, printer) } Loading @@ -52,7 +47,8 @@ class ShadeWindowLogger @Inject constructor(@ShadeWindowLog private val buffer: TAG, DEBUG, { bool1 = visible }, { "Updating visibility, should be visible : $bool1" }) { "Updating visibility, should be visible : $bool1" }, ) } fun logIsExpanded( Loading @@ -65,7 +61,7 @@ class ShadeWindowLogger @Inject constructor(@ShadeWindowLog private val buffer: headsUpNotificationShowing: Boolean, scrimsVisibilityNotTransparent: Boolean, backgroundBlurRadius: Boolean, launchingActivityFromNotification: Boolean launchingActivityFromNotification: Boolean, ) { buffer.log( TAG, Loading @@ -82,11 +78,13 @@ class ShadeWindowLogger @Inject constructor(@ShadeWindowLog private val buffer: long2 = if (backgroundBlurRadius) 1 else 0 double1 = if (launchingActivityFromNotification) 1.0 else 0.0 }, { "Setting isExpanded to $str1: forceWindowCollapsed $bool1, " + { "Setting isExpanded to $str1: forceWindowCollapsed $bool1, " + "isKeyguardShowingAndNotOccluded $bool2, panelVisible $bool3, " + "keyguardFadingAway $bool4, bouncerShowing $int1," + "headsUpNotificationShowing $int2, scrimsVisibilityNotTransparent $long1," + "backgroundBlurRadius $long2, launchingActivityFromNotification $double1"} "backgroundBlurRadius $long2, launchingActivityFromNotification $double1" }, ) } Loading @@ -95,7 +93,7 @@ class ShadeWindowLogger @Inject constructor(@ShadeWindowLog private val buffer: TAG, DEBUG, { bool1 = visible }, { "Updating shade, should be visible and focusable: $bool1" } { "Updating shade, should be visible and focusable: $bool1" }, ) } Loading @@ -104,7 +102,19 @@ class ShadeWindowLogger @Inject constructor(@ShadeWindowLog private val buffer: TAG, DEBUG, { bool1 = focusable }, { "Updating shade, should be focusable : $bool1" } { "Updating shade, should be focusable : $bool1" }, ) } fun logConfigChangeWidthAdjust(originalWidth: Int, newWidth: Int) { buffer.log( TAG, DEBUG, { int1 = originalWidth int2 = newWidth }, { "Config changed. SceneWindowRootView width updating from $int1 to $int2." }, ) } }