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

Commit 2ddd9048 authored by Santos Cordon's avatar Santos Cordon Committed by Fiona Campbell
Browse files

Add thermal options for refresh rate blocking zones.

Bug: 294852396
Test: atest DisplayModeDirectorTest
Change-Id: Iad1d3b7786a019f68dea3d0820fe587cb36c8a1d
Merged-In: Iad1d3b7786a019f68dea3d0820fe587cb36c8a1d
parent 33b4225f
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -366,9 +366,10 @@ public class AutomaticBrightnessController {
    }

    /**
     * @return The current brightness recommendation calculated from the current conditions.
     * @param brightnessEvent Event object to populate with details about why the specific
     *                        brightness was chosen.
     * @param brightnessEvent Holds details about how the brightness is calculated.
     *
     * @return The current automatic brightness recommended value. Populates brightnessEvent
     *         parameters with details about how the brightness was calculated.
     */
    public float getAutomaticScreenBrightness(BrightnessEvent brightnessEvent) {
        if (brightnessEvent != null) {
+32 −1
Original line number Diff line number Diff line
@@ -184,6 +184,7 @@ import javax.xml.datatype.DatatypeConfigurationException;
 *        <defaultRefreshRateInHbmSunlight>75</defaultRefreshRateInHbmSunlight>
 *        <lowerBlockingZoneConfigs>
 *          <defaultRefreshRate>75</defaultRefreshRate>
 *          <refreshRateThermalThrottlingId>id_of_a_throttling_map</refreshRateThermalThrottlingId>
 *          <blockingZoneThreshold>
 *            <displayBrightnessPoint>
 *              <lux>50</lux>
@@ -722,6 +723,12 @@ public class DisplayDeviceConfig {
    private float[] mHighDisplayBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS;
    private float[] mHighAmbientBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS;

    /**
     * Thermal throttling maps for the low and high blocking zones.
     */
    private String mLowBlockingZoneThermalMapId = null;
    private String mHighBlockingZoneThermalMapId = null;

    private final HashMap<String, ThermalBrightnessThrottlingData>
            mThermalBrightnessThrottlingDataMapByThrottlingId = new HashMap<>();

@@ -1525,6 +1532,13 @@ public class DisplayDeviceConfig {
        return mLowAmbientBrightnessThresholds;
    }

    /**
     * @return The refresh rate thermal map for low blocking zone.
     */
    public SparseArray<SurfaceControl.RefreshRateRange> getLowBlockingZoneThermalMap() {
        return getThermalRefreshRateThrottlingData(mLowBlockingZoneThermalMapId);
    }

    /**
     * @return An array of high display brightness thresholds. This, in combination with high
     * ambient brightness thresholds help define buckets in which the refresh rate switching is not
@@ -1547,6 +1561,13 @@ public class DisplayDeviceConfig {
        return mHighAmbientBrightnessThresholds;
    }

    /**
     * @return The refresh rate thermal map for high blocking zone.
     */
    public SparseArray<SurfaceControl.RefreshRateRange> getHighBlockingZoneThermalMap() {
        return getThermalRefreshRateThrottlingData(mHighBlockingZoneThermalMapId);
    }

    /**
     * @return A mapping from screen off brightness sensor readings to lux values. This estimates
     * the ambient lux when the screen is off to determine the initial brightness
@@ -1664,6 +1685,8 @@ public class DisplayDeviceConfig {
                + ", mDefaultRefreshRateInHbmHdr= " + mDefaultRefreshRateInHbmHdr
                + ", mDefaultRefreshRateInHbmSunlight= " + mDefaultRefreshRateInHbmSunlight
                + ", mRefreshRateThrottlingMap= " + mRefreshRateThrottlingMap
                + ", mLowBlockingZoneThermalMapId= " + mLowBlockingZoneThermalMapId
                + ", mHighBlockingZoneThermalMapId= " + mHighBlockingZoneThermalMapId
                + "\n"
                + ", mLowDisplayBrightnessThresholds= "
                + Arrays.toString(mLowDisplayBrightnessThresholds)
@@ -2114,9 +2137,13 @@ public class DisplayDeviceConfig {
    }

    /**
     * Loads the refresh rate configurations pertaining to the upper blocking zones.
     * Loads the refresh rate configurations pertaining to the lower blocking zones.
     */
    private void loadLowerRefreshRateBlockingZones(BlockingZoneConfig lowerBlockingZoneConfig) {
        if (lowerBlockingZoneConfig != null) {
            mLowBlockingZoneThermalMapId =
                    lowerBlockingZoneConfig.getRefreshRateThermalThrottlingId();
        }
        loadLowerBlockingZoneDefaultRefreshRate(lowerBlockingZoneConfig);
        loadLowerBrightnessThresholds(lowerBlockingZoneConfig);
    }
@@ -2125,6 +2152,10 @@ public class DisplayDeviceConfig {
     * Loads the refresh rate configurations pertaining to the upper blocking zones.
     */
    private void loadHigherRefreshRateBlockingZones(BlockingZoneConfig upperBlockingZoneConfig) {
        if (upperBlockingZoneConfig != null) {
            mHighBlockingZoneThermalMapId =
                    upperBlockingZoneConfig.getRefreshRateThermalThrottlingId();
        }
        loadHigherBlockingZoneDefaultRefreshRate(upperBlockingZoneConfig);
        loadHigherBrightnessThresholds(upperBlockingZoneConfig);
    }
+72 −1
Original line number Diff line number Diff line
@@ -1540,6 +1540,21 @@ public class DisplayModeDirector {
        private final Injector mInjector;
        private final Handler mHandler;

        private final IThermalEventListener.Stub mThermalListener =
                new IThermalEventListener.Stub() {
                    @Override
                    public void notifyThrottling(Temperature temp) {
                        @Temperature.ThrottlingStatus int currentStatus = temp.getStatus();
                        synchronized (mLock) {
                            if (mThermalStatus != currentStatus) {
                                mThermalStatus = currentStatus;
                            }
                            onBrightnessChangedLocked();
                        }
                    }
                };
        private boolean mThermalRegistered;

        // Enable light sensor only when mShouldObserveAmbientLowChange is true or
        // mShouldObserveAmbientHighChange is true, screen is on, peak refresh rate
        // changeable and low power mode off. After initialization, these states will
@@ -1548,9 +1563,17 @@ public class DisplayModeDirector {
        private boolean mRefreshRateChangeable = false;
        private boolean mLowPowerModeEnabled = false;

        @Nullable
        private SparseArray<RefreshRateRange> mLowZoneRefreshRateForThermals;
        private int mRefreshRateInLowZone;

        @Nullable
        private SparseArray<RefreshRateRange> mHighZoneRefreshRateForThermals;
        private int mRefreshRateInHighZone;

        @GuardedBy("mLock")
        private @Temperature.ThrottlingStatus int mThermalStatus = Temperature.THROTTLING_NONE;

        BrightnessObserver(Context context, Handler handler, Injector injector) {
            mContext = context;
            mHandler = handler;
@@ -1649,6 +1672,8 @@ public class DisplayModeDirector {
                                R.integer.config_defaultRefreshRateInZone)
                        : displayDeviceConfig.getDefaultLowBlockingZoneRefreshRate();
            }
            mLowZoneRefreshRateForThermals = displayDeviceConfig == null ? null
                    : displayDeviceConfig.getLowBlockingZoneThermalMap();
            mRefreshRateInLowZone = refreshRateInLowZone;
        }

@@ -1668,6 +1693,8 @@ public class DisplayModeDirector {
                                R.integer.config_fixedRefreshRateInHighZone)
                        : displayDeviceConfig.getDefaultHighBlockingZoneRefreshRate();
            }
            mHighZoneRefreshRateForThermals = displayDeviceConfig == null ? null
                    : displayDeviceConfig.getHighBlockingZoneThermalMap();
            mRefreshRateInHighZone = refreshRateInHighZone;
        }

@@ -2117,6 +2144,15 @@ public class DisplayModeDirector {
            if (insideLowZone) {
                refreshRateVote =
                        Vote.forPhysicalRefreshRates(mRefreshRateInLowZone, mRefreshRateInLowZone);
                if (mLowZoneRefreshRateForThermals != null) {
                    RefreshRateRange range = SkinThermalStatusObserver
                            .findBestMatchingRefreshRateRange(mThermalStatus,
                                    mLowZoneRefreshRateForThermals);
                    if (range != null) {
                        refreshRateVote =
                                Vote.forPhysicalRefreshRates(range.min, range.max);
                    }
                }
                refreshRateSwitchingVote = Vote.forDisableRefreshRateSwitching();
            }

@@ -2126,6 +2162,15 @@ public class DisplayModeDirector {
                refreshRateVote =
                        Vote.forPhysicalRefreshRates(mRefreshRateInHighZone,
                                mRefreshRateInHighZone);
                if (mHighZoneRefreshRateForThermals != null) {
                    RefreshRateRange range = SkinThermalStatusObserver
                            .findBestMatchingRefreshRateRange(mThermalStatus,
                                    mHighZoneRefreshRateForThermals);
                    if (range != null) {
                        refreshRateVote =
                                Vote.forPhysicalRefreshRates(range.min, range.max);
                    }
                }
                refreshRateSwitchingVote = Vote.forDisableRefreshRateSwitching();
            }

@@ -2184,13 +2229,25 @@ public class DisplayModeDirector {
                        + mRefreshRateChangeable);
            }

            boolean registerForThermals = false;
            if ((mShouldObserveAmbientLowChange || mShouldObserveAmbientHighChange)
                     && isDeviceActive() && !mLowPowerModeEnabled && mRefreshRateChangeable) {
                registerLightSensor();

                registerForThermals = mLowZoneRefreshRateForThermals != null
                        || mHighZoneRefreshRateForThermals != null;
            } else {
                unregisterSensorListener();
            }

            if (registerForThermals && !mThermalRegistered) {
                mThermalRegistered = mInjector.registerThermalServiceListener(mThermalListener);
            } else if (!registerForThermals && mThermalRegistered) {
                mInjector.unregisterThermalServiceListener(mThermalListener);
                mThermalRegistered = false;
                synchronized (mLock) {
                    mThermalStatus = Temperature.THROTTLING_NONE; // reset
                }
            }
        }

        private void registerLightSensor() {
@@ -2823,6 +2880,7 @@ public class DisplayModeDirector {
        boolean isDozeState(Display d);

        boolean registerThermalServiceListener(IThermalEventListener listener);
        void unregisterThermalServiceListener(IThermalEventListener listener);

        boolean supportsFrameRateOverride();
    }
@@ -2917,6 +2975,19 @@ public class DisplayModeDirector {
            return true;
        }

        @Override
        public void unregisterThermalServiceListener(IThermalEventListener listener) {
            IThermalService thermalService = getThermalService();
            if (thermalService == null) {
                Slog.w(TAG, "Could not unregister thermal status. Service not available");
            }
            try {
                thermalService.unregisterThermalEventListener(listener);
            } catch (RemoteException e) {
                Slog.e(TAG, "Failed to unregister thermal status listener", e);
            }
        }

        @Override
        public boolean supportsFrameRateOverride() {
            return SurfaceFlingerProperties.enable_frame_rate_override().orElse(true);
+14 −14
Original line number Diff line number Diff line
@@ -64,6 +64,20 @@ final class SkinThermalStatusObserver extends IThermalEventListener.Stub impleme
        mHandler = handler;
    }

    @Nullable
    public static SurfaceControl.RefreshRateRange findBestMatchingRefreshRateRange(
            @Temperature.ThrottlingStatus int currentStatus,
            SparseArray<SurfaceControl.RefreshRateRange> throttlingMap) {
        SurfaceControl.RefreshRateRange foundRange = null;
        for (int status = currentStatus; status >= 0; status--) {
            foundRange = throttlingMap.get(status);
            if (foundRange != null) {
                break;
            }
        }
        return foundRange;
    }

    void observe() {
        // if failed to register thermal service listener, don't register display listener
        if (!mInjector.registerThermalServiceListener(this)) {
@@ -228,20 +242,6 @@ final class SkinThermalStatusObserver extends IThermalEventListener.Stub impleme
        }
    }

    @Nullable
    private SurfaceControl.RefreshRateRange findBestMatchingRefreshRateRange(
            @Temperature.ThrottlingStatus int currentStatus,
            SparseArray<SurfaceControl.RefreshRateRange> throttlingMap) {
        SurfaceControl.RefreshRateRange foundRange = null;
        for (int status = currentStatus; status >= 0; status--) {
            foundRange = throttlingMap.get(status);
            if (foundRange != null) {
                break;
            }
        }
        return foundRange;
    }

    private void fallbackReportThrottlingIfNeeded(int displayId,
            @Temperature.ThrottlingStatus int currentStatus) {
        Vote vote = null;
+4 −0
Original line number Diff line number Diff line
@@ -579,6 +579,10 @@
                    minOccurs="1" maxOccurs="1">
            <xs:annotation name="final"/>
        </xs:element>
        <xs:element type ="xs:string" name="refreshRateThermalThrottlingId">
            <xs:annotation name="nullable"/>
            <xs:annotation name="final"/>
        </xs:element>
        <xs:element name="blockingZoneThreshold" type="blockingZoneThreshold"
                    minOccurs="1" maxOccurs="1">
            <xs:annotation name="final"/>
Loading