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

Commit fa290397 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." into tm-qpr-dev

parents 06191a4c 6eb4c1a2
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -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);
    }
}
+36 −1
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
@@ -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,6 +336,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 +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 {
+21 −8
Original line number Diff line number Diff line
@@ -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);
+61 −5
Original line number Diff line number Diff line
@@ -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();