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

Commit 929a1a87 authored by Philip Junker's avatar Philip Junker Committed by Android (Google) Code Review
Browse files

Merge "Disable screen wake locks for cached apps" into udc-qpr-dev

parents 23907da1 d4757797
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1780,6 +1780,15 @@ public final class DisplayManager {
         * @hide
         */
        String KEY_USE_NORMAL_BRIGHTNESS_MODE_CONTROLLER = "use_normal_brightness_mode_controller";

        /**
         * Key for disabling screen wake locks while apps are in cached state.
         * Read value via {@link android.provider.DeviceConfig#getBoolean(String, String, boolean)}
         * with {@link android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER} as the namespace.
         * @hide
         */
        String KEY_DISABLE_SCREEN_WAKE_LOCKS_WHILE_CACHED =
                "disable_screen_wake_locks_while_cached";
    }

    /**
+5 −0
Original line number Diff line number Diff line
@@ -60,6 +60,11 @@ public class DeviceConfigParameterProvider {
                DisplayManager.DeviceConfig.KEY_USE_NORMAL_BRIGHTNESS_MODE_CONTROLLER, false);
    }

    public boolean isDisableScreenWakeLocksWhileCachedFeatureEnabled() {
        return mDeviceConfig.getBoolean(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
                DisplayManager.DeviceConfig.KEY_DISABLE_SCREEN_WAKE_LOCKS_WHILE_CACHED, true);
    }

    // feature: smooth_display_feature
    // parameter: peak_refresh_rate_default
    public float getPeakRefreshRateDefault() {
+46 −6
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.WorkSource;
import android.os.WorkSource.WorkChain;
import android.provider.DeviceConfigInterface;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.service.dreams.DreamManagerInternal;
@@ -128,6 +129,7 @@ import com.android.server.UiThread;
import com.android.server.UserspaceRebootLogger;
import com.android.server.Watchdog;
import com.android.server.am.BatteryStatsService;
import com.android.server.display.feature.DeviceConfigParameterProvider;
import com.android.server.lights.LightsManager;
import com.android.server.lights.LogicalLight;
import com.android.server.policy.WindowManagerPolicy;
@@ -323,6 +325,9 @@ public final class PowerManagerService extends SystemService
    private final Injector mInjector;
    private final PermissionCheckerWrapper mPermissionCheckerWrapper;
    private final PowerPropertiesWrapper mPowerPropertiesWrapper;
    private final DeviceConfigParameterProvider mDeviceConfigProvider;

    private boolean mDisableScreenWakeLocksWhileCached;

    private LightsManager mLightsManager;
    private BatteryManagerInternal mBatteryManagerInternal;
@@ -1065,6 +1070,10 @@ public final class PowerManagerService extends SystemService
                }
            };
        }

        DeviceConfigParameterProvider createDeviceConfigParameterProvider() {
            return new DeviceConfigParameterProvider(DeviceConfigInterface.REAL);
        }
    }

    /** Interface for checking an app op permission */
@@ -1161,6 +1170,7 @@ public final class PowerManagerService extends SystemService
                mInjector.createInattentiveSleepWarningController();
        mPermissionCheckerWrapper = mInjector.createPermissionCheckerWrapper();
        mPowerPropertiesWrapper = mInjector.createPowerPropertiesWrapper();
        mDeviceConfigProvider = mInjector.createDeviceConfigParameterProvider();

        mPowerGroupWakefulnessChangeListener = new PowerGroupWakefulnessChangeListener();

@@ -1346,6 +1356,14 @@ public final class PowerManagerService extends SystemService

            mLightsManager = getLocalService(LightsManager.class);
            mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);
            updateDeviceConfigLocked();
            mDeviceConfigProvider.addOnPropertiesChangedListener(BackgroundThread.getExecutor(),
                    properties -> {
                        synchronized (mLock) {
                            updateDeviceConfigLocked();
                            updateWakeLockDisabledStatesLocked();
                        }
                    });

            // Initialize display power management.
            mDisplayManagerInternal.initPowerManagement(
@@ -1545,6 +1563,12 @@ public final class PowerManagerService extends SystemService
        updatePowerStateLocked();
    }

    @GuardedBy("mLock")
    private void updateDeviceConfigLocked() {
        mDisableScreenWakeLocksWhileCached = mDeviceConfigProvider
                .isDisableScreenWakeLocksWhileCachedFeatureEnabled();
    }

    @RequiresPermission(value = android.Manifest.permission.TURN_SCREEN_ON, conditional = true)
    private void acquireWakeLockInternal(IBinder lock, int displayId, int flags, String tag,
            String packageName, WorkSource ws, String historyTag, int uid, int pid,
@@ -2760,13 +2784,13 @@ public final class PowerManagerService extends SystemService
    /** Get wake lock summary flags that correspond to the given wake lock. */
    @SuppressWarnings("deprecation")
    private int getWakeLockSummaryFlags(WakeLock wakeLock) {
        if (wakeLock.mDisabled) {
            // We only respect this if the wake lock is not disabled.
            return 0;
        }
        switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
            case PowerManager.PARTIAL_WAKE_LOCK:
                if (!wakeLock.mDisabled) {
                    // We only respect this if the wake lock is not disabled.
                return WAKE_LOCK_CPU;
                }
                break;
            case PowerManager.FULL_WAKE_LOCK:
                return WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
            case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
@@ -4151,7 +4175,7 @@ public final class PowerManagerService extends SystemService
        for (int i = 0; i < numWakeLocks; i++) {
            final WakeLock wakeLock = mWakeLocks.get(i);
            if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
                    == PowerManager.PARTIAL_WAKE_LOCK) {
                    == PowerManager.PARTIAL_WAKE_LOCK || isScreenLock(wakeLock)) {
                if (setWakeLockDisabledStateLocked(wakeLock)) {
                    changed = true;
                    if (wakeLock.mDisabled) {
@@ -4205,6 +4229,22 @@ public final class PowerManagerService extends SystemService
                }
            }
            return wakeLock.setDisabled(disabled);
        } else if (mDisableScreenWakeLocksWhileCached && isScreenLock(wakeLock)) {
            boolean disabled = false;
            final int appid = UserHandle.getAppId(wakeLock.mOwnerUid);
            final UidState state = wakeLock.mUidState;
            // Cached inactive processes are never allowed to hold wake locks.
            if (mConstants.NO_CACHED_WAKE_LOCKS
                    && appid >= Process.FIRST_APPLICATION_UID
                    && !state.mActive
                    && state.mProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
                    && state.mProcState >= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
                if (DEBUG_SPEW) {
                    Slog.d(TAG, "disabling full wakelock " + wakeLock);
                }
                disabled = true;
            }
            return wakeLock.setDisabled(disabled);
        }
        return false;
    }
+203 −0
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.server.power;

import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_RECEIVER;
import static android.app.ActivityManager.PROCESS_STATE_TOP_SLEEPING;
import static android.os.PowerManager.USER_ACTIVITY_EVENT_BUTTON;
import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
@@ -78,6 +80,7 @@ import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
import android.os.UserHandle;
import android.os.test.TestLooper;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.service.dreams.DreamManagerInternal;
import android.sysprop.PowerProperties;
@@ -91,6 +94,7 @@ import com.android.internal.app.IBatteryStats;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.display.feature.DeviceConfigParameterProvider;
import com.android.server.lights.LightsManager;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.power.PowerManagerService.BatteryReceiver;
@@ -159,6 +163,7 @@ public class PowerManagerServiceTest {
    @Mock private InattentiveSleepWarningController mInattentiveSleepWarningControllerMock;
    @Mock private PowerManagerService.PermissionCheckerWrapper mPermissionCheckerWrapperMock;
    @Mock private PowerManagerService.PowerPropertiesWrapper mPowerPropertiesWrapper;
    @Mock private DeviceConfigParameterProvider mDeviceParameterProvider;

    @Rule public TestRule compatChangeRule = new PlatformCompatChangeRule();

@@ -340,6 +345,11 @@ public class PowerManagerServiceTest {
            PowerManagerService.PowerPropertiesWrapper createPowerPropertiesWrapper() {
                return mPowerPropertiesWrapper;
            }

            @Override
            DeviceConfigParameterProvider createDeviceConfigParameterProvider() {
                return mDeviceParameterProvider;
            }
        });
        return mService;
    }
@@ -2680,4 +2690,197 @@ public class PowerManagerServiceTest {
        verify(mNotifierMock, never()).onUserActivity(anyInt(),  anyInt(), anyInt());
    }

    @Test
    public void testFeatureEnabledProcStateUncachedToCached_fullWakeLockDisabled() {
        doReturn(true).when(mDeviceParameterProvider)
                .isDisableScreenWakeLocksWhileCachedFeatureEnabled();
        createService();
        startSystem();
        WakeLock wakeLock = acquireWakeLock("fullWakeLock", PowerManager.FULL_WAKE_LOCK);
        setUncachedUidProcState(wakeLock.mOwnerUid);

        setCachedUidProcState(wakeLock.mOwnerUid);
        assertThat(wakeLock.mDisabled).isTrue();
    }

    @Test
    public void testFeatureDisabledProcStateUncachedToCached_fullWakeLockEnabled() {
        doReturn(false).when(mDeviceParameterProvider)
                .isDisableScreenWakeLocksWhileCachedFeatureEnabled();
        createService();
        startSystem();
        WakeLock wakeLock = acquireWakeLock("fullWakeLock", PowerManager.FULL_WAKE_LOCK);
        setUncachedUidProcState(wakeLock.mOwnerUid);

        setCachedUidProcState(wakeLock.mOwnerUid);
        assertThat(wakeLock.mDisabled).isFalse();
    }

    @Test
    public void testFeatureEnabledProcStateUncachedToCached_screenBrightWakeLockDisabled() {
        doReturn(true).when(mDeviceParameterProvider)
                .isDisableScreenWakeLocksWhileCachedFeatureEnabled();
        createService();
        startSystem();
        WakeLock wakeLock = acquireWakeLock("screenBrightWakeLock",
                PowerManager.SCREEN_BRIGHT_WAKE_LOCK);
        setUncachedUidProcState(wakeLock.mOwnerUid);

        setCachedUidProcState(wakeLock.mOwnerUid);
        assertThat(wakeLock.mDisabled).isTrue();
    }

    @Test
    public void testFeatureDisabledProcStateUncachedToCached_screenBrightWakeLockEnabled() {
        doReturn(false).when(mDeviceParameterProvider)
                .isDisableScreenWakeLocksWhileCachedFeatureEnabled();
        createService();
        startSystem();
        WakeLock wakeLock = acquireWakeLock("screenBrightWakeLock",
                PowerManager.SCREEN_BRIGHT_WAKE_LOCK);
        setUncachedUidProcState(wakeLock.mOwnerUid);

        setCachedUidProcState(wakeLock.mOwnerUid);
        assertThat(wakeLock.mDisabled).isFalse();
    }

    @Test
    public void testFeatureEnabledProcStateUncachedToCached_screenDimWakeLockDisabled() {
        doReturn(true).when(mDeviceParameterProvider)
                .isDisableScreenWakeLocksWhileCachedFeatureEnabled();
        createService();
        startSystem();
        WakeLock wakeLock = acquireWakeLock("screenDimWakeLock",
                PowerManager.SCREEN_DIM_WAKE_LOCK);
        setUncachedUidProcState(wakeLock.mOwnerUid);

        setCachedUidProcState(wakeLock.mOwnerUid);
        assertThat(wakeLock.mDisabled).isTrue();
    }

    @Test
    public void testFeatureDisabledProcStateUncachedToCached_screenDimWakeLockEnabled() {
        doReturn(false).when(mDeviceParameterProvider)
                .isDisableScreenWakeLocksWhileCachedFeatureEnabled();
        createService();
        startSystem();
        WakeLock wakeLock = acquireWakeLock("screenDimWakeLock",
                PowerManager.SCREEN_DIM_WAKE_LOCK);
        setUncachedUidProcState(wakeLock.mOwnerUid);

        setCachedUidProcState(wakeLock.mOwnerUid);
        assertThat(wakeLock.mDisabled).isFalse();
    }

    @Test
    public void testFeatureEnabledProcStateCachedToUncached_fullWakeLockEnabled() {
        doReturn(true).when(mDeviceParameterProvider)
                .isDisableScreenWakeLocksWhileCachedFeatureEnabled();
        createService();
        startSystem();
        WakeLock wakeLock = acquireWakeLock("fullWakeLock", PowerManager.FULL_WAKE_LOCK);
        setCachedUidProcState(wakeLock.mOwnerUid);

        setUncachedUidProcState(wakeLock.mOwnerUid);
        assertThat(wakeLock.mDisabled).isFalse();
    }

    @Test
    public void testFeatureDisabledProcStateCachedToUncached_fullWakeLockEnabled() {
        doReturn(false).when(mDeviceParameterProvider)
                .isDisableScreenWakeLocksWhileCachedFeatureEnabled();
        createService();
        startSystem();
        WakeLock wakeLock = acquireWakeLock("fullWakeLock", PowerManager.FULL_WAKE_LOCK);
        setCachedUidProcState(wakeLock.mOwnerUid);

        setUncachedUidProcState(wakeLock.mOwnerUid);
        assertThat(wakeLock.mDisabled).isFalse();
    }

    @Test
    public void testFeatureEnabledProcStateCachedToUncached_screenBrightWakeLockEnabled() {
        doReturn(true).when(mDeviceParameterProvider)
                .isDisableScreenWakeLocksWhileCachedFeatureEnabled();
        createService();
        startSystem();
        WakeLock wakeLock = acquireWakeLock("screenBrightWakeLock",
                PowerManager.SCREEN_BRIGHT_WAKE_LOCK);
        setCachedUidProcState(wakeLock.mOwnerUid);

        setUncachedUidProcState(wakeLock.mOwnerUid);
        assertThat(wakeLock.mDisabled).isFalse();
    }

    @Test
    public void testFeatureDisabledProcStateCachedToUncached_screenBrightWakeLockEnabled() {
        doReturn(false).when(mDeviceParameterProvider)
                .isDisableScreenWakeLocksWhileCachedFeatureEnabled();
        createService();
        startSystem();
        WakeLock wakeLock = acquireWakeLock("screenBrightWakeLock",
                PowerManager.SCREEN_BRIGHT_WAKE_LOCK);
        setCachedUidProcState(wakeLock.mOwnerUid);

        setUncachedUidProcState(wakeLock.mOwnerUid);
        assertThat(wakeLock.mDisabled).isFalse();
    }

    @Test
    public void testFeatureEnabledProcStateCachedToUncached_screenDimWakeLockEnabled() {
        doReturn(true).when(mDeviceParameterProvider)
                .isDisableScreenWakeLocksWhileCachedFeatureEnabled();
        createService();
        startSystem();
        WakeLock wakeLock = acquireWakeLock("screenDimWakeLock",
                PowerManager.SCREEN_DIM_WAKE_LOCK);
        setCachedUidProcState(wakeLock.mOwnerUid);

        setUncachedUidProcState(wakeLock.mOwnerUid);
        assertThat(wakeLock.mDisabled).isFalse();
    }

    @Test
    public void testFeatureDisabledProcStateCachedToUncached_screenDimWakeLockEnabled() {
        doReturn(false).when(mDeviceParameterProvider)
                .isDisableScreenWakeLocksWhileCachedFeatureEnabled();
        createService();
        startSystem();
        WakeLock wakeLock = acquireWakeLock("screenDimWakeLock",
                PowerManager.SCREEN_DIM_WAKE_LOCK);
        setCachedUidProcState(wakeLock.mOwnerUid);

        setUncachedUidProcState(wakeLock.mOwnerUid);
        assertThat(wakeLock.mDisabled).isFalse();
    }

    @Test
    public void testFeatureDynamicallyDisabledProcStateUncachedToCached_fullWakeLockEnabled() {
        doReturn(true).when(mDeviceParameterProvider)
                .isDisableScreenWakeLocksWhileCachedFeatureEnabled();
        ArgumentCaptor<DeviceConfig.OnPropertiesChangedListener> listenerCaptor =
                ArgumentCaptor.forClass(DeviceConfig.OnPropertiesChangedListener.class);
        createService();
        startSystem();
        verify(mDeviceParameterProvider, times(1))
                .addOnPropertiesChangedListener(any(), listenerCaptor.capture());
        WakeLock wakeLock = acquireWakeLock("fullWakeLock", PowerManager.FULL_WAKE_LOCK);
        setUncachedUidProcState(wakeLock.mOwnerUid);
        // dynamically disable the feature
        doReturn(false).when(mDeviceParameterProvider)
                .isDisableScreenWakeLocksWhileCachedFeatureEnabled();
        listenerCaptor.getValue().onPropertiesChanged(
                new DeviceConfig.Properties("ignored_namespace", null));

        setUncachedUidProcState(wakeLock.mOwnerUid);
        assertThat(wakeLock.mDisabled).isFalse();
    }

    private void setCachedUidProcState(int uid) {
        mService.updateUidProcStateInternal(uid, PROCESS_STATE_TOP_SLEEPING);
    }

    private void setUncachedUidProcState(int uid) {
        mService.updateUidProcStateInternal(uid, PROCESS_STATE_RECEIVER);
    }
}