Merge changes I0f37f856,I55dc5c2a into sc-dev am: 5dea7907f3

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15193078

Change-Id: I43f9d3327da450a7da196702035d1ef4bbafcf2b
This commit is contained in:
Ady Abraham
2021-07-03 04:58:32 +00:00
committed by Automerger Merge Worker
3 changed files with 192 additions and 72 deletions

View File

@@ -89,18 +89,13 @@ class RefreshRatePolicy {
}
int getPreferredModeId(WindowState w) {
// If app is animating, it's not able to control refresh rate because we want the animation
// to run in default refresh rate.
if (w.isAnimating(TRANSITION | PARENTS)) {
return 0;
}
if (w.mAttrs.preferredRefreshRate != 0 || w.mAttrs.preferredDisplayModeId != 0) {
return w.mAttrs.preferredDisplayModeId;
}
return 0;
return w.mAttrs.preferredDisplayModeId;
}
/**
@@ -134,12 +129,9 @@ class RefreshRatePolicy {
return 0;
}
final String packageName = w.getOwningPackage();
if (mHighRefreshRateDenylist.isDenylisted(packageName)) {
return mLowRefreshRateMode.getRefreshRate();
}
final int preferredModeId = getPreferredModeId(w);
// If the app set a preferredDisplayModeId, the preferred refresh rate is the refresh rate
// of that mode id.
final int preferredModeId = w.mAttrs.preferredDisplayModeId;
if (preferredModeId > 0) {
DisplayInfo info = w.getDisplayInfo();
if (info != null) {
@@ -151,6 +143,17 @@ class RefreshRatePolicy {
}
}
if (w.mAttrs.preferredRefreshRate > 0) {
return w.mAttrs.preferredRefreshRate;
}
// If the app didn't set a preferred mode id or refresh rate, but it is part of the deny
// list, we return the low refresh rate as the preferred one.
final String packageName = w.getOwningPackage();
if (mHighRefreshRateDenylist.isDenylisted(packageName)) {
return mLowRefreshRateMode.getRefreshRate();
}
return 0;
}
@@ -161,11 +164,6 @@ class RefreshRatePolicy {
return 0;
}
// If app requests a certain refresh rate or mode, don't override it.
if (w.mAttrs.preferredDisplayModeId != 0) {
return 0;
}
return w.mAttrs.preferredMinDisplayRefreshRate;
}
@@ -176,11 +174,6 @@ class RefreshRatePolicy {
return 0;
}
// If app requests a certain refresh rate or mode, don't override it.
if (w.mAttrs.preferredDisplayModeId != 0) {
return 0;
}
if (w.mAttrs.preferredMaxDisplayRefreshRate > 0) {
return w.mAttrs.preferredMaxDisplayRefreshRate;
}

View File

@@ -228,7 +228,7 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase {
}
@Test
public void testPreferredRefreshRate() {
public void testDenyListPreferredRefreshRate() {
final WindowState appWindow = createWindow("appWindow");
assertNotNull("Window state is created", appWindow);
when(appWindow.getDisplayContent().getDisplayPolicy()).thenReturn(mDisplayPolicy);
@@ -281,4 +281,32 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase {
verify(appWindow.getPendingTransaction(), never()).setFrameRate(
any(SurfaceControl.class), anyInt(), anyInt(), anyInt());
}
@Test
public void testAppPreferredRefreshRate() {
final WindowState appWindow = createWindow("appWindow");
assertNotNull("Window state is created", appWindow);
when(appWindow.getDisplayContent().getDisplayPolicy()).thenReturn(mDisplayPolicy);
appWindow.mAttrs.packageName = "com.android.test";
appWindow.mAttrs.preferredRefreshRate = 60;
assertEquals(0, mRefreshRatePolicy.getPreferredModeId(appWindow));
assertEquals(60, mRefreshRatePolicy.getPreferredRefreshRate(appWindow), FLOAT_TOLERANCE);
appWindow.updateFrameRateSelectionPriorityIfNeeded();
assertEquals(RefreshRatePolicy.LAYER_PRIORITY_UNSET, appWindow.mFrameRateSelectionPriority);
assertEquals(60, appWindow.mAppPreferredFrameRate, FLOAT_TOLERANCE);
// Call the function a few times.
appWindow.updateFrameRateSelectionPriorityIfNeeded();
appWindow.updateFrameRateSelectionPriorityIfNeeded();
// Since nothing changed in the priority state, the transaction should not be updating.
verify(appWindow.getPendingTransaction(), never()).setFrameRateSelectionPriority(
any(SurfaceControl.class), anyInt());
verify(appWindow.getPendingTransaction(), times(1)).setFrameRate(
appWindow.getSurfaceControl(), 60,
Surface.FRAME_RATE_COMPATIBILITY_EXACT, Surface.CHANGE_FRAME_RATE_ALWAYS);
}
}

View File

@@ -27,7 +27,6 @@ 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;
@@ -47,7 +46,14 @@ import org.junit.runner.RunWith;
@FlakyTest
public class RefreshRatePolicyTest extends WindowTestsBase {
private static final float FLOAT_TOLERANCE = 0.01f;
private static final int HI_MODE_ID = 1;
private static final float HI_REFRESH_RATE = 90;
private static final int MID_MODE_ID = 2;
private static final float MID_REFRESH_RATE = 70;
private static final int LOW_MODE_ID = 3;
private static final float LOW_REFRESH_RATE = 60;
private RefreshRatePolicy mPolicy;
private HighRefreshRateDenylist mDenylist = mock(HighRefreshRateDenylist.class);
@@ -64,22 +70,31 @@ public class RefreshRatePolicyTest extends WindowTestsBase {
@Before
public void setUp() {
DisplayInfo di = new DisplayInfo(mDisplayInfo);
Mode defaultMode = di.getDefaultMode();
di.supportedModes = new Mode[] {
new Mode(1, defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), 90),
new Mode(2, defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), 70),
Mode defaultMode = mDisplayInfo.getDefaultMode();
mDisplayInfo.supportedModes = new Mode[] {
new Mode(HI_MODE_ID,
defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(),
HI_REFRESH_RATE),
new Mode(MID_MODE_ID,
defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(),
MID_REFRESH_RATE),
new Mode(LOW_MODE_ID,
defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), 60),
defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(),
LOW_REFRESH_RATE),
};
di.defaultModeId = 1;
mPolicy = new RefreshRatePolicy(mWm, di, mDenylist);
mDisplayInfo.defaultModeId = HI_MODE_ID;
mPolicy = new RefreshRatePolicy(mWm, mDisplayInfo, mDenylist);
}
WindowState createWindow(String name) {
WindowState window = createWindow(null, TYPE_BASE_APPLICATION, name);
when(window.getDisplayInfo()).thenReturn(mDisplayInfo);
return window;
}
@Test
public void testCamera() {
final WindowState cameraUsingWindow = createWindow(null, TYPE_BASE_APPLICATION,
"cameraUsingWindow");
final WindowState cameraUsingWindow = createWindow("cameraUsingWindow");
cameraUsingWindow.mAttrs.packageName = "com.android.test";
parcelLayoutParams(cameraUsingWindow);
assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
@@ -90,70 +105,152 @@ public class RefreshRatePolicyTest extends WindowTestsBase {
assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
assertEquals(60, mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
assertEquals(LOW_REFRESH_RATE,
mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
mPolicy.removeNonHighRefreshRatePackage("com.android.test");
assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
}
@Test
public void testDenyList() {
final WindowState denylistedWindow = createWindow(null, TYPE_BASE_APPLICATION,
"denylistedWindow");
final WindowState denylistedWindow = createWindow("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);
assertEquals(LOW_REFRESH_RATE,
mPolicy.getPreferredRefreshRate(denylistedWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(denylistedWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMaxRefreshRate(denylistedWindow), FLOAT_TOLERANCE);
}
@Test
public void testAppOverride_blacklist() {
final WindowState overrideWindow = createWindow(null, TYPE_BASE_APPLICATION,
"overrideWindow");
public void testAppOverridePreferredModeId_denylist() {
final WindowState overrideWindow = createWindow("overrideWindow");
overrideWindow.mAttrs.packageName = "com.android.test";
overrideWindow.mAttrs.preferredDisplayModeId = LOW_MODE_ID;
overrideWindow.mAttrs.preferredDisplayModeId = HI_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);
}
@Test
public void testAppOverride_camera() {
final WindowState overrideWindow = createWindow(null, TYPE_BASE_APPLICATION,
"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);
assertEquals(HI_MODE_ID, mPolicy.getPreferredModeId(overrideWindow));
assertEquals(HI_REFRESH_RATE,
mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
}
@Test
public void testAnimatingAppOverride() {
final WindowState overrideWindow = createWindow(null, TYPE_BASE_APPLICATION,
"overrideWindow");
public void testAppOverridePreferredRefreshRate_denylist() {
final WindowState overrideWindow = createWindow("overrideWindow");
overrideWindow.mAttrs.packageName = "com.android.test";
overrideWindow.mAttrs.preferredRefreshRate = HI_REFRESH_RATE;
parcelLayoutParams(overrideWindow);
when(mDenylist.isDenylisted("com.android.test")).thenReturn(true);
assertEquals(0, mPolicy.getPreferredModeId(overrideWindow));
assertEquals(HI_REFRESH_RATE,
mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
}
@Test
public void testAppOverridePreferredModeId_camera() {
final WindowState overrideWindow = createWindow("overrideWindow");
overrideWindow.mAttrs.packageName = "com.android.test";
overrideWindow.mAttrs.preferredDisplayModeId = HI_MODE_ID;
parcelLayoutParams(overrideWindow);
mPolicy.addNonHighRefreshRatePackage("com.android.test");
assertEquals(HI_MODE_ID, mPolicy.getPreferredModeId(overrideWindow));
assertEquals(HI_REFRESH_RATE,
mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(LOW_REFRESH_RATE,
mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
}
@Test
public void testAppOverridePreferredRefreshRate_camera() {
final WindowState overrideWindow = createWindow("overrideWindow");
overrideWindow.mAttrs.packageName = "com.android.test";
overrideWindow.mAttrs.preferredRefreshRate = HI_REFRESH_RATE;
parcelLayoutParams(overrideWindow);
mPolicy.addNonHighRefreshRatePackage("com.android.test");
assertEquals(0, mPolicy.getPreferredModeId(overrideWindow));
assertEquals(HI_REFRESH_RATE,
mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(LOW_REFRESH_RATE,
mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
}
@Test
public void testAnimatingAppOverridePreferredModeId() {
final WindowState overrideWindow = createWindow("overrideWindow");
overrideWindow.mAttrs.packageName = "com.android.test";
overrideWindow.mAttrs.preferredDisplayModeId = LOW_MODE_ID;
parcelLayoutParams(overrideWindow);
assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(overrideWindow));
assertEquals(LOW_REFRESH_RATE,
mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
overrideWindow.mActivityRecord.mSurfaceAnimator.startAnimation(
overrideWindow.getPendingTransaction(), mock(AnimationAdapter.class),
false /* hidden */, ANIMATION_TYPE_APP_TRANSITION);
mPolicy.addNonHighRefreshRatePackage("com.android.test");
assertEquals(0, mPolicy.getPreferredModeId(overrideWindow));
assertEquals(0, mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
}
@Test
public void testAnimatingAppOverridePreferredRefreshRate() {
final WindowState overrideWindow = createWindow("overrideWindow");
overrideWindow.mAttrs.packageName = "com.android.test";
overrideWindow.mAttrs.preferredRefreshRate = LOW_REFRESH_RATE;
parcelLayoutParams(overrideWindow);
assertEquals(0, mPolicy.getPreferredModeId(overrideWindow));
assertEquals(LOW_REFRESH_RATE,
mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
overrideWindow.mActivityRecord.mSurfaceAnimator.startAnimation(
overrideWindow.getPendingTransaction(), mock(AnimationAdapter.class),
false /* hidden */, ANIMATION_TYPE_APP_TRANSITION);
assertEquals(0, mPolicy.getPreferredModeId(overrideWindow));
assertEquals(0, mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
}
@Test
public void testAnimatingDenylist() {
final WindowState window = createWindow("overrideWindow");
window.mAttrs.packageName = "com.android.test";
parcelLayoutParams(window);
when(mDenylist.isDenylisted("com.android.test")).thenReturn(true);
assertEquals(0, mPolicy.getPreferredModeId(window));
assertEquals(LOW_REFRESH_RATE,
mPolicy.getPreferredRefreshRate(window), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(window), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMaxRefreshRate(window), FLOAT_TOLERANCE);
window.mActivityRecord.mSurfaceAnimator.startAnimation(
window.getPendingTransaction(), mock(AnimationAdapter.class),
false /* hidden */, ANIMATION_TYPE_APP_TRANSITION);
assertEquals(0, mPolicy.getPreferredModeId(window));
assertEquals(0, mPolicy.getPreferredRefreshRate(window), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(window), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMaxRefreshRate(window), FLOAT_TOLERANCE);
}
@Test
public void testAnimatingCamera() {
final WindowState cameraUsingWindow = createWindow(null, TYPE_BASE_APPLICATION,
"cameraUsingWindow");
final WindowState cameraUsingWindow = createWindow("cameraUsingWindow");
cameraUsingWindow.mAttrs.packageName = "com.android.test";
parcelLayoutParams(cameraUsingWindow);
@@ -161,7 +258,8 @@ public class RefreshRatePolicyTest extends WindowTestsBase {
assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
assertEquals(60, mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
assertEquals(LOW_REFRESH_RATE,
mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
cameraUsingWindow.mActivityRecord.mSurfaceAnimator.startAnimation(
cameraUsingWindow.getPendingTransaction(), mock(AnimationAdapter.class),
@@ -174,13 +272,13 @@ public class RefreshRatePolicyTest extends WindowTestsBase {
@Test
public void testAppMaxRefreshRate() {
final WindowState window = createWindow(null, TYPE_BASE_APPLICATION, "window");
window.mAttrs.preferredMaxDisplayRefreshRate = 60f;
final WindowState window = createWindow("window");
window.mAttrs.preferredMaxDisplayRefreshRate = LOW_REFRESH_RATE;
parcelLayoutParams(window);
assertEquals(0, mPolicy.getPreferredModeId(window));
assertEquals(0, mPolicy.getPreferredRefreshRate(window), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(window), FLOAT_TOLERANCE);
assertEquals(60, mPolicy.getPreferredMaxRefreshRate(window), FLOAT_TOLERANCE);
assertEquals(LOW_REFRESH_RATE, mPolicy.getPreferredMaxRefreshRate(window), FLOAT_TOLERANCE);
window.mActivityRecord.mSurfaceAnimator.startAnimation(
window.getPendingTransaction(), mock(AnimationAdapter.class),
@@ -193,12 +291,12 @@ public class RefreshRatePolicyTest extends WindowTestsBase {
@Test
public void testAppMinRefreshRate() {
final WindowState window = createWindow(null, TYPE_BASE_APPLICATION, "window");
window.mAttrs.preferredMinDisplayRefreshRate = 60f;
final WindowState window = createWindow("window");
window.mAttrs.preferredMinDisplayRefreshRate = LOW_REFRESH_RATE;
parcelLayoutParams(window);
assertEquals(0, mPolicy.getPreferredModeId(window));
assertEquals(0, mPolicy.getPreferredRefreshRate(window), FLOAT_TOLERANCE);
assertEquals(60, mPolicy.getPreferredMinRefreshRate(window), FLOAT_TOLERANCE);
assertEquals(LOW_REFRESH_RATE, mPolicy.getPreferredMinRefreshRate(window), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMaxRefreshRate(window), FLOAT_TOLERANCE);
window.mActivityRecord.mSurfaceAnimator.startAnimation(
@@ -206,16 +304,17 @@ public class RefreshRatePolicyTest extends WindowTestsBase {
false /* hidden */, ANIMATION_TYPE_APP_TRANSITION);
assertEquals(0, mPolicy.getPreferredModeId(window));
assertEquals(0, mPolicy.getPreferredRefreshRate(window), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(window), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMaxRefreshRate(window), FLOAT_TOLERANCE);
}
@Test
public void testAppPreferredRefreshRate() {
final WindowState window = createWindow(null, TYPE_BASE_APPLICATION, "window");
window.mAttrs.preferredRefreshRate = 60f;
final WindowState window = createWindow("window");
window.mAttrs.preferredRefreshRate = LOW_REFRESH_RATE;
parcelLayoutParams(window);
assertEquals(0, mPolicy.getPreferredModeId(window));
assertEquals(60, mPolicy.getPreferredRefreshRate(window), FLOAT_TOLERANCE);
assertEquals(LOW_REFRESH_RATE, mPolicy.getPreferredRefreshRate(window), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMinRefreshRate(window), FLOAT_TOLERANCE);
assertEquals(0, mPolicy.getPreferredMaxRefreshRate(window), FLOAT_TOLERANCE);
}