diff options
| author | 2022-10-20 14:18:57 -0700 | |
|---|---|---|
| committer | 2022-11-17 15:08:04 -0800 | |
| commit | 6eb4c1a28c84750b9745503d4aa5c37814462192 (patch) | |
| tree | db04906ba5a3da1f78f155417535d3de492d454f | |
| parent | fb435f4376077013f555adff8117e90060e610de (diff) | |
Stop dreaming when undocking while showing low-light clock.
Bug: 254633538
Test: atest PowerManagerServiceTest
Merged-In: I8a9999f9648b9591bf8672d138463d0d401fcf75
Change-Id: I5f06162868496e220201c2f3ee651cc07477ef78
4 files changed, 153 insertions, 14 deletions
diff --git a/core/java/android/service/dreams/DreamManagerInternal.java b/core/java/android/service/dreams/DreamManagerInternal.java index cd38e8a01d62..7c2f9520bb00 100644 --- a/core/java/android/service/dreams/DreamManagerInternal.java +++ b/core/java/android/service/dreams/DreamManagerInternal.java @@ -58,4 +58,39 @@ public abstract class DreamManagerInternal { * @param isScreenOn True if the screen is currently on. */ 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); + } } diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java index 8f6df0f52527..3a49d8627c23 100644 --- a/services/core/java/com/android/server/dreams/DreamManagerService.java +++ b/services/core/java/com/android/server/dreams/DreamManagerService.java @@ -81,6 +81,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; /** * Service api for managing dreams. @@ -120,6 +121,10 @@ public final class DreamManagerService extends SystemService { private final boolean mDreamsEnabledByDefaultConfig; private final boolean mDreamsActivatedOnChargeByDefault; private final boolean mDreamsActivatedOnDockByDefault; + private final boolean mKeepDreamingWhenUndockedDefault; + + private final CopyOnWriteArrayList<DreamManagerInternal.DreamManagerStateListener> + mDreamManagerStateListeners = new CopyOnWriteArrayList<>(); @GuardedBy("mLock") private DreamRecord mCurrentDream; @@ -226,6 +231,8 @@ public final class DreamManagerService extends SystemService { mDreamsActivatedOnDockByDefault = mContext.getResources().getBoolean( com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault); mSettingsObserver = new SettingsObserver(mHandler); + mKeepDreamingWhenUndockedDefault = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_keepDreamingWhenUndocking); } @Override @@ -300,6 +307,7 @@ public final class DreamManagerService extends SystemService { pw.println("mIsDocked=" + mIsDocked); pw.println("mIsCharging=" + mIsCharging); pw.println("mWhenToDream=" + mWhenToDream); + pw.println("mKeepDreamingWhenUndockedDefault=" + mKeepDreamingWhenUndockedDefault); pw.println("getDozeComponent()=" + getDozeComponent()); 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() { synchronized (mLock) { return mCurrentDream != null && !mCurrentDream.isPreview @@ -571,6 +588,8 @@ public final class DreamManagerService extends SystemService { } mSystemDreamComponent = componentName; + reportKeepDreamingWhenUndockedChanged( + mKeepDreamingWhenUndockedDefault && mSystemDreamComponent == null); // Switch dream if currently dreaming and not dozing. if (isDreamingInternal() && !isDozingInternal()) { @@ -1012,6 +1031,22 @@ public final class DreamManagerService extends SystemService { public void requestDream() { 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 { diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 377a651eb031..ab90ef929d28 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -468,9 +468,6 @@ public final class PowerManagerService extends SystemService // True if the device should wake up when plugged or unplugged. 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. 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). 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 PowerGroup.PowerGroupListener { @GuardedBy("mLock") @@ -1265,6 +1275,12 @@ public final class PowerManagerService extends SystemService new 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, mInjector.createSuspendBlocker( this, "PowerManagerService.WirelessChargerDetector"), @@ -1382,8 +1398,6 @@ public final class PowerManagerService extends SystemService com.android.internal.R.bool.config_powerDecoupleInteractiveModeFromDisplay); mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean( com.android.internal.R.bool.config_unplugTurnsOnScreen); - mKeepDreamingWhenUndockingConfig = resources.getBoolean( - com.android.internal.R.bool.config_keepDreamingWhenUndocking); mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig = resources.getBoolean( com.android.internal.R.bool.config_allowTheaterModeWakeFromUnplug); mSuspendWhenScreenOffDueToProximityConfig = resources.getBoolean( @@ -2508,7 +2522,7 @@ public final class PowerManagerService extends SystemService } // Don't wake when undocking while dreaming if configured not to. - if (mKeepDreamingWhenUndockingConfig + if (mKeepDreamingWhenUndocked && getGlobalWakefulnessLocked() == WAKEFULNESS_DREAMING && wasPowered && !mIsPowered && oldPlugType == BatteryManager.BATTERY_PLUGGED_DOCK) { @@ -4457,8 +4471,7 @@ public final class PowerManagerService extends SystemService + mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig); pw.println(" mTheaterModeEnabled=" + mTheaterModeEnabled); - pw.println(" mKeepDreamingWhenUndockingConfig=" - + mKeepDreamingWhenUndockingConfig); + pw.println(" mKeepDreamingWhenUndocked=" + mKeepDreamingWhenUndocked); pw.println(" mSuspendWhenScreenOffDueToProximityConfig=" + mSuspendWhenScreenOffDueToProximityConfig); pw.println(" mDreamsSupportedConfig=" + mDreamsSupportedConfig); 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 f5ed41a7fa8b..32772a41f71b 100644 --- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java @@ -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 - 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(); startSystem(); - when(mResourcesSpy.getBoolean( - com.android.internal.R.bool.config_keepDreamingWhenUndocking)) + when(mBatteryManagerInternalMock.getPlugType()) + .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); - mService.readConfigurationLocked(); + when(mDreamManagerInternalMock.keepDreamingWhenUndockedDefault()).thenReturn(true); + + createService(); + startSystem(); when(mBatteryManagerInternalMock.getPlugType()) .thenReturn(BatteryManager.BATTERY_PLUGGED_DOCK); @@ -643,6 +668,37 @@ public class PowerManagerServiceTest { 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 public void testWakefulnessDoze_goToSleep() { createService(); |