Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bdde7f69 authored by William Leshner's avatar William Leshner Committed by Android (Google) Code Review
Browse files

Merge "Stop dreaming when undocking while showing low-light clock."

parents ae649a1a b26c5ab1
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -58,4 +58,32 @@ public abstract class DreamManagerInternal {
     * @param isScreenOn True if the screen is currently on.
     */
    public abstract boolean canStartDreaming(boolean isScreenOn);

    /**
     * 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);
    }
}
+35 −2
Original line number Diff line number Diff line
@@ -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
@@ -294,12 +301,12 @@ public final class DreamManagerService extends SystemService {
            pw.println("mForceAmbientDisplayEnabled=" + mForceAmbientDisplayEnabled);
            pw.println("mDreamsOnlyEnabledForDockUser=" + mDreamsOnlyEnabledForDockUser);
            pw.println("mDreamsEnabledSetting=" + mDreamsEnabledSetting);
            pw.println("mForceAmbientDisplayEnabled=" + mForceAmbientDisplayEnabled);
            pw.println("mDreamsActivatedOnDockByDefault=" + mDreamsActivatedOnDockByDefault);
            pw.println("mDreamsActivatedOnChargeByDefault=" + mDreamsActivatedOnChargeByDefault);
            pw.println("mIsDocked=" + mIsDocked);
            pw.println("mIsCharging=" + mIsCharging);
            pw.println("mWhenToDream=" + mWhenToDream);
            pw.println("mKeepDreamingWhenUndockedDefault=" + mKeepDreamingWhenUndockedDefault);
            pw.println("getDozeComponent()=" + getDozeComponent());
            pw.println();

@@ -328,6 +335,15 @@ public final class DreamManagerService extends SystemService {
        }
    }

    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) {
@@ -571,6 +587,7 @@ public final class DreamManagerService extends SystemService {
            }

            mSystemDreamComponent = componentName;
            reportKeepDreamingWhenUndockedChanged(shouldKeepDreamingWhenUndocked());

            // Switch dream if currently dreaming and not dozing.
            if (isDreamingInternal() && !isDozingInternal()) {
@@ -580,6 +597,10 @@ public final class DreamManagerService extends SystemService {
        }
    }

    private boolean shouldKeepDreamingWhenUndocked() {
        return mKeepDreamingWhenUndockedDefault && mSystemDreamComponent == null;
    }

    private ComponentName getDefaultDreamComponentForUser(int userId) {
        String name = Settings.Secure.getStringForUser(mContext.getContentResolver(),
                Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT,
@@ -1012,6 +1033,18 @@ public final class DreamManagerService extends SystemService {
        public void requestDream() {
            requestDreamInternal();
        }

        @Override
        public void registerDreamManagerStateListener(DreamManagerStateListener listener) {
            mDreamManagerStateListeners.add(listener);
            // Initialize the listener's state.
            listener.onKeepDreamingWhenUndockedChanged(shouldKeepDreamingWhenUndocked());
        }

        @Override
        public void unregisterDreamManagerStateListener(DreamManagerStateListener listener) {
            mDreamManagerStateListeners.remove(listener);
        }
    }

    private static final class DreamRecord {
+18 −8
Original line number Diff line number Diff line
@@ -472,9 +472,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;

@@ -681,6 +678,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")
@@ -1285,6 +1295,9 @@ public final class PowerManagerService extends SystemService
                    new DisplayGroupPowerChangeListener();
            mDisplayManagerInternal.registerDisplayGroupListener(displayGroupPowerChangeListener);

            // This DreamManager method does not acquire a lock, so it should be safe to call.
            mDreamManager.registerDreamManagerStateListener(new DreamManagerStateListener());

            mWirelessChargerDetector = mInjector.createWirelessChargerDetector(sensorManager,
                    mInjector.createSuspendBlocker(
                            this, "PowerManagerService.WirelessChargerDetector"),
@@ -1402,8 +1415,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(
@@ -2518,7 +2529,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) {
@@ -4472,8 +4483,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);
+71 −5
Original line number Diff line number Diff line
@@ -658,17 +658,52 @@ 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);

        createService();
        startSystem();

        when(mResourcesSpy.getBoolean(
                com.android.internal.R.bool.config_keepDreamingWhenUndocking))
        ArgumentCaptor<DreamManagerInternal.DreamManagerStateListener> dreamManagerStateListener =
                ArgumentCaptor.forClass(DreamManagerInternal.DreamManagerStateListener.class);
        verify(mDreamManagerInternalMock).registerDreamManagerStateListener(
                dreamManagerStateListener.capture());
        dreamManagerStateListener.getValue().onKeepDreamingWhenUndockedChanged(false);

        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();

        createService();
        startSystem();

        ArgumentCaptor<DreamManagerInternal.DreamManagerStateListener> dreamManagerStateListener =
                ArgumentCaptor.forClass(DreamManagerInternal.DreamManagerStateListener.class);
        verify(mDreamManagerInternalMock).registerDreamManagerStateListener(
                dreamManagerStateListener.capture());
        dreamManagerStateListener.getValue().onKeepDreamingWhenUndockedChanged(true);

        when(mBatteryManagerInternalMock.getPlugType())
                .thenReturn(BatteryManager.BATTERY_PLUGGED_DOCK);
@@ -682,6 +717,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);

        createService();
        startSystem();

        ArgumentCaptor<DreamManagerInternal.DreamManagerStateListener> dreamManagerStateListener =
                ArgumentCaptor.forClass(DreamManagerInternal.DreamManagerStateListener.class);
        verify(mDreamManagerInternalMock).registerDreamManagerStateListener(
                dreamManagerStateListener.capture());
        dreamManagerStateListener.getValue().onKeepDreamingWhenUndockedChanged(true);

        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();