Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 87d09f88 authored by Ady Abraham's avatar Ady Abraham
Browse files

RefreshRatePolicy: a few fixes

RefreshRatePolicyTest had some tests that checks for an app override
vote but use the same vote as the deny list or camera that they are
trying to override. This CL fixes all tests and the implementation
to return the expected values.

Test: atest RefreshRatePolicyTest FrameRateSelectionPriorityTests
Bug: 192413241
Change-Id: I0f37f856947ea39de6ea11c77c11771cbca29b49
parent 1e5c50bb
Loading
Loading
Loading
Loading
+12 −23
Original line number Diff line number Diff line
@@ -89,20 +89,15 @@ 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;
    }

    /**
     * Calculate the priority based on whether the window is in focus and whether the application
     * voted for a specific refresh rate.
@@ -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,10 +143,17 @@ class RefreshRatePolicy {
            }
        }

        if (w.mAttrs.preferredRefreshRate != 0) {
        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;
    }

@@ -165,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;
    }

@@ -180,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;
        }
+141 −42
Original line number Diff line number Diff line
@@ -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);
        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 testAppOverride_camera() {
        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.preferredDisplayModeId = LOW_MODE_ID;
        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);
        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 testAnimatingAppOverride() {
        final WindowState overrideWindow = createWindow(null, TYPE_BASE_APPLICATION,
                "overrideWindow");
    public void testAnimatingAppOverridePreferredRefreshRate() {
        final WindowState overrideWindow = createWindow("overrideWindow");
        overrideWindow.mAttrs.packageName = "com.android.test";
        overrideWindow.mAttrs.preferredDisplayModeId = LOW_MODE_ID;
        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);
        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 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);
    }