Merge "Framework support for Android Dreams."
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 8ee18f7..c78b935 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3744,6 +3744,23 @@
"setup_prepaid_detection_redir_host";
/**
+ * The user's preferred "dream" (interactive screensaver) component.
+ *
+ * This component will be launched by the PhoneWindowManager after the user's chosen idle
+ * timeout (specified by {@link #DREAM_TIMEOUT}).
+ * @hide
+ */
+ public static final String DREAM_COMPONENT =
+ "dream_component";
+
+ /**
+ * The delay before a "dream" is started (set to 0 to disable).
+ * @hide
+ */
+ public static final String DREAM_TIMEOUT =
+ "dream_timeout";
+
+ /**
* @hide
*/
public static final String[] SETTINGS_TO_BACKUP = {
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 4e52e40..64b1ac8 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -884,7 +884,13 @@
public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always);
/**
- * Called when we have stopped keeping the screen on because a window
+ * Called when we have started keeping the screen on because a window
+ * requesting this has become visible.
+ */
+ public void screenOnStartedLw();
+
+ /**
+ * Called when we have stopped keeping the screen on because the last window
* requesting this is no longer visible.
*/
public void screenOnStoppedLw();
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index e5abeac..e48dbe9 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -23,6 +23,7 @@
import android.app.UiModeManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -344,6 +345,10 @@
int mLockScreenTimeout;
boolean mLockScreenTimerActive;
+ // visual screen saver support
+ int mScreenSaverTimeout;
+ boolean mScreenSaverEnabled = false;
+
// Behavior of ENDCALL Button. (See Settings.System.END_BUTTON_BEHAVIOR.)
int mEndcallBehavior;
@@ -399,6 +404,8 @@
Settings.Secure.DEFAULT_INPUT_METHOD), false, this);
resolver.registerContentObserver(Settings.System.getUriFor(
"fancy_rotation_anim"), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.Secure.DREAM_TIMEOUT), false, this);
updateSettings();
}
@@ -832,6 +839,11 @@
mHasSoftInput = hasSoftInput;
updateRotation = true;
}
+
+ mScreenSaverTimeout = Settings.System.getInt(resolver,
+ Settings.Secure.DREAM_TIMEOUT, 0);
+ mScreenSaverEnabled = true;
+ updateScreenSaverTimeoutLocked();
}
if (updateRotation) {
updateRotation(0);
@@ -2603,6 +2615,7 @@
mScreenOn = false;
updateOrientationListenerLp();
updateLockScreenTimeout();
+ updateScreenSaverTimeoutLocked();
}
}
@@ -2614,6 +2627,7 @@
mScreenOn = true;
updateOrientationListenerLp();
updateLockScreenTimeout();
+ updateScreenSaverTimeoutLocked();
}
}
@@ -2894,6 +2908,63 @@
mStatusBarService.userActivity();
} catch (RemoteException ex) {}
}
+
+ synchronized (mLock) {
+ updateScreenSaverTimeoutLocked();
+ }
+ }
+
+ Runnable mScreenSaverActivator = new Runnable() {
+ public void run() {
+ synchronized (this) {
+ if (!(mScreenSaverEnabled && mScreenOn)) {
+ Log.w(TAG, "mScreenSaverActivator ran, but the screensaver should not be showing. Who's driving this thing?");
+ return;
+ }
+
+ if (localLOGV) Log.v(TAG, "mScreenSaverActivator entering dreamland");
+ try {
+ String component = Settings.System.getString(
+ mContext.getContentResolver(), Settings.Secure.DREAM_COMPONENT);
+ if (component != null) {
+ ComponentName cn = ComponentName.unflattenFromString(component);
+ Intent intent = new Intent(Intent.ACTION_MAIN)
+ .setComponent(cn)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+ | Intent.FLAG_ACTIVITY_NO_USER_ACTION
+ | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ mContext.startActivity(intent);
+ } else {
+ Log.e(TAG, "Couldn't start screen saver: none selected");
+ }
+ } catch (android.content.ActivityNotFoundException exc) {
+ // no screensaver? give up
+ Log.e(TAG, "Couldn't start screen saver: none installed");
+ }
+ }
+ }
+ };
+
+ // Must call while holding mLock
+ private void updateScreenSaverTimeoutLocked() {
+ synchronized (mScreenSaverActivator) {
+ mHandler.removeCallbacks(mScreenSaverActivator);
+ if (mScreenSaverEnabled && mScreenOn && mScreenSaverTimeout > 0) {
+ if (localLOGV)
+ Log.v(TAG, "scheduling screensaver for " + mScreenSaverTimeout + "ms from now");
+ mHandler.postDelayed(mScreenSaverActivator, mScreenSaverTimeout);
+ } else {
+ if (localLOGV) {
+ if (mScreenSaverTimeout == 0)
+ Log.v(TAG, "screen saver disabled by user");
+ else if (!mScreenOn)
+ Log.v(TAG, "screen saver disabled while screen off");
+ else
+ Log.v(TAG, "screen saver disabled by wakelock");
+ }
+ }
+ }
}
Runnable mScreenLockTimeout = new Runnable() {
@@ -3089,10 +3160,27 @@
return true;
}
+ public void screenOnStartedLw() {
+ // The window manager has just grabbed a wake lock. This is our cue to disable the screen
+ // saver.
+ synchronized (mLock) {
+ mScreenSaverEnabled = false;
+ }
+ }
+
public void screenOnStoppedLw() {
- if (!mKeyguardMediator.isShowingAndNotHidden() && mPowerManager.isScreenOn()) {
- long curTime = SystemClock.uptimeMillis();
- mPowerManager.userActivity(curTime, false, LocalPowerManager.OTHER_EVENT);
+ if (mPowerManager.isScreenOn()) {
+ if (!mKeyguardMediator.isShowingAndNotHidden()) {
+ long curTime = SystemClock.uptimeMillis();
+ mPowerManager.userActivity(curTime, false, LocalPowerManager.OTHER_EVENT);
+ }
+
+ synchronized (mLock) {
+ // even if the keyguard is up, now that all the wakelocks have been released, we
+ // should re-enable the screen saver
+ mScreenSaverEnabled = true;
+ updateScreenSaverTimeoutLocked();
+ }
}
}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 79dbfd6..08fea1b 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -8297,6 +8297,7 @@
boolean state = mHoldingScreenWakeLock.isHeld();
if (holding != state) {
if (holding) {
+ mPolicy.screenOnStartedLw();
mHoldingScreenWakeLock.acquire();
} else {
mPolicy.screenOnStoppedLw();