Merge "Ensure dim changes are in same transaction; do not wait for token to change visibility" into udc-dev
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 76efce5..21e4ab1 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -1762,6 +1762,15 @@
* 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";
}
/**
diff --git a/services/core/java/com/android/server/display/feature/DeviceConfigParameterProvider.java b/services/core/java/com/android/server/display/feature/DeviceConfigParameterProvider.java
new file mode 100644
index 0000000..0310383
--- /dev/null
+++ b/services/core/java/com/android/server/display/feature/DeviceConfigParameterProvider.java
@@ -0,0 +1,50 @@
+/*
+ * 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);
+ }
+}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index a53b831..d82f7a5 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -92,6 +92,7 @@
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.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 @@
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 @@
}
};
}
+
+ DeviceConfigParameterProvider createDeviceConfigParameterProvider() {
+ return new DeviceConfigParameterProvider(DeviceConfigInterface.REAL);
+ }
}
/** Interface for checking an app op permission */
@@ -1161,6 +1170,7 @@
mInjector.createInattentiveSleepWarningController();
mPermissionCheckerWrapper = mInjector.createPermissionCheckerWrapper();
mPowerPropertiesWrapper = mInjector.createPowerPropertiesWrapper();
+ mDeviceConfigProvider = mInjector.createDeviceConfigParameterProvider();
mPowerGroupWakefulnessChangeListener = new PowerGroupWakefulnessChangeListener();
@@ -1346,6 +1356,14 @@
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 @@
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 @@
/** 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;
+ return WAKE_LOCK_CPU;
case PowerManager.FULL_WAKE_LOCK:
return WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
@@ -4151,7 +4175,7 @@
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 @@
}
}
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;
}
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 5c6164e..431d3a6 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -18,6 +18,8 @@
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.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.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 @@
@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 @@
PowerManagerService.PowerPropertiesWrapper createPowerPropertiesWrapper() {
return mPowerPropertiesWrapper;
}
+
+ @Override
+ DeviceConfigParameterProvider createDeviceConfigParameterProvider() {
+ return mDeviceParameterProvider;
+ }
});
return mService;
}
@@ -2680,4 +2690,197 @@
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);
+ }
}