Merge "Update PowerManager to make ambient display suppression apply to dreams." into tm-qpr-dev

This commit is contained in:
Lucas Silva
2022-10-18 00:51:59 +00:00
committed by Android (Google) Code Review
5 changed files with 156 additions and 8 deletions

View File

@@ -2479,6 +2479,8 @@
<integer name="config_attentionMaximumExtension">900000</integer> <!-- 15 minutes. -->
<!-- Is the system user the only user allowed to dream. -->
<bool name="config_dreamsOnlyEnabledForSystemUser">false</bool>
<!-- Whether dreams are disabled when ambient mode is suppressed. -->
<bool name="config_dreamsDisabledByAmbientModeSuppressionConfig">false</bool>
<!-- Whether to dismiss the active dream when an activity is started. Doesn't apply to
assistant activities (ACTIVITY_TYPE_ASSISTANT) -->

View File

@@ -2235,6 +2235,7 @@
<java-symbol type="integer" name="config_dreamsBatteryLevelMinimumWhenNotPowered" />
<java-symbol type="integer" name="config_dreamsBatteryLevelDrainCutoff" />
<java-symbol type="string" name="config_dreamsDefaultComponent" />
<java-symbol type="bool" name="config_dreamsDisabledByAmbientModeSuppressionConfig" />
<java-symbol type="bool" name="config_dreamsOnlyEnabledForSystemUser" />
<java-symbol type="array" name="config_supportedDreamComplications" />
<java-symbol type="array" name="config_disabledDreamComponents" />

View File

@@ -40,13 +40,24 @@ import java.util.Set;
public class AmbientDisplaySuppressionController {
private static final String TAG = "AmbientDisplaySuppressionController";
private final Context mContext;
private final Set<Pair<String, Integer>> mSuppressionTokens;
private final AmbientDisplaySuppressionChangedCallback mCallback;
private IStatusBarService mStatusBarService;
AmbientDisplaySuppressionController(Context context) {
mContext = requireNonNull(context);
/** Interface to get a list of available logical devices. */
interface AmbientDisplaySuppressionChangedCallback {
/**
* Called when the suppression state changes.
*
* @param isSuppressed Whether ambient is suppressed.
*/
void onSuppressionChanged(boolean isSuppressed);
}
AmbientDisplaySuppressionController(
@NonNull AmbientDisplaySuppressionChangedCallback callback) {
mSuppressionTokens = Collections.synchronizedSet(new ArraySet<>());
mCallback = requireNonNull(callback);
}
/**
@@ -58,6 +69,7 @@ public class AmbientDisplaySuppressionController {
*/
public void suppress(@NonNull String token, int callingUid, boolean suppress) {
Pair<String, Integer> suppressionToken = Pair.create(requireNonNull(token), callingUid);
final boolean wasSuppressed = isSuppressed();
if (suppress) {
mSuppressionTokens.add(suppressionToken);
@@ -65,9 +77,14 @@ public class AmbientDisplaySuppressionController {
mSuppressionTokens.remove(suppressionToken);
}
final boolean isSuppressed = isSuppressed();
if (isSuppressed != wasSuppressed) {
mCallback.onSuppressionChanged(isSuppressed);
}
try {
synchronized (mSuppressionTokens) {
getStatusBar().suppressAmbientDisplay(isSuppressed());
getStatusBar().suppressAmbientDisplay(isSuppressed);
}
} catch (RemoteException e) {
Slog.e(TAG, "Failed to suppress ambient display", e);

View File

@@ -127,6 +127,7 @@ import com.android.server.am.BatteryStatsService;
import com.android.server.lights.LightsManager;
import com.android.server.lights.LogicalLight;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.power.AmbientDisplaySuppressionController.AmbientDisplaySuppressionChangedCallback;
import com.android.server.power.batterysaver.BatterySaverController;
import com.android.server.power.batterysaver.BatterySaverPolicy;
import com.android.server.power.batterysaver.BatterySaverStateMachine;
@@ -507,6 +508,9 @@ public final class PowerManagerService extends SystemService
// effectively and terminate the dream. Use -1 to disable this safety feature.
private int mDreamsBatteryLevelDrainCutoffConfig;
// Whether dreams should be disabled when ambient mode is suppressed.
private boolean mDreamsDisabledByAmbientModeSuppressionConfig;
// True if dreams are enabled by the user.
private boolean mDreamsEnabledSetting;
@@ -964,8 +968,8 @@ public final class PowerManagerService extends SystemService
}
AmbientDisplaySuppressionController createAmbientDisplaySuppressionController(
Context context) {
return new AmbientDisplaySuppressionController(context);
@NonNull AmbientDisplaySuppressionChangedCallback callback) {
return new AmbientDisplaySuppressionController(callback);
}
InattentiveSleepWarningController createInattentiveSleepWarningController() {
@@ -1044,7 +1048,8 @@ public final class PowerManagerService extends SystemService
mConstants = new Constants(mHandler);
mAmbientDisplayConfiguration = mInjector.createAmbientDisplayConfiguration(context);
mAmbientDisplaySuppressionController =
mInjector.createAmbientDisplaySuppressionController(context);
mInjector.createAmbientDisplaySuppressionController(
mAmbientSuppressionChangedCallback);
mAttentionDetector = new AttentionDetector(this::onUserAttention, mLock);
mFaceDownDetector = new FaceDownDetector(this::onFlip);
mScreenUndimDetector = new ScreenUndimDetector();
@@ -1403,6 +1408,8 @@ public final class PowerManagerService extends SystemService
com.android.internal.R.integer.config_dreamsBatteryLevelMinimumWhenNotPowered);
mDreamsBatteryLevelDrainCutoffConfig = resources.getInteger(
com.android.internal.R.integer.config_dreamsBatteryLevelDrainCutoff);
mDreamsDisabledByAmbientModeSuppressionConfig = resources.getBoolean(
com.android.internal.R.bool.config_dreamsDisabledByAmbientModeSuppressionConfig);
mDozeAfterScreenOff = resources.getBoolean(
com.android.internal.R.bool.config_dozeAfterScreenOffByDefault);
mMinimumScreenOffTimeoutConfig = resources.getInteger(
@@ -3329,7 +3336,7 @@ public final class PowerManagerService extends SystemService
}
// Doze has ended or will be stopped. Update the power state.
sleepPowerGroupLocked(powerGroup, now, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT,
sleepPowerGroupLocked(powerGroup, now, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT,
Process.SYSTEM_UID);
}
}
@@ -3340,12 +3347,32 @@ public final class PowerManagerService extends SystemService
}
}
@GuardedBy("mLock")
private void onDreamSuppressionChangedLocked(final boolean isSuppressed) {
if (!mDreamsDisabledByAmbientModeSuppressionConfig) {
return;
}
if (!isSuppressed && mIsPowered && mDreamsSupportedConfig && mDreamsEnabledSetting
&& shouldNapAtBedTimeLocked() && isItBedTimeYetLocked(
mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP))) {
napInternal(SystemClock.uptimeMillis(), Process.SYSTEM_UID, /* allowWake= */ true);
} else if (isSuppressed) {
mDirty |= DIRTY_SETTINGS;
updatePowerStateLocked();
}
}
/**
* Returns true if the {@code groupId} is allowed to dream in its current state.
*/
@GuardedBy("mLock")
private boolean canDreamLocked(final PowerGroup powerGroup) {
final boolean dreamsSuppressed = mDreamsDisabledByAmbientModeSuppressionConfig
&& mAmbientDisplaySuppressionController.isSuppressed();
if (!mBootCompleted
|| dreamsSuppressed
|| getGlobalWakefulnessLocked() != WAKEFULNESS_DREAMING
|| !mDreamsSupportedConfig
|| !mDreamsEnabledSetting
@@ -5037,6 +5064,16 @@ public final class PowerManagerService extends SystemService
}
};
private final AmbientDisplaySuppressionChangedCallback mAmbientSuppressionChangedCallback =
new AmbientDisplaySuppressionChangedCallback() {
@Override
public void onSuppressionChanged(boolean isSuppressed) {
synchronized (mLock) {
onDreamSuppressionChangedLocked(isSuppressed);
}
}
};
/**
* Callback for asynchronous operations performed by the power manager.
*/

View File

@@ -393,6 +393,12 @@ public class PowerManagerServiceTest {
.thenReturn(minimumScreenOffTimeoutConfigMillis);
}
private void setDreamsDisabledByAmbientModeSuppressionConfig(boolean disable) {
when(mResourcesSpy.getBoolean(
com.android.internal.R.bool.config_dreamsDisabledByAmbientModeSuppressionConfig))
.thenReturn(disable);
}
private void advanceTime(long timeMs) {
mClock.fastForward(timeMs);
mTestLooper.dispatchAll();
@@ -790,6 +796,91 @@ public class PowerManagerServiceTest {
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
}
@SuppressWarnings("GuardedBy")
@Test
public void testAmbientSuppression_disablesDreamingAndWakesDevice() {
Settings.Secure.putInt(mContextSpy.getContentResolver(),
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1);
Settings.Secure.putInt(mContextSpy.getContentResolver(),
Settings.Secure.SCREENSAVER_ENABLED, 1);
setDreamsDisabledByAmbientModeSuppressionConfig(true);
setMinimumScreenOffTimeoutConfig(10000);
createService();
startSystem();
doAnswer(inv -> {
when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
return null;
}).when(mDreamManagerInternalMock).startDream(anyBoolean(), anyString());
setPluggedIn(true);
// Allow asynchronous sandman calls to execute.
advanceTime(10000);
forceDream();
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
mService.getBinderServiceInstance().suppressAmbientDisplay("test", true);
advanceTime(50);
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
}
@SuppressWarnings("GuardedBy")
@Test
public void testAmbientSuppressionDisabled_shouldNotWakeDevice() {
Settings.Secure.putInt(mContextSpy.getContentResolver(),
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1);
Settings.Secure.putInt(mContextSpy.getContentResolver(),
Settings.Secure.SCREENSAVER_ENABLED, 1);
setDreamsDisabledByAmbientModeSuppressionConfig(false);
setMinimumScreenOffTimeoutConfig(10000);
createService();
startSystem();
doAnswer(inv -> {
when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
return null;
}).when(mDreamManagerInternalMock).startDream(anyBoolean(), anyString());
setPluggedIn(true);
// Allow asynchronous sandman calls to execute.
advanceTime(10000);
forceDream();
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
mService.getBinderServiceInstance().suppressAmbientDisplay("test", true);
advanceTime(50);
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
}
@Test
public void testAmbientSuppression_doesNotAffectDreamForcing() {
Settings.Secure.putInt(mContextSpy.getContentResolver(),
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1);
Settings.Secure.putInt(mContextSpy.getContentResolver(),
Settings.Secure.SCREENSAVER_ENABLED, 1);
setDreamsDisabledByAmbientModeSuppressionConfig(true);
setMinimumScreenOffTimeoutConfig(10000);
createService();
startSystem();
doAnswer(inv -> {
when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
return null;
}).when(mDreamManagerInternalMock).startDream(anyBoolean(), anyString());
mService.getBinderServiceInstance().suppressAmbientDisplay("test", true);
setPluggedIn(true);
// Allow asynchronous sandman calls to execute.
advanceTime(10000);
// Verify that forcing dream still works even though ambient display is suppressed
forceDream();
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
}
@Test
public void testSetDozeOverrideFromDreamManager_triggersSuspendBlocker() {
final String suspendBlockerName = "PowerManagerService.Display";