From e454a698d9f1fcc37c110e3d08b21f31b0be2b7e Mon Sep 17 00:00:00 2001 From: Galia Peycheva Date: Tue, 20 Dec 2022 15:52:33 +0100 Subject: [PATCH] Handle dream restart When a startDream is called directly after a stopDream for the same DreamService, the old instance should be stopped and the state should be cleared. Otherwise, the old dream's mStopStubbornDreamRunnable messes up the state in the dream manager and power manager. In this CL we stop the old dream immediately if a startDream is called for the same dream component while the old dream is gently waking. This ensures that the dream state is cleared. Bug: 260205205 Bug: 260094933 Bug: 265110360 Test: 2x adb shell cmd dreams start-dreaming - verify the device is dreaming afterwards Change-Id: Ibd261038430a38f2fa519549372ddbf19d7cb36b (cherry picked from commit 4bd7a87938db1e9035cb1b72b512f82c40d8d76a) Merged-In: Ibd261038430a38f2fa519549372ddbf19d7cb36b --- .../android/server/dreams/DreamController.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java index f87a1461f9d2c..ad5eeea893031 100644 --- a/services/core/java/com/android/server/dreams/DreamController.java +++ b/services/core/java/com/android/server/dreams/DreamController.java @@ -42,6 +42,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Iterator; import java.util.NoSuchElementException; +import java.util.Objects; /** * Internal controller for starting and stopping the current dream and managing related state. @@ -119,10 +120,20 @@ final class DreamController { + ", isPreviewMode=" + isPreviewMode + ", canDoze=" + canDoze + ", userId=" + userId + ", reason='" + reason + "'"); - if (mCurrentDream != null) { - mPreviousDreams.add(mCurrentDream); - } + final DreamRecord oldDream = mCurrentDream; mCurrentDream = new DreamRecord(token, name, isPreviewMode, canDoze, userId, wakeLock); + if (oldDream != null) { + if (!oldDream.mWakingGently) { + // We will stop these previous dreams once the new dream is started. + mPreviousDreams.add(oldDream); + } else if (Objects.equals(oldDream.mName, mCurrentDream.mName)) { + // We are attempting to start a dream that is currently waking up gently. + // Let's silently stop the old instance here to clear the dream state. + // This should happen after the new mCurrentDream is set to avoid announcing + // a "dream stopped" state. + stopDreamInstance(/* immediately */ true, "restarting same dream", oldDream); + } + } mCurrentDream.mDreamStartTime = SystemClock.elapsedRealtime(); MetricsLogger.visible(mContext,