summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt2
-rw-r--r--core/java/android/service/dreams/DreamManagerInternal.java8
-rw-r--r--core/java/android/service/dreams/DreamService.java145
-rw-r--r--core/java/android/service/dreams/IDreamManager.aidl2
-rw-r--r--core/java/android/service/dreams/IDreamService.aidl1
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindowManager.java2
-rw-r--r--services/core/java/com/android/server/dreams/DreamController.java51
-rw-r--r--services/core/java/com/android/server/dreams/DreamManagerService.java54
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java4
9 files changed, 185 insertions, 84 deletions
diff --git a/api/current.txt b/api/current.txt
index 399e92c..86ea9c8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -26961,6 +26961,7 @@ package android.service.dreams {
method public void onPanelClosed(int, android.view.Menu);
method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
method public boolean onSearchRequested();
+ method public void onWakeUp();
method public void onWindowAttributesChanged(android.view.WindowManager.LayoutParams);
method public void onWindowFocusChanged(boolean);
method public android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback);
@@ -26970,6 +26971,7 @@ package android.service.dreams {
method public void setFullscreen(boolean);
method public void setInteractive(boolean);
method public void setScreenBright(boolean);
+ method public final void wakeUp();
field public static final java.lang.String DREAM_META_DATA = "android.service.dream";
field public static final java.lang.String SERVICE_INTERFACE = "android.service.dreams.DreamService";
}
diff --git a/core/java/android/service/dreams/DreamManagerInternal.java b/core/java/android/service/dreams/DreamManagerInternal.java
index 9f7ddba..ff7cef9 100644
--- a/core/java/android/service/dreams/DreamManagerInternal.java
+++ b/core/java/android/service/dreams/DreamManagerInternal.java
@@ -24,13 +24,19 @@ package android.service.dreams;
public abstract class DreamManagerInternal {
/**
* Called by the power manager to start a dream.
+ *
+ * @param doze If true, starts the doze dream component if one has been configured,
+ * otherwise starts the user-specified dream.
*/
public abstract void startDream(boolean doze);
/**
* Called by the power manager to stop a dream.
+ *
+ * @param immediate If true, ends the dream summarily, otherwise gives it some time
+ * to perform a proper exit transition.
*/
- public abstract void stopDream();
+ public abstract void stopDream(boolean immediate);
/**
* Called by the power manager to determine whether a dream is running.
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 1e9ce05..5fa542a 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -171,6 +171,7 @@ public class DreamService extends Service implements Window.Callback {
private boolean mFullscreen;
private boolean mScreenBright = true;
private boolean mStarted;
+ private boolean mWaking;
private boolean mFinished;
private boolean mCanDoze;
private boolean mDozing;
@@ -196,12 +197,12 @@ public class DreamService extends Service implements Window.Callback {
public boolean dispatchKeyEvent(KeyEvent event) {
// TODO: create more flexible version of mInteractive that allows use of KEYCODE_BACK
if (!mInteractive) {
- if (mDebug) Slog.v(TAG, "Finishing on keyEvent");
- safelyFinish();
+ if (mDebug) Slog.v(TAG, "Waking up on keyEvent");
+ wakeUp();
return true;
} else if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
- if (mDebug) Slog.v(TAG, "Finishing on back key");
- safelyFinish();
+ if (mDebug) Slog.v(TAG, "Waking up on back key");
+ wakeUp();
return true;
}
return mWindow.superDispatchKeyEvent(event);
@@ -211,8 +212,8 @@ public class DreamService extends Service implements Window.Callback {
@Override
public boolean dispatchKeyShortcutEvent(KeyEvent event) {
if (!mInteractive) {
- if (mDebug) Slog.v(TAG, "Finishing on keyShortcutEvent");
- safelyFinish();
+ if (mDebug) Slog.v(TAG, "Waking up on keyShortcutEvent");
+ wakeUp();
return true;
}
return mWindow.superDispatchKeyShortcutEvent(event);
@@ -224,8 +225,8 @@ public class DreamService extends Service implements Window.Callback {
// TODO: create more flexible version of mInteractive that allows clicks
// but finish()es on any other kind of activity
if (!mInteractive) {
- if (mDebug) Slog.v(TAG, "Finishing on touchEvent");
- safelyFinish();
+ if (mDebug) Slog.v(TAG, "Waking up on touchEvent");
+ wakeUp();
return true;
}
return mWindow.superDispatchTouchEvent(event);
@@ -235,8 +236,8 @@ public class DreamService extends Service implements Window.Callback {
@Override
public boolean dispatchTrackballEvent(MotionEvent event) {
if (!mInteractive) {
- if (mDebug) Slog.v(TAG, "Finishing on trackballEvent");
- safelyFinish();
+ if (mDebug) Slog.v(TAG, "Waking up on trackballEvent");
+ wakeUp();
return true;
}
return mWindow.superDispatchTrackballEvent(event);
@@ -246,8 +247,8 @@ public class DreamService extends Service implements Window.Callback {
@Override
public boolean dispatchGenericMotionEvent(MotionEvent event) {
if (!mInteractive) {
- if (mDebug) Slog.v(TAG, "Finishing on genericMotionEvent");
- safelyFinish();
+ if (mDebug) Slog.v(TAG, "Waking up on genericMotionEvent");
+ wakeUp();
return true;
}
return mWindow.superDispatchGenericMotionEvent(event);
@@ -690,6 +691,22 @@ public class DreamService extends Service implements Window.Callback {
// hook for subclasses
}
+ /**
+ * Called when the dream is being asked to stop itself and wake.
+ * <p>
+ * The default implementation simply calls {@link #finish} which ends the dream
+ * immediately. Subclasses may override this function to perform a smooth exit
+ * transition then call {@link #finish} afterwards.
+ * </p><p>
+ * Note that the dream will only be given a short period of time (currently about
+ * five seconds) to wake up. If the dream does not finish itself in a timely manner
+ * then the system will forcibly finish it once the time allowance is up.
+ * </p>
+ */
+ public void onWakeUp() {
+ finish();
+ }
+
/** {@inheritDoc} */
@Override
public final IBinder onBind(Intent intent) {
@@ -705,8 +722,62 @@ public class DreamService extends Service implements Window.Callback {
* </p>
*/
public final void finish() {
- if (mDebug) Slog.v(TAG, "finish()");
- finishInternal();
+ if (mDebug) Slog.v(TAG, "finish(): mFinished=" + mFinished);
+
+ if (!mFinished) {
+ mFinished = true;
+
+ if (mWindowToken == null) {
+ Slog.w(TAG, "Finish was called before the dream was attached.");
+ } else {
+ try {
+ mSandman.finishSelf(mWindowToken, true /*immediate*/);
+ } catch (RemoteException ex) {
+ // system server died
+ }
+ }
+
+ stopSelf(); // if launched via any other means
+ }
+ }
+
+ /**
+ * Wakes the dream up gently.
+ * <p>
+ * Calls {@link #onWakeUp} to give the dream a chance to perform an exit transition.
+ * When the transition is over, the dream should call {@link #finish}.
+ * </p>
+ */
+ public final void wakeUp() {
+ wakeUp(false);
+ }
+
+ private void wakeUp(boolean fromSystem) {
+ if (mDebug) Slog.v(TAG, "wakeUp(): fromSystem=" + fromSystem
+ + ", mWaking=" + mWaking + ", mFinished=" + mFinished);
+
+ if (!mWaking && !mFinished) {
+ mWaking = true;
+
+ // As a minor optimization, invoke the callback first in case it simply
+ // calls finish() immediately so there wouldn't be much point in telling
+ // the system that we are finishing the dream gently.
+ onWakeUp();
+
+ // Now tell the system we are waking gently, unless we already told
+ // it we were finishing immediately.
+ if (!fromSystem && !mFinished) {
+ if (mWindowToken == null) {
+ Slog.w(TAG, "WakeUp was called before the dream was attached.");
+ } else {
+ try {
+ mSandman.finishSelf(mWindowToken, false /*immediate*/);
+ } catch (RemoteException ex) {
+ // system server died
+ }
+ }
+ }
+ }
}
/** {@inheritDoc} */
@@ -763,10 +834,10 @@ public class DreamService extends Service implements Window.Callback {
Slog.e(TAG, "attach() called when already attached with token=" + mWindowToken);
return;
}
- if (mFinished) {
+ if (mFinished || mWaking) {
Slog.w(TAG, "attach() called after dream already finished");
try {
- mSandman.finishSelf(windowToken);
+ mSandman.finishSelf(windowToken, true /*immediate*/);
} catch (RemoteException ex) {
// system server died
}
@@ -837,37 +908,6 @@ public class DreamService extends Service implements Window.Callback {
});
}
- private void safelyFinish() {
- if (mDebug) Slog.v(TAG, "safelyFinish()");
-
- finish();
-
- if (!mFinished) {
- Slog.w(TAG, "Bad dream, did not call super.finish()");
- finishInternal();
- }
- }
-
- private void finishInternal() {
- if (mDebug) Slog.v(TAG, "finishInternal() mFinished = " + mFinished);
-
- if (!mFinished) {
- mFinished = true;
-
- if (mWindowToken == null) {
- Slog.w(TAG, "Finish was called before the dream was attached.");
- } else {
- try {
- mSandman.finishSelf(mWindowToken);
- } catch (RemoteException ex) {
- // system server died
- }
- }
-
- stopSelf(); // if launched via any other means
- }
- }
-
private boolean getWindowFlagValue(int flag, boolean defaultValue) {
return mWindow == null ? defaultValue : (mWindow.getAttributes().flags & flag) != 0;
}
@@ -946,6 +986,15 @@ public class DreamService extends Service implements Window.Callback {
}
});
}
- }
+ @Override
+ public void wakeUp() {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ DreamService.this.wakeUp(true /*fromSystem*/);
+ }
+ });
+ }
+ }
}
diff --git a/core/java/android/service/dreams/IDreamManager.aidl b/core/java/android/service/dreams/IDreamManager.aidl
index 2718e31..9608a4d 100644
--- a/core/java/android/service/dreams/IDreamManager.aidl
+++ b/core/java/android/service/dreams/IDreamManager.aidl
@@ -31,7 +31,7 @@ interface IDreamManager {
ComponentName getDefaultDreamComponent();
void testDream(in ComponentName componentName);
boolean isDreaming();
- void finishSelf(in IBinder token);
+ void finishSelf(in IBinder token, boolean immediate);
void startDozing(in IBinder token);
void stopDozing(in IBinder token);
IDozeHardware getDozeHardware(in IBinder token);
diff --git a/core/java/android/service/dreams/IDreamService.aidl b/core/java/android/service/dreams/IDreamService.aidl
index bd58f1d..9bb1804 100644
--- a/core/java/android/service/dreams/IDreamService.aidl
+++ b/core/java/android/service/dreams/IDreamService.aidl
@@ -22,4 +22,5 @@ package android.service.dreams;
oneway interface IDreamService {
void attach(IBinder windowToken, boolean canDoze);
void detach();
+ void wakeUp();
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index a3c84c6..ba4c588 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -2179,7 +2179,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// If there's a dream running then use home to escape the dream
// but don't actually go home.
if (mDreamManagerInternal != null && mDreamManagerInternal.isDreaming()) {
- mDreamManagerInternal.stopDream();
+ mDreamManagerInternal.stopDream(false /*immediate*/);
return -1;
}
diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java
index 649b5c9..334f0ac 100644
--- a/services/core/java/com/android/server/dreams/DreamController.java
+++ b/services/core/java/com/android/server/dreams/DreamController.java
@@ -47,6 +47,9 @@ final class DreamController {
// How long we wait for a newly bound dream to create the service connection
private static final int DREAM_CONNECTION_TIMEOUT = 5 * 1000;
+ // Time to allow the dream to perform an exit transition when waking up.
+ private static final int DREAM_FINISH_TIMEOUT = 5 * 1000;
+
private final Context mContext;
private final Handler mHandler;
private final Listener mListener;
@@ -66,11 +69,19 @@ final class DreamController {
public void run() {
if (mCurrentDream != null && mCurrentDream.mBound && !mCurrentDream.mConnected) {
Slog.w(TAG, "Bound dream did not connect in the time allotted");
- stopDream();
+ stopDream(true /*immediate*/);
}
}
};
+ private final Runnable mStopStubbornDreamRunnable = new Runnable() {
+ @Override
+ public void run() {
+ Slog.w(TAG, "Stubborn dream did not finish itself in the time allotted");
+ stopDream(true /*immediate*/);
+ }
+ };
+
public DreamController(Context context, Handler handler, Listener listener) {
mContext = context;
mHandler = handler;
@@ -90,6 +101,7 @@ final class DreamController {
pw.println(" mBound=" + mCurrentDream.mBound);
pw.println(" mService=" + mCurrentDream.mService);
pw.println(" mSentStartBroadcast=" + mCurrentDream.mSentStartBroadcast);
+ pw.println(" mWakingGently=" + mCurrentDream.mWakingGently);
} else {
pw.println(" mCurrentDream: null");
}
@@ -97,7 +109,7 @@ final class DreamController {
public void startDream(Binder token, ComponentName name,
boolean isTest, boolean canDoze, int userId) {
- stopDream();
+ stopDream(true /*immediate*/);
// Close the notification shade. Don't need to send to all, but better to be explicit.
mContext.sendBroadcastAsUser(mCloseNotificationShadeIntent, UserHandle.ALL);
@@ -112,7 +124,7 @@ final class DreamController {
mIWindowManager.addWindowToken(token, WindowManager.LayoutParams.TYPE_DREAM);
} catch (RemoteException ex) {
Slog.e(TAG, "Unable to add window token for dream.", ex);
- stopDream();
+ stopDream(true /*immediate*/);
return;
}
@@ -123,12 +135,12 @@ final class DreamController {
if (!mContext.bindServiceAsUser(intent, mCurrentDream,
Context.BIND_AUTO_CREATE, new UserHandle(userId))) {
Slog.e(TAG, "Unable to bind dream service: " + intent);
- stopDream();
+ stopDream(true /*immediate*/);
return;
}
} catch (SecurityException ex) {
Slog.e(TAG, "Unable to bind dream service: " + intent, ex);
- stopDream();
+ stopDream(true /*immediate*/);
return;
}
@@ -136,11 +148,29 @@ final class DreamController {
mHandler.postDelayed(mStopUnconnectedDreamRunnable, DREAM_CONNECTION_TIMEOUT);
}
- public void stopDream() {
+ public void stopDream(boolean immediate) {
if (mCurrentDream == null) {
return;
}
+ if (!immediate) {
+ if (mCurrentDream.mWakingGently) {
+ return; // already waking gently
+ }
+
+ if (mCurrentDream.mService != null) {
+ // Give the dream a moment to wake up and finish itself gently.
+ mCurrentDream.mWakingGently = true;
+ try {
+ mCurrentDream.mService.wakeUp();
+ mHandler.postDelayed(mStopStubbornDreamRunnable, DREAM_FINISH_TIMEOUT);
+ return;
+ } catch (RemoteException ex) {
+ // oh well, we tried, finish immediately instead
+ }
+ }
+ }
+
final DreamRecord oldDream = mCurrentDream;
mCurrentDream = null;
Slog.i(TAG, "Stopping dream: name=" + oldDream.mName
@@ -148,6 +178,7 @@ final class DreamController {
+ ", userId=" + oldDream.mUserId);
mHandler.removeCallbacks(mStopUnconnectedDreamRunnable);
+ mHandler.removeCallbacks(mStopStubbornDreamRunnable);
if (oldDream.mSentStartBroadcast) {
mContext.sendBroadcastAsUser(mDreamingStoppedIntent, UserHandle.ALL);
@@ -195,7 +226,7 @@ final class DreamController {
service.attach(mCurrentDream.mToken, mCurrentDream.mCanDoze);
} catch (RemoteException ex) {
Slog.e(TAG, "The dream service died unexpectedly.", ex);
- stopDream();
+ stopDream(true /*immediate*/);
return;
}
@@ -226,6 +257,8 @@ final class DreamController {
public IDreamService mService;
public boolean mSentStartBroadcast;
+ public boolean mWakingGently;
+
public DreamRecord(Binder token, ComponentName name,
boolean isTest, boolean canDoze, int userId) {
mToken = token;
@@ -243,7 +276,7 @@ final class DreamController {
public void run() {
mService = null;
if (mCurrentDream == DreamRecord.this) {
- stopDream();
+ stopDream(true /*immediate*/);
}
}
});
@@ -271,7 +304,7 @@ final class DreamController {
public void run() {
mService = null;
if (mCurrentDream == DreamRecord.this) {
- stopDream();
+ stopDream(true /*immediate*/);
}
}
});
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index a35e2ba..4ccf73b 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -80,6 +80,7 @@ public final class DreamManagerService extends SystemService {
private boolean mCurrentDreamIsTest;
private boolean mCurrentDreamCanDoze;
private boolean mCurrentDreamIsDozing;
+ private boolean mCurrentDreamIsWaking;
private DozeHardwareWrapper mCurrentDreamDozeHardware;
public DreamManagerService(Context context) {
@@ -113,7 +114,7 @@ public final class DreamManagerService extends SystemService {
@Override
public void onReceive(Context context, Intent intent) {
synchronized (mLock) {
- stopDreamLocked();
+ stopDreamLocked(false /*immediate*/);
}
}
}, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
@@ -132,6 +133,7 @@ public final class DreamManagerService extends SystemService {
pw.println("mCurrentDreamIsTest=" + mCurrentDreamIsTest);
pw.println("mCurrentDreamCanDoze=" + mCurrentDreamCanDoze);
pw.println("mCurrentDreamIsDozing=" + mCurrentDreamIsDozing);
+ pw.println("mCurrentDreamIsWaking=" + mCurrentDreamIsWaking);
pw.println("mCurrentDreamDozeHardware=" + mCurrentDreamDozeHardware);
pw.println("getDozeComponent()=" + getDozeComponent());
pw.println();
@@ -146,7 +148,8 @@ public final class DreamManagerService extends SystemService {
private boolean isDreamingInternal() {
synchronized (mLock) {
- return mCurrentDreamToken != null && !mCurrentDreamIsTest;
+ return mCurrentDreamToken != null && !mCurrentDreamIsTest
+ && !mCurrentDreamIsWaking;
}
}
@@ -166,12 +169,12 @@ public final class DreamManagerService extends SystemService {
// for example when being undocked.
long time = SystemClock.uptimeMillis();
mPowerManager.userActivity(time, false /*noChangeLights*/);
- stopDreamInternal();
+ stopDreamInternal(false /*immediate*/);
}
- private void finishSelfInternal(IBinder token) {
+ private void finishSelfInternal(IBinder token, boolean immediate) {
if (DEBUG) {
- Slog.d(TAG, "Dream finished: " + token);
+ Slog.d(TAG, "Dream finished: " + token + ", immediate=" + immediate);
}
// Note that a dream finishing and self-terminating is not
@@ -183,7 +186,7 @@ public final class DreamManagerService extends SystemService {
// device may simply go to sleep.
synchronized (mLock) {
if (mCurrentDreamToken == token) {
- stopDreamLocked();
+ stopDreamLocked(immediate);
}
}
}
@@ -204,9 +207,9 @@ public final class DreamManagerService extends SystemService {
}
}
- private void stopDreamInternal() {
+ private void stopDreamInternal(boolean immediate) {
synchronized (mLock) {
- stopDreamLocked();
+ stopDreamLocked(immediate);
}
}
@@ -345,9 +348,9 @@ public final class DreamManagerService extends SystemService {
return;
}
- stopDreamLocked();
+ stopDreamLocked(true /*immediate*/);
- if (DEBUG) Slog.i(TAG, "Entering dreamland.");
+ Slog.i(TAG, "Entering dreamland.");
final Binder newToken = new Binder();
mCurrentDreamToken = newToken;
@@ -364,16 +367,22 @@ public final class DreamManagerService extends SystemService {
});
}
- private void stopDreamLocked() {
+ private void stopDreamLocked(final boolean immediate) {
if (mCurrentDreamToken != null) {
- if (DEBUG) Slog.i(TAG, "Leaving dreamland.");
-
- cleanupDreamLocked();
+ if (immediate) {
+ Slog.i(TAG, "Leaving dreamland.");
+ cleanupDreamLocked();
+ } else if (mCurrentDreamIsWaking) {
+ return; // already waking
+ } else {
+ Slog.i(TAG, "Gently waking up from dream.");
+ mCurrentDreamIsWaking = true;
+ }
mHandler.post(new Runnable() {
@Override
public void run() {
- mController.stopDream();
+ mController.stopDream(immediate);
}
});
}
@@ -385,6 +394,7 @@ public final class DreamManagerService extends SystemService {
mCurrentDreamIsTest = false;
mCurrentDreamCanDoze = false;
mCurrentDreamUserId = 0;
+ mCurrentDreamIsWaking = false;
if (mCurrentDreamIsDozing) {
mCurrentDreamIsDozing = false;
mDozeWakeLock.release();
@@ -568,7 +578,7 @@ public final class DreamManagerService extends SystemService {
}
@Override // Binder call
- public void finishSelf(IBinder token) {
+ public void finishSelf(IBinder token, boolean immediate) {
// Requires no permission, called by Dream from an arbitrary process.
if (token == null) {
throw new IllegalArgumentException("token must not be null");
@@ -576,7 +586,7 @@ public final class DreamManagerService extends SystemService {
final long ident = Binder.clearCallingIdentity();
try {
- finishSelfInternal(token);
+ finishSelfInternal(token, immediate);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -635,8 +645,8 @@ public final class DreamManagerService extends SystemService {
}
@Override
- public void stopDream() {
- stopDreamInternal();
+ public void stopDream(boolean immediate) {
+ stopDreamInternal(immediate);
}
@Override
@@ -683,11 +693,11 @@ public final class DreamManagerService extends SystemService {
@Override
public void run() {
if (DEBUG) Slog.d(TAG, "System properties changed");
- synchronized(mLock) {
+ synchronized (mLock) {
if (mCurrentDreamName != null && mCurrentDreamCanDoze
&& !mCurrentDreamName.equals(getDozeComponent())) {
- // may have updated the doze component, wake up
- stopDreamLocked();
+ // May have updated the doze component, wake up
+ mPowerManager.wakeUp(SystemClock.uptimeMillis());
}
}
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index cb4d339..4b1e8eb 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -1551,7 +1551,7 @@ public final class PowerManagerService extends com.android.server.SystemService
if (mDreamManager != null) {
// Restart the dream whenever the sandman is summoned.
if (startDreaming) {
- mDreamManager.stopDream();
+ mDreamManager.stopDream(false /*immediate*/);
mDreamManager.startDream(wakefulness == WAKEFULNESS_DOZING);
}
isDreaming = mDreamManager.isDreaming();
@@ -1619,7 +1619,7 @@ public final class PowerManagerService extends com.android.server.SystemService
// Stop dream.
if (isDreaming) {
- mDreamManager.stopDream();
+ mDreamManager.stopDream(false /*immediate*/);
}
}