summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-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
4 files changed, 106 insertions, 50 deletions
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();
}