Loading core/java/android/hardware/display/DisplayManager.java +9 −0 Original line number Diff line number Diff line Loading @@ -1762,6 +1762,15 @@ public final class DisplayManager { * 123,1,critical,0.8,default;123,1,moderate,0.6,id_2;456,2,moderate,0.9,critical,0.7 */ String KEY_BRIGHTNESS_THROTTLING_DATA = "brightness_throttling_data"; /** * 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"; } /** Loading services/core/java/com/android/server/display/feature/DeviceConfigParameterProvider.java 0 → 100644 +50 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.display.feature; import android.hardware.display.DisplayManager; import android.provider.DeviceConfig; import android.provider.DeviceConfigInterface; import java.util.concurrent.Executor; /** * Helper class to access all DeviceConfig features for display_manager namespace * **/ public class DeviceConfigParameterProvider { private static final String TAG = "DisplayFeatureProvider"; private final DeviceConfigInterface mDeviceConfig; public DeviceConfigParameterProvider(DeviceConfigInterface deviceConfig) { mDeviceConfig = deviceConfig; } public boolean isDisableScreenWakeLocksWhileCachedFeatureEnabled() { return mDeviceConfig.getBoolean(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, DisplayManager.DeviceConfig.KEY_DISABLE_SCREEN_WAKE_LOCKS_WHILE_CACHED, true); } /** add property change listener to DeviceConfig */ public void addOnPropertiesChangedListener(Executor executor, DeviceConfig.OnPropertiesChangedListener listener) { mDeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, executor, listener); } } services/core/java/com/android/server/power/PowerManagerService.java +46 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -1065,6 +1070,10 @@ public final class PowerManagerService extends SystemService } }; } DeviceConfigParameterProvider createDeviceConfigParameterProvider() { return new DeviceConfigParameterProvider(DeviceConfigInterface.REAL); } } /** Interface for checking an app op permission */ Loading Loading @@ -1161,6 +1170,7 @@ public final class PowerManagerService extends SystemService mInjector.createInattentiveSleepWarningController(); mPermissionCheckerWrapper = mInjector.createPermissionCheckerWrapper(); mPowerPropertiesWrapper = mInjector.createPowerPropertiesWrapper(); mDeviceConfigProvider = mInjector.createDeviceConfigParameterProvider(); mPowerGroupWakefulnessChangeListener = new PowerGroupWakefulnessChangeListener(); Loading Loading @@ -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( Loading Loading @@ -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, Loading Loading @@ -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: Loading Loading @@ -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) { Loading Loading @@ -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; } Loading services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java +203 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -340,6 +345,11 @@ public class PowerManagerServiceTest { PowerManagerService.PowerPropertiesWrapper createPowerPropertiesWrapper() { return mPowerPropertiesWrapper; } @Override DeviceConfigParameterProvider createDeviceConfigParameterProvider() { return mDeviceParameterProvider; } }); return mService; } Loading Loading @@ -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); } } Loading
core/java/android/hardware/display/DisplayManager.java +9 −0 Original line number Diff line number Diff line Loading @@ -1762,6 +1762,15 @@ public final class DisplayManager { * 123,1,critical,0.8,default;123,1,moderate,0.6,id_2;456,2,moderate,0.9,critical,0.7 */ String KEY_BRIGHTNESS_THROTTLING_DATA = "brightness_throttling_data"; /** * 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"; } /** Loading
services/core/java/com/android/server/display/feature/DeviceConfigParameterProvider.java 0 → 100644 +50 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.display.feature; import android.hardware.display.DisplayManager; import android.provider.DeviceConfig; import android.provider.DeviceConfigInterface; import java.util.concurrent.Executor; /** * Helper class to access all DeviceConfig features for display_manager namespace * **/ public class DeviceConfigParameterProvider { private static final String TAG = "DisplayFeatureProvider"; private final DeviceConfigInterface mDeviceConfig; public DeviceConfigParameterProvider(DeviceConfigInterface deviceConfig) { mDeviceConfig = deviceConfig; } public boolean isDisableScreenWakeLocksWhileCachedFeatureEnabled() { return mDeviceConfig.getBoolean(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, DisplayManager.DeviceConfig.KEY_DISABLE_SCREEN_WAKE_LOCKS_WHILE_CACHED, true); } /** add property change listener to DeviceConfig */ public void addOnPropertiesChangedListener(Executor executor, DeviceConfig.OnPropertiesChangedListener listener) { mDeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, executor, listener); } }
services/core/java/com/android/server/power/PowerManagerService.java +46 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -1065,6 +1070,10 @@ public final class PowerManagerService extends SystemService } }; } DeviceConfigParameterProvider createDeviceConfigParameterProvider() { return new DeviceConfigParameterProvider(DeviceConfigInterface.REAL); } } /** Interface for checking an app op permission */ Loading Loading @@ -1161,6 +1170,7 @@ public final class PowerManagerService extends SystemService mInjector.createInattentiveSleepWarningController(); mPermissionCheckerWrapper = mInjector.createPermissionCheckerWrapper(); mPowerPropertiesWrapper = mInjector.createPowerPropertiesWrapper(); mDeviceConfigProvider = mInjector.createDeviceConfigParameterProvider(); mPowerGroupWakefulnessChangeListener = new PowerGroupWakefulnessChangeListener(); Loading Loading @@ -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( Loading Loading @@ -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, Loading Loading @@ -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: Loading Loading @@ -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) { Loading Loading @@ -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; } Loading
services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java +203 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -340,6 +345,11 @@ public class PowerManagerServiceTest { PowerManagerService.PowerPropertiesWrapper createPowerPropertiesWrapper() { return mPowerPropertiesWrapper; } @Override DeviceConfigParameterProvider createDeviceConfigParameterProvider() { return mDeviceParameterProvider; } }); return mService; } Loading Loading @@ -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); } }