diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 5964f632da1a1..2996c3d871201 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -3781,6 +3781,7 @@ public interface WindowManager extends ViewManager { out.writeInt(screenOrientation); out.writeFloat(preferredRefreshRate); out.writeInt(preferredDisplayModeId); + out.writeFloat(preferredMaxDisplayRefreshRate); out.writeInt(systemUiVisibility); out.writeInt(subtreeSystemUiVisibility); out.writeBoolean(hasSystemUiListeners); @@ -3851,6 +3852,7 @@ public interface WindowManager extends ViewManager { screenOrientation = in.readInt(); preferredRefreshRate = in.readFloat(); preferredDisplayModeId = in.readInt(); + preferredMaxDisplayRefreshRate = in.readFloat(); systemUiVisibility = in.readInt(); subtreeSystemUiVisibility = in.readInt(); hasSystemUiListeners = in.readBoolean(); @@ -3928,6 +3930,8 @@ public interface WindowManager extends ViewManager { public static final int MINIMAL_POST_PROCESSING_PREFERENCE_CHANGED = 1 << 28; /** {@hide} */ public static final int BLUR_BEHIND_RADIUS_CHANGED = 1 << 29; + /** {@hide} */ + public static final int PREFERRED_MAX_DISPLAY_REFRESH_RATE = 1 << 30; // internal buffer to backup/restore parameters under compatibility mode. private int[] mCompatibilityParamsBackup = null; @@ -4059,6 +4063,11 @@ public interface WindowManager extends ViewManager { changes |= PREFERRED_DISPLAY_MODE_ID; } + if (preferredMaxDisplayRefreshRate != o.preferredMaxDisplayRefreshRate) { + preferredMaxDisplayRefreshRate = o.preferredMaxDisplayRefreshRate; + changes |= PREFERRED_MAX_DISPLAY_REFRESH_RATE; + } + if (systemUiVisibility != o.systemUiVisibility || subtreeSystemUiVisibility != o.subtreeSystemUiVisibility) { systemUiVisibility = o.systemUiVisibility; @@ -4263,6 +4272,10 @@ public interface WindowManager extends ViewManager { sb.append(" preferredDisplayMode="); sb.append(preferredDisplayModeId); } + if (preferredMaxDisplayRefreshRate != 0) { + sb.append(" preferredMaxDisplayRefreshRate="); + sb.append(preferredMaxDisplayRefreshRate); + } if (hasSystemUiListeners) { sb.append(" sysuil="); sb.append(hasSystemUiListeners); diff --git a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java index 20b987de9aa14..e1696924dd3df 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java @@ -24,9 +24,11 @@ import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import android.os.Parcel; import android.platform.test.annotations.Presubmit; import android.view.Display.Mode; import android.view.DisplayInfo; +import android.view.WindowManager.LayoutParams; import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; @@ -50,6 +52,16 @@ public class RefreshRatePolicyTest extends WindowTestsBase { private RefreshRatePolicy mPolicy; private HighRefreshRateDenylist mDenylist = mock(HighRefreshRateDenylist.class); + // Parcel and Unparcel the LayoutParams in the window state to test the path the object + // travels from the app's process to system server + void parcelLayoutParams(WindowState window) { + Parcel parcel = Parcel.obtain(); + window.mAttrs.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + window.mAttrs.copyFrom(new LayoutParams(parcel)); + parcel.recycle(); + } + @Before public void setUp() { DisplayInfo di = new DisplayInfo(mDisplayInfo); @@ -69,6 +81,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { final WindowState cameraUsingWindow = createWindow(null, TYPE_BASE_APPLICATION, "cameraUsingWindow"); cameraUsingWindow.mAttrs.packageName = "com.android.test"; + parcelLayoutParams(cameraUsingWindow); assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow)); assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE); assertEquals(0, mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE); @@ -86,6 +99,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { final WindowState denylistedWindow = createWindow(null, TYPE_BASE_APPLICATION, "denylistedWindow"); denylistedWindow.mAttrs.packageName = "com.android.test"; + parcelLayoutParams(denylistedWindow); when(mDenylist.isDenylisted("com.android.test")).thenReturn(true); assertEquals(0, mPolicy.getPreferredModeId(denylistedWindow)); assertEquals(60, mPolicy.getPreferredRefreshRate(denylistedWindow), FLOAT_TOLERANCE); @@ -97,6 +111,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { "overrideWindow"); overrideWindow.mAttrs.packageName = "com.android.test"; overrideWindow.mAttrs.preferredDisplayModeId = LOW_MODE_ID; + parcelLayoutParams(overrideWindow); when(mDenylist.isDenylisted("com.android.test")).thenReturn(true); assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(overrideWindow)); assertEquals(60, mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE); @@ -108,6 +123,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { "overrideWindow"); overrideWindow.mAttrs.packageName = "com.android.test"; overrideWindow.mAttrs.preferredDisplayModeId = LOW_MODE_ID; + parcelLayoutParams(overrideWindow); mPolicy.addNonHighRefreshRatePackage("com.android.test"); assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(overrideWindow)); assertEquals(0, mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE); @@ -120,6 +136,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { "overrideWindow"); overrideWindow.mAttrs.packageName = "com.android.test"; overrideWindow.mAttrs.preferredDisplayModeId = LOW_MODE_ID; + parcelLayoutParams(overrideWindow); overrideWindow.mActivityRecord.mSurfaceAnimator.startAnimation( overrideWindow.getPendingTransaction(), mock(AnimationAdapter.class), false /* hidden */, ANIMATION_TYPE_APP_TRANSITION); @@ -134,6 +151,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { final WindowState cameraUsingWindow = createWindow(null, TYPE_BASE_APPLICATION, "cameraUsingWindow"); cameraUsingWindow.mAttrs.packageName = "com.android.test"; + parcelLayoutParams(cameraUsingWindow); mPolicy.addNonHighRefreshRatePackage("com.android.test"); assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow)); @@ -152,6 +170,7 @@ public class RefreshRatePolicyTest extends WindowTestsBase { public void testAppMaxRefreshRate() { final WindowState window = createWindow(null, TYPE_BASE_APPLICATION, "window"); window.mAttrs.preferredMaxDisplayRefreshRate = 60f; + parcelLayoutParams(window); assertEquals(0, mPolicy.getPreferredModeId(window)); assertEquals(0, mPolicy.getPreferredRefreshRate(window), FLOAT_TOLERANCE); assertEquals(60, mPolicy.getPreferredMaxRefreshRate(window), FLOAT_TOLERANCE);