Merge "Stop dreaming when undocking while showing low-light clock." into tm-qpr-dev

This commit is contained in:
William Leshner
2022-11-19 00:00:59 +00:00
committed by Android (Google) Code Review
4 changed files with 153 additions and 14 deletions

View File

@@ -58,4 +58,39 @@ public abstract class DreamManagerInternal {
* @param isScreenOn True if the screen is currently on. * @param isScreenOn True if the screen is currently on.
*/ */
public abstract boolean canStartDreaming(boolean isScreenOn); public abstract boolean canStartDreaming(boolean isScreenOn);
/**
* Return whether dreams can continue when undocking by default. Even if the default is true,
* it can be overridden temporarily, in which case {@link DreamManagerStateListener} will be
* informed of any changes.
*/
public abstract boolean keepDreamingWhenUndockedDefault();
/**
* Register a {@link DreamManagerStateListener}, which will be called when there are changes to
* dream state.
*
* @param listener The listener to register.
*/
public abstract void registerDreamManagerStateListener(DreamManagerStateListener listener);
/**
* Unregister a {@link DreamManagerStateListener}, which will be called when there are changes
* to dream state.
*
* @param listener The listener to unregister.
*/
public abstract void unregisterDreamManagerStateListener(DreamManagerStateListener listener);
/**
* Called when there are changes to dream state.
*/
public interface DreamManagerStateListener {
/**
* Called when keep dreaming when undocked has changed.
*
* @param keepDreaming True if the current dream should continue when undocking.
*/
void onKeepDreamingWhenUndockedChanged(boolean keepDreaming);
}
} }

View File

@@ -81,6 +81,7 @@ import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
/** /**
* Service api for managing dreams. * Service api for managing dreams.
@@ -120,6 +121,10 @@ public final class DreamManagerService extends SystemService {
private final boolean mDreamsEnabledByDefaultConfig; private final boolean mDreamsEnabledByDefaultConfig;
private final boolean mDreamsActivatedOnChargeByDefault; private final boolean mDreamsActivatedOnChargeByDefault;
private final boolean mDreamsActivatedOnDockByDefault; private final boolean mDreamsActivatedOnDockByDefault;
private final boolean mKeepDreamingWhenUndockedDefault;
private final CopyOnWriteArrayList<DreamManagerInternal.DreamManagerStateListener>
mDreamManagerStateListeners = new CopyOnWriteArrayList<>();
@GuardedBy("mLock") @GuardedBy("mLock")
private DreamRecord mCurrentDream; private DreamRecord mCurrentDream;
@@ -226,6 +231,8 @@ public final class DreamManagerService extends SystemService {
mDreamsActivatedOnDockByDefault = mContext.getResources().getBoolean( mDreamsActivatedOnDockByDefault = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault); com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
mSettingsObserver = new SettingsObserver(mHandler); mSettingsObserver = new SettingsObserver(mHandler);
mKeepDreamingWhenUndockedDefault = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_keepDreamingWhenUndocking);
} }
@Override @Override
@@ -300,6 +307,7 @@ public final class DreamManagerService extends SystemService {
pw.println("mIsDocked=" + mIsDocked); pw.println("mIsDocked=" + mIsDocked);
pw.println("mIsCharging=" + mIsCharging); pw.println("mIsCharging=" + mIsCharging);
pw.println("mWhenToDream=" + mWhenToDream); pw.println("mWhenToDream=" + mWhenToDream);
pw.println("mKeepDreamingWhenUndockedDefault=" + mKeepDreamingWhenUndockedDefault);
pw.println("getDozeComponent()=" + getDozeComponent()); pw.println("getDozeComponent()=" + getDozeComponent());
pw.println(); pw.println();
@@ -328,7 +336,16 @@ public final class DreamManagerService extends SystemService {
} }
} }
/** Whether a real dream is occurring. */ private void reportKeepDreamingWhenUndockedChanged(boolean keepDreaming) {
mHandler.post(() -> {
for (DreamManagerInternal.DreamManagerStateListener listener
: mDreamManagerStateListeners) {
listener.onKeepDreamingWhenUndockedChanged(keepDreaming);
}
});
}
/** Whether a real dream is occurring. */
private boolean isDreamingInternal() { private boolean isDreamingInternal() {
synchronized (mLock) { synchronized (mLock) {
return mCurrentDream != null && !mCurrentDream.isPreview return mCurrentDream != null && !mCurrentDream.isPreview
@@ -571,6 +588,8 @@ public final class DreamManagerService extends SystemService {
} }
mSystemDreamComponent = componentName; mSystemDreamComponent = componentName;
reportKeepDreamingWhenUndockedChanged(
mKeepDreamingWhenUndockedDefault && mSystemDreamComponent == null);
// Switch dream if currently dreaming and not dozing. // Switch dream if currently dreaming and not dozing.
if (isDreamingInternal() && !isDozingInternal()) { if (isDreamingInternal() && !isDozingInternal()) {
@@ -1012,6 +1031,22 @@ public final class DreamManagerService extends SystemService {
public void requestDream() { public void requestDream() {
requestDreamInternal(); requestDreamInternal();
} }
@Override
public boolean keepDreamingWhenUndockedDefault() {
// This value does not change, so a lock should not be needed.
return mKeepDreamingWhenUndockedDefault;
}
@Override
public void registerDreamManagerStateListener(DreamManagerStateListener listener) {
mDreamManagerStateListeners.add(listener);
}
@Override
public void unregisterDreamManagerStateListener(DreamManagerStateListener listener) {
mDreamManagerStateListeners.remove(listener);
}
} }
private static final class DreamRecord { private static final class DreamRecord {

View File

@@ -468,9 +468,6 @@ public final class PowerManagerService extends SystemService
// True if the device should wake up when plugged or unplugged. // True if the device should wake up when plugged or unplugged.
private boolean mWakeUpWhenPluggedOrUnpluggedConfig; private boolean mWakeUpWhenPluggedOrUnpluggedConfig;
// True if the device should keep dreaming when undocked.
private boolean mKeepDreamingWhenUndockingConfig;
// True if the device should wake up when plugged or unplugged in theater mode. // True if the device should wake up when plugged or unplugged in theater mode.
private boolean mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig; private boolean mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig;
@@ -677,6 +674,19 @@ public final class PowerManagerService extends SystemService
// but the DreamService has not yet been told to start (it's an async process). // but the DreamService has not yet been told to start (it's an async process).
private boolean mDozeStartInProgress; private boolean mDozeStartInProgress;
// Whether to keep dreaming when the device is undocked.
private boolean mKeepDreamingWhenUndocked;
private final class DreamManagerStateListener implements
DreamManagerInternal.DreamManagerStateListener {
@Override
public void onKeepDreamingWhenUndockedChanged(boolean keepDreaming) {
synchronized (mLock) {
mKeepDreamingWhenUndocked = keepDreaming;
}
}
}
private final class PowerGroupWakefulnessChangeListener implements private final class PowerGroupWakefulnessChangeListener implements
PowerGroup.PowerGroupListener { PowerGroup.PowerGroupListener {
@GuardedBy("mLock") @GuardedBy("mLock")
@@ -1265,6 +1275,12 @@ public final class PowerManagerService extends SystemService
new DisplayGroupPowerChangeListener(); new DisplayGroupPowerChangeListener();
mDisplayManagerInternal.registerDisplayGroupListener(displayGroupPowerChangeListener); mDisplayManagerInternal.registerDisplayGroupListener(displayGroupPowerChangeListener);
// These DreamManager methods do not acquire locks, so they should be safe to call.
mKeepDreamingWhenUndocked = mDreamManager.keepDreamingWhenUndockedDefault();
if (mKeepDreamingWhenUndocked) {
mDreamManager.registerDreamManagerStateListener(new DreamManagerStateListener());
}
mWirelessChargerDetector = mInjector.createWirelessChargerDetector(sensorManager, mWirelessChargerDetector = mInjector.createWirelessChargerDetector(sensorManager,
mInjector.createSuspendBlocker( mInjector.createSuspendBlocker(
this, "PowerManagerService.WirelessChargerDetector"), this, "PowerManagerService.WirelessChargerDetector"),
@@ -1382,8 +1398,6 @@ public final class PowerManagerService extends SystemService
com.android.internal.R.bool.config_powerDecoupleInteractiveModeFromDisplay); com.android.internal.R.bool.config_powerDecoupleInteractiveModeFromDisplay);
mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean( mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
com.android.internal.R.bool.config_unplugTurnsOnScreen); com.android.internal.R.bool.config_unplugTurnsOnScreen);
mKeepDreamingWhenUndockingConfig = resources.getBoolean(
com.android.internal.R.bool.config_keepDreamingWhenUndocking);
mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig = resources.getBoolean( mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig = resources.getBoolean(
com.android.internal.R.bool.config_allowTheaterModeWakeFromUnplug); com.android.internal.R.bool.config_allowTheaterModeWakeFromUnplug);
mSuspendWhenScreenOffDueToProximityConfig = resources.getBoolean( mSuspendWhenScreenOffDueToProximityConfig = resources.getBoolean(
@@ -2508,7 +2522,7 @@ public final class PowerManagerService extends SystemService
} }
// Don't wake when undocking while dreaming if configured not to. // Don't wake when undocking while dreaming if configured not to.
if (mKeepDreamingWhenUndockingConfig if (mKeepDreamingWhenUndocked
&& getGlobalWakefulnessLocked() == WAKEFULNESS_DREAMING && getGlobalWakefulnessLocked() == WAKEFULNESS_DREAMING
&& wasPowered && !mIsPowered && wasPowered && !mIsPowered
&& oldPlugType == BatteryManager.BATTERY_PLUGGED_DOCK) { && oldPlugType == BatteryManager.BATTERY_PLUGGED_DOCK) {
@@ -4457,8 +4471,7 @@ public final class PowerManagerService extends SystemService
+ mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig); + mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig);
pw.println(" mTheaterModeEnabled=" pw.println(" mTheaterModeEnabled="
+ mTheaterModeEnabled); + mTheaterModeEnabled);
pw.println(" mKeepDreamingWhenUndockingConfig=" pw.println(" mKeepDreamingWhenUndocked=" + mKeepDreamingWhenUndocked);
+ mKeepDreamingWhenUndockingConfig);
pw.println(" mSuspendWhenScreenOffDueToProximityConfig=" pw.println(" mSuspendWhenScreenOffDueToProximityConfig="
+ mSuspendWhenScreenOffDueToProximityConfig); + mSuspendWhenScreenOffDueToProximityConfig);
pw.println(" mDreamsSupportedConfig=" + mDreamsSupportedConfig); pw.println(" mDreamsSupportedConfig=" + mDreamsSupportedConfig);

View File

@@ -619,17 +619,42 @@ public class PowerManagerServiceTest {
} }
/** /**
* Tests that dreaming continues when undocking and configured to do so. * Tests that dreaming stops when undocking and not configured to keep dreaming.
*/ */
@Test @Test
public void testWakefulnessDream_shouldKeepDreamingWhenUndocked() { public void testWakefulnessDream_shouldStopDreamingWhenUndocked_whenNotConfigured() {
// Make sure "unplug turns on screen" is configured to true.
when(mResourcesSpy.getBoolean(com.android.internal.R.bool.config_unplugTurnsOnScreen))
.thenReturn(true);
when(mDreamManagerInternalMock.keepDreamingWhenUndockedDefault()).thenReturn(false);
createService(); createService();
startSystem(); startSystem();
when(mResourcesSpy.getBoolean( when(mBatteryManagerInternalMock.getPlugType())
com.android.internal.R.bool.config_keepDreamingWhenUndocking)) .thenReturn(BatteryManager.BATTERY_PLUGGED_DOCK);
setPluggedIn(true);
forceAwake(); // Needs to be awake first before it can dream.
forceDream();
when(mBatteryManagerInternalMock.getPlugType()).thenReturn(0);
setPluggedIn(false);
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
}
/**
* Tests that dreaming continues when undocking and configured to do so.
*/
@Test
public void testWakefulnessDream_shouldKeepDreamingWhenUndocked_whenConfigured() {
// Make sure "unplug turns on screen" is configured to true.
when(mResourcesSpy.getBoolean(com.android.internal.R.bool.config_unplugTurnsOnScreen))
.thenReturn(true); .thenReturn(true);
mService.readConfigurationLocked(); when(mDreamManagerInternalMock.keepDreamingWhenUndockedDefault()).thenReturn(true);
createService();
startSystem();
when(mBatteryManagerInternalMock.getPlugType()) when(mBatteryManagerInternalMock.getPlugType())
.thenReturn(BatteryManager.BATTERY_PLUGGED_DOCK); .thenReturn(BatteryManager.BATTERY_PLUGGED_DOCK);
@@ -643,6 +668,37 @@ public class PowerManagerServiceTest {
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING); assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
} }
/**
* Tests that dreaming stops when undocking while showing a dream that prevents it.
*/
@Test
public void testWakefulnessDream_shouldStopDreamingWhenUndocked_whenDreamPrevents() {
// Make sure "unplug turns on screen" is configured to true.
when(mResourcesSpy.getBoolean(com.android.internal.R.bool.config_unplugTurnsOnScreen))
.thenReturn(true);
when(mDreamManagerInternalMock.keepDreamingWhenUndockedDefault()).thenReturn(true);
createService();
startSystem();
ArgumentCaptor<DreamManagerInternal.DreamManagerStateListener> dreamManagerStateListener =
ArgumentCaptor.forClass(DreamManagerInternal.DreamManagerStateListener.class);
verify(mDreamManagerInternalMock).registerDreamManagerStateListener(
dreamManagerStateListener.capture());
when(mBatteryManagerInternalMock.getPlugType())
.thenReturn(BatteryManager.BATTERY_PLUGGED_DOCK);
setPluggedIn(true);
forceAwake(); // Needs to be awake first before it can dream.
forceDream();
dreamManagerStateListener.getValue().onKeepDreamingWhenUndockedChanged(false);
when(mBatteryManagerInternalMock.getPlugType()).thenReturn(0);
setPluggedIn(false);
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
}
@Test @Test
public void testWakefulnessDoze_goToSleep() { public void testWakefulnessDoze_goToSleep() {
createService(); createService();