From 32cda054bd6d4db4659dfdb8679fbfde41623013 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Wed, 12 Jun 2024 13:38:00 +0000 Subject: Avoid premature redraw of display cutout This follows the concept of I90451c14dc28daa3f90a74c3117548fead25af3f ScreenDecorations should not request redraw by itself for display change. It should draw by the request from window manager, so the redrawn result can apply with display projection change together. This change avoids the premature path: DisplayRepository onDisplayChanged > onFaceSensorLocationChanged > updateOverlayProviderViews > onReloadResAndMeasure > View#setLayoutParams > VRI#requestLayout > VRI#scheduleTraversals Bug: 327693677 Test: atest ScreenDecorationsTest# \ testUpdateOverlayProviderViews_PendingConfigChange Test: Use Activity#setRequestedOrientation (display change event could arrive earlier from this path) to toggle orientation between SCREEN_ORIENTATION_LANDSCAPE and SCREEN_ORIENTATION_REVERSE_LANDSCAPE. The display cutout won't flicker on another side. Flag: EXEMPT bugfix Change-Id: I5d2c067c726281aa307b266c85bcb819be9d9079 --- .../src/com/android/systemui/ScreenDecorations.java | 5 +++++ .../com/android/systemui/ScreenDecorationsTest.java | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index 4c9af6607afa..e055e7c9683b 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -1250,6 +1250,11 @@ public class ScreenDecorations implements if (mOverlays == null) { return; } + if (mPendingConfigChange) { + // Let RestartingPreDrawListener's onPreDraw call updateConfiguration + // -> updateOverlayProviderViews to redraw with display change synchronously. + return; + } ++mProviderRefreshToken; for (final OverlayWindow overlay: mOverlays) { if (overlay == null) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java index d267ad449f45..54a14a292ba1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java @@ -39,6 +39,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isA; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -1181,6 +1182,24 @@ public class ScreenDecorationsTest extends SysuiTestCase { assertThat(mScreenDecorations.mIsRegistered, is(false)); } + @Test + public void testUpdateOverlayProviderViews_PendingConfigChange() { + final DecorProvider cutout = new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP); + spyOn(cutout); + doNothing().when(cutout).onReloadResAndMeasure(any(), anyInt(), anyInt(), anyInt(), any()); + mMockCutoutList.add(cutout); + mScreenDecorations.start(); + doCallRealMethod().when(mScreenDecorations).updateOverlayProviderViews(any()); + + mScreenDecorations.mPendingConfigChange = true; + mScreenDecorations.updateOverlayProviderViews(null /* filterIds */); + verify(cutout, never()).onReloadResAndMeasure(any(), anyInt(), anyInt(), anyInt(), any()); + + mScreenDecorations.mPendingConfigChange = false; + mScreenDecorations.updateOverlayProviderViews(null /* filterIds */); + verify(cutout).onReloadResAndMeasure(any(), anyInt(), anyInt(), anyInt(), any()); + } + @Test public void testSupportHwcLayer_SwitchFrom_NotSupport() { setupResources(0 /* radius */, 10 /* radiusTop */, 20 /* radiusBottom */, -- cgit v1.2.3-59-g8ed1b