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

Commit 5ea5d77a authored by Richard Chang's avatar Richard Chang
Browse files

ThermalManagerService: fix different system clock comparison

ThermalManagerService tried to compare
SystemClock.elapsedRealtime() and System.currentTimeMillis().
It may lead to more unnecessary update tasks.

Ref: https://developer.android.com/reference/android/os/SystemClock
Add testcase testTemperatureWatcherGetForecastUpdate

Bug: 203028173
Test: atest ThermalManagerServiceTest
Change-Id: Ic0c579cb124fd8d86bff9f6d9e21e33ca9d9f0ff
parent ef86923d
Loading
Loading
Loading
Loading
+6 −3
Original line number Original line Diff line number Diff line
@@ -1088,6 +1088,10 @@ public class ThermalManagerService extends SystemService {
        @GuardedBy("mSamples")
        @GuardedBy("mSamples")
        private long mLastForecastCallTimeMillis = 0;
        private long mLastForecastCallTimeMillis = 0;


        private static final int INACTIVITY_THRESHOLD_MILLIS = 10000;
        @VisibleForTesting
        long mInactivityThresholdMillis = INACTIVITY_THRESHOLD_MILLIS;

        void updateSevereThresholds() {
        void updateSevereThresholds() {
            synchronized (mSamples) {
            synchronized (mSamples) {
                List<TemperatureThreshold> thresholds =
                List<TemperatureThreshold> thresholds =
@@ -1107,13 +1111,12 @@ public class ThermalManagerService extends SystemService {
            }
            }
        }
        }


        private static final int INACTIVITY_THRESHOLD_MILLIS = 10000;
        private static final int RING_BUFFER_SIZE = 30;
        private static final int RING_BUFFER_SIZE = 30;


        private void updateTemperature() {
        private void updateTemperature() {
            synchronized (mSamples) {
            synchronized (mSamples) {
                if (SystemClock.elapsedRealtime() - mLastForecastCallTimeMillis
                if (SystemClock.elapsedRealtime() - mLastForecastCallTimeMillis
                        < INACTIVITY_THRESHOLD_MILLIS) {
                        < mInactivityThresholdMillis) {
                    // Trigger this again after a second as long as forecast has been called more
                    // Trigger this again after a second as long as forecast has been called more
                    // recently than the inactivity timeout
                    // recently than the inactivity timeout
                    mHandler.postDelayed(this::updateTemperature, 1000);
                    mHandler.postDelayed(this::updateTemperature, 1000);
@@ -1199,7 +1202,7 @@ public class ThermalManagerService extends SystemService {


        float getForecast(int forecastSeconds) {
        float getForecast(int forecastSeconds) {
            synchronized (mSamples) {
            synchronized (mSamples) {
                mLastForecastCallTimeMillis = System.currentTimeMillis();
                mLastForecastCallTimeMillis = SystemClock.elapsedRealtime();
                if (mSamples.isEmpty()) {
                if (mSamples.isEmpty()) {
                    updateTemperature();
                    updateTemperature();
                }
                }
+30 −0
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.power;
package com.android.server.power;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.any;
@@ -457,4 +458,33 @@ public class ThermalManagerServiceTest {
        watcher.mSevereThresholds.erase();
        watcher.mSevereThresholds.erase();
        assertTrue(Float.isNaN(watcher.getForecast(0)));
        assertTrue(Float.isNaN(watcher.getForecast(0)));
    }
    }

    @Test
    public void testTemperatureWatcherGetForecastUpdate() throws Exception {
        ThermalManagerService.TemperatureWatcher watcher = mService.mTemperatureWatcher;

        // Reduce the inactivity threshold to speed up testing
        watcher.mInactivityThresholdMillis = 2000;

        // Make sure mSamples is empty before updateTemperature
        assertTrue(isWatcherSamplesEmpty(watcher));

        // Call getForecast once to trigger updateTemperature
        watcher.getForecast(0);

        // After 1 second, the samples should be updated
        Thread.sleep(1000);
        assertFalse(isWatcherSamplesEmpty(watcher));

        // After mInactivityThresholdMillis, the samples should be cleared
        Thread.sleep(watcher.mInactivityThresholdMillis);
        assertTrue(isWatcherSamplesEmpty(watcher));
    }

    // Helper function to hold mSamples lock, avoid GuardedBy lint errors
    private boolean isWatcherSamplesEmpty(ThermalManagerService.TemperatureWatcher watcher) {
        synchronized (watcher.mSamples) {
            return watcher.mSamples.isEmpty();
        }
    }
}
}