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

Commit baec980e authored by Austin Borger's avatar Austin Borger Committed by Android (Google) Code Review
Browse files

Merge "Allow camera to specify a refresh rate range" into tm-dev

parents 0e0c3e43 edfaf5ac
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -1068,7 +1068,9 @@ public class CameraServiceProxy extends SystemService
                    if (!alreadyActivePackage) {
                        WindowManagerInternal wmi =
                                LocalServices.getService(WindowManagerInternal.class);
                        wmi.addNonHighRefreshRatePackage(clientName);
                        // TODO(b/209669709): populate min.max refreshRate based on
                        //  the camera capture speed
                        wmi.addRefreshRateRangeForPackage(clientName, 60.0f, 60.0f);
                    }

                    // Update activity events
@@ -1107,7 +1109,7 @@ public class CameraServiceProxy extends SystemService
                        if (!stillActivePackage) {
                            WindowManagerInternal wmi =
                                    LocalServices.getService(WindowManagerInternal.class);
                            wmi.removeNonHighRefreshRatePackage(clientName);
                            wmi.removeRefreshRateRangeForPackage(clientName);
                        }
                    }

+43 −9
Original line number Diff line number Diff line
@@ -19,20 +19,46 @@ package com.android.server.wm;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;

import android.util.ArraySet;
import android.hardware.display.DisplayManagerInternal.RefreshRateRange;
import android.view.Display;
import android.view.Display.Mode;
import android.view.DisplayInfo;

import java.util.HashMap;

/**
 * Policy to select a lower refresh rate for the display if applicable.
 */
class RefreshRatePolicy {

    class PackageRefreshRate {
        private final HashMap<String, RefreshRateRange> mPackages = new HashMap<>();

        public void add(String s, float minRefreshRate, float maxRefreshRate) {
            float minSupportedRefreshRate =
                    Math.max(RefreshRatePolicy.this.mMinSupportedRefreshRate, minRefreshRate);
            float maxSupportedRefreshRate =
                    Math.min(RefreshRatePolicy.this.mMaxSupportedRefreshRate, maxRefreshRate);

            mPackages.put(s,
                    new RefreshRateRange(minSupportedRefreshRate, maxSupportedRefreshRate));
        }

        public RefreshRateRange get(String s) {
            return mPackages.get(s);
        }

        public void remove(String s) {
            mPackages.remove(s);
        }
    }

    private final Mode mLowRefreshRateMode;
    private final ArraySet<String> mNonHighRefreshRatePackages = new ArraySet<>();
    private final PackageRefreshRate mNonHighRefreshRatePackages = new PackageRefreshRate();
    private final HighRefreshRateDenylist mHighRefreshRateDenylist;
    private final WindowManagerService mWmService;
    private float mMinSupportedRefreshRate;
    private float mMaxSupportedRefreshRate;

    /**
     * The following constants represent priority of the window. SF uses this information when
@@ -70,7 +96,12 @@ class RefreshRatePolicy {
        Mode mode = displayInfo.getDefaultMode();
        float[] refreshRates = displayInfo.getDefaultRefreshRates();
        float bestRefreshRate = mode.getRefreshRate();
        mMinSupportedRefreshRate = bestRefreshRate;
        mMaxSupportedRefreshRate = bestRefreshRate;
        for (int i = refreshRates.length - 1; i >= 0; i--) {
            mMinSupportedRefreshRate = Math.min(mMinSupportedRefreshRate, refreshRates[i]);
            mMaxSupportedRefreshRate = Math.max(mMaxSupportedRefreshRate, refreshRates[i]);

            if (refreshRates[i] >= 60f && refreshRates[i] < bestRefreshRate) {
                bestRefreshRate = refreshRates[i];
            }
@@ -78,12 +109,13 @@ class RefreshRatePolicy {
        return displayInfo.findDefaultModeByRefreshRate(bestRefreshRate);
    }

    void addNonHighRefreshRatePackage(String packageName) {
        mNonHighRefreshRatePackages.add(packageName);
    void addRefreshRateRangeForPackage(String packageName,
            float minRefreshRate, float maxRefreshRate) {
        mNonHighRefreshRatePackages.add(packageName, minRefreshRate, maxRefreshRate);
        mWmService.requestTraversal();
    }

    void removeNonHighRefreshRatePackage(String packageName) {
    void removeRefreshRateRangeForPackage(String packageName) {
        mNonHighRefreshRatePackages.remove(packageName);
        mWmService.requestTraversal();
    }
@@ -172,8 +204,9 @@ class RefreshRatePolicy {
        // If app is using Camera, we set both the min and max refresh rate to the camera's
        // preferred refresh rate to make sure we don't end up with a refresh rate lower
        // than the camera capture rate, which will lead to dropping camera frames.
        if (mNonHighRefreshRatePackages.contains(packageName)) {
            return mLowRefreshRateMode.getRefreshRate();
        RefreshRateRange range = mNonHighRefreshRatePackages.get(packageName);
        if (range != null) {
            return range.min;
        }

        return 0;
@@ -192,8 +225,9 @@ class RefreshRatePolicy {

        final String packageName = w.getOwningPackage();
        // If app is using Camera, force it to default (lower) refresh rate.
        if (mNonHighRefreshRatePackages.contains(packageName)) {
            return mLowRefreshRateMode.getRefreshRate();
        RefreshRateRange range = mNonHighRefreshRatePackages.get(packageName);
        if (range != null) {
            return range.max;
        }

        return 0;
+5 −4
Original line number Diff line number Diff line
@@ -725,17 +725,18 @@ public abstract class WindowManagerInternal {
    public abstract void hideIme(IBinder imeTargetWindowToken, int displayId);

    /**
     * Tell window manager about a package that should not be running with high refresh rate
     * setting until removeNonHighRefreshRatePackage is called for the same package.
     * Tell window manager about a package that should be running with a restricted range of
     * refresh rate setting until removeRefreshRateRangeForPackage is called for the same package.
     *
     * This must not be called again for the same package.
     */
    public abstract void addNonHighRefreshRatePackage(@NonNull String packageName);
    public abstract void addRefreshRateRangeForPackage(@NonNull String packageName,
            float minRefreshRate, float maxRefreshRate);

    /**
     * Tell window manager to stop constraining refresh rate for the given package.
     */
    public abstract void removeNonHighRefreshRatePackage(@NonNull String packageName);
    public abstract void removeRefreshRateRangeForPackage(@NonNull String packageName);

    /**
     * Checks if the device supports touch or faketouch.
+6 −4
Original line number Diff line number Diff line
@@ -7969,18 +7969,20 @@ public class WindowManagerService extends IWindowManager.Stub
        }

        @Override
        public void addNonHighRefreshRatePackage(@NonNull String packageName) {
        public void addRefreshRateRangeForPackage(@NonNull String packageName,
                float minRefreshRate, float maxRefreshRate) {
            synchronized (mGlobalLock) {
                mRoot.forAllDisplays(dc -> dc.getDisplayPolicy().getRefreshRatePolicy()
                        .addNonHighRefreshRatePackage(packageName));
                        .addRefreshRateRangeForPackage(
                                packageName, minRefreshRate, maxRefreshRate));
            }
        }

        @Override
        public void removeNonHighRefreshRatePackage(@NonNull String packageName) {
        public void removeRefreshRateRangeForPackage(@NonNull String packageName) {
            synchronized (mGlobalLock) {
                mRoot.forAllDisplays(dc -> dc.getDisplayPolicy().getRefreshRatePolicy()
                        .removeNonHighRefreshRatePackage(packageName));
                        .removeRefreshRateRangeForPackage(packageName));
            }
        }

+57 −5
Original line number Diff line number Diff line
@@ -101,14 +101,63 @@ public class RefreshRatePolicyTest extends WindowTestsBase {
        assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
        assertEquals(0, mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
        assertEquals(0, mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
        mPolicy.addNonHighRefreshRatePackage("com.android.test");
        mPolicy.addRefreshRateRangeForPackage("com.android.test",
                LOW_REFRESH_RATE, LOW_REFRESH_RATE);
        assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
        assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
        assertEquals(LOW_REFRESH_RATE,
                mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
        assertEquals(LOW_REFRESH_RATE,
                mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
        mPolicy.removeNonHighRefreshRatePackage("com.android.test");
        mPolicy.removeRefreshRateRangeForPackage("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 testCameraRange() {
        final WindowState cameraUsingWindow = createWindow("cameraUsingWindow");
        cameraUsingWindow.mAttrs.packageName = "com.android.test";
        parcelLayoutParams(cameraUsingWindow);
        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);
        mPolicy.addRefreshRateRangeForPackage("com.android.test",
                LOW_REFRESH_RATE, MID_REFRESH_RATE);
        assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
        assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
        assertEquals(LOW_REFRESH_RATE,
                mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
        assertEquals(MID_REFRESH_RATE,
                mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
        mPolicy.removeRefreshRateRangeForPackage("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 testCameraRange_OutOfRange() {
        final WindowState cameraUsingWindow = createWindow("cameraUsingWindow");
        cameraUsingWindow.mAttrs.packageName = "com.android.test";
        parcelLayoutParams(cameraUsingWindow);
        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);
        mPolicy.addRefreshRateRangeForPackage("com.android.test",
                LOW_REFRESH_RATE - 10, HI_REFRESH_RATE + 10);
        assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
        assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
        assertEquals(LOW_REFRESH_RATE,
                mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
        assertEquals(HI_REFRESH_RATE,
                mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
        mPolicy.removeRefreshRateRangeForPackage("com.android.test");
        assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
        assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
        assertEquals(0, mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
@@ -162,7 +211,8 @@ public class RefreshRatePolicyTest extends WindowTestsBase {
        overrideWindow.mAttrs.packageName = "com.android.test";
        overrideWindow.mAttrs.preferredDisplayModeId = HI_MODE_ID;
        parcelLayoutParams(overrideWindow);
        mPolicy.addNonHighRefreshRatePackage("com.android.test");
        mPolicy.addRefreshRateRangeForPackage("com.android.test",
                LOW_REFRESH_RATE, LOW_REFRESH_RATE);
        assertEquals(HI_MODE_ID, mPolicy.getPreferredModeId(overrideWindow));
        assertEquals(HI_REFRESH_RATE,
                mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE);
@@ -178,7 +228,8 @@ public class RefreshRatePolicyTest extends WindowTestsBase {
        overrideWindow.mAttrs.packageName = "com.android.test";
        overrideWindow.mAttrs.preferredRefreshRate = HI_REFRESH_RATE;
        parcelLayoutParams(overrideWindow);
        mPolicy.addNonHighRefreshRatePackage("com.android.test");
        mPolicy.addRefreshRateRangeForPackage("com.android.test",
                LOW_REFRESH_RATE, LOW_REFRESH_RATE);
        assertEquals(0, mPolicy.getPreferredModeId(overrideWindow));
        assertEquals(HI_REFRESH_RATE,
                mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE);
@@ -257,7 +308,8 @@ public class RefreshRatePolicyTest extends WindowTestsBase {
        cameraUsingWindow.mAttrs.packageName = "com.android.test";
        parcelLayoutParams(cameraUsingWindow);

        mPolicy.addNonHighRefreshRatePackage("com.android.test");
        mPolicy.addRefreshRateRangeForPackage("com.android.test",
                LOW_REFRESH_RATE, LOW_REFRESH_RATE);
        assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
        assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
        assertEquals(LOW_REFRESH_RATE,