summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityManagerInternal.java21
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java54
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java34
3 files changed, 103 insertions, 6 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index d56dc1e07f52..bde8f3978222 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -16,6 +16,8 @@
package android.app;
+import android.annotation.NonNull;
+
/**
* Activity manager local system service interface.
*
@@ -27,4 +29,23 @@ public abstract class ActivityManagerInternal {
public abstract int startIsolatedProcess(String entryPoint, String[] mainArgs,
String processName, String abiOverride, int uid, Runnable crashHandler);
+
+ /**
+ * Acquires a sleep token with the specified tag.
+ *
+ * @param tag A string identifying the purpose of the token (eg. "Dream").
+ */
+ public abstract SleepToken acquireSleepToken(@NonNull String tag);
+
+ /**
+ * Sleep tokens cause the activity manager to put the top activity to sleep.
+ * They are used by components such as dreams that may hide and block interaction
+ * with underlying activities.
+ */
+ public static abstract class SleepToken {
+ /**
+ * Releases the sleep token.
+ */
+ public abstract void release();
+ }
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b65893274c13..15d675672ba5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -114,6 +114,7 @@ import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManager.StackInfo;
import android.app.ActivityManagerInternal;
+import android.app.ActivityManagerInternal.SleepToken;
import android.app.ActivityManagerNative;
import android.app.ActivityOptions;
import android.app.ActivityThread;
@@ -1013,6 +1014,13 @@ public final class ActivityManagerService extends ActivityManagerNative
*/
private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
+ /**
+ * A list of tokens that cause the top activity to be put to sleep.
+ * They are used by components that may hide and block interaction with underlying
+ * activities.
+ */
+ final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
+
static final int LOCK_SCREEN_HIDDEN = 0;
static final int LOCK_SCREEN_LEAVING = 1;
static final int LOCK_SCREEN_SHOWN = 2;
@@ -9813,15 +9821,14 @@ public final class ActivityManagerService extends ActivityManagerNative
return false;
}
+ // TODO: Transform the lock screen state into a sleep token instead.
switch (mWakefulness) {
case PowerManagerInternal.WAKEFULNESS_AWAKE:
case PowerManagerInternal.WAKEFULNESS_DREAMING:
- // If we're interactive but applications are already paused then defer
- // resuming them until the lock screen is hidden.
- return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
case PowerManagerInternal.WAKEFULNESS_DOZING:
- // If we're dozing then pause applications whenever the lock screen is shown.
- return mLockScreenShown != LOCK_SCREEN_HIDDEN;
+ // Pause applications whenever the lock screen is shown or any sleep
+ // tokens have been acquired.
+ return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
case PowerManagerInternal.WAKEFULNESS_ASLEEP:
default:
// If we're asleep then pause applications unconditionally.
@@ -12950,6 +12957,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (dumpPackage == null) {
pw.println(" mWakefulness="
+ PowerManagerInternal.wakefulnessToString(mWakefulness));
+ pw.println(" mSleepTokens=" + mSleepTokens);
pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
+ lockScreenShownToString());
pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
@@ -19723,6 +19731,42 @@ public final class ActivityManagerService extends ActivityManagerNative
return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
processName, abiOverride, uid, crashHandler);
}
+
+ @Override
+ public SleepToken acquireSleepToken(String tag) {
+ Preconditions.checkNotNull(tag);
+
+ synchronized (ActivityManagerService.this) {
+ SleepTokenImpl token = new SleepTokenImpl(tag);
+ mSleepTokens.add(token);
+ updateSleepIfNeededLocked();
+ return token;
+ }
+ }
+ }
+
+ private final class SleepTokenImpl extends SleepToken {
+ private final String mTag;
+ private final long mAcquireTime;
+
+ public SleepTokenImpl(String tag) {
+ mTag = tag;
+ mAcquireTime = SystemClock.uptimeMillis();
+ }
+
+ @Override
+ public void release() {
+ synchronized (ActivityManagerService.this) {
+ if (mSleepTokens.remove(this)) {
+ updateSleepIfNeededLocked();
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
+ }
}
/**
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index ad85b5997301..25857c5d5062 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -17,6 +17,8 @@
package com.android.server.policy;
import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
+import android.app.ActivityManagerInternal.SleepToken;
import android.app.ActivityManagerNative;
import android.app.AppOpsManager;
import android.app.IUiModeManager;
@@ -252,6 +254,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
WindowManagerFuncs mWindowManagerFuncs;
WindowManagerInternal mWindowManagerInternal;
PowerManager mPowerManager;
+ ActivityManagerInternal mActivityManagerInternal;
DreamManagerInternal mDreamManagerInternal;
IStatusBarService mStatusBarService;
boolean mPreloadedRecentApps;
@@ -493,6 +496,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean mShowingLockscreen;
boolean mShowingDream;
boolean mDreamingLockscreen;
+ boolean mDreamingSleepTokenNeeded;
+ SleepToken mDreamingSleepToken;
boolean mKeyguardSecure;
boolean mKeyguardSecureIncludingHidden;
volatile boolean mKeyguardOccluded;
@@ -599,6 +604,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private static final int MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK = 12;
private static final int MSG_POWER_DELAYED_PRESS = 13;
private static final int MSG_POWER_LONG_PRESS = 14;
+ private static final int MSG_UPDATE_DREAMING_SLEEP_TOKEN = 15;
private class PolicyHandler extends Handler {
@Override
@@ -647,6 +653,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case MSG_POWER_LONG_PRESS:
powerLongPress();
break;
+ case MSG_UPDATE_DREAMING_SLEEP_TOKEN:
+ updateDreamingSleepToken(msg.arg1 != 0);
+ break;
}
}
}
@@ -1220,6 +1229,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mWindowManager = windowManager;
mWindowManagerFuncs = windowManagerFuncs;
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
+ mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
// Init display burn-in protection
@@ -4239,6 +4249,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// while the dream is showing.
if (!mShowingDream) {
mDreamingLockscreen = mShowingLockscreen;
+ if (mDreamingSleepTokenNeeded) {
+ mDreamingSleepTokenNeeded = false;
+ mHandler.obtainMessage(MSG_UPDATE_DREAMING_SLEEP_TOKEN, 0, 1).sendToTarget();
+ }
+ } else {
+ if (!mDreamingSleepTokenNeeded) {
+ mDreamingSleepTokenNeeded = true;
+ mHandler.obtainMessage(MSG_UPDATE_DREAMING_SLEEP_TOKEN, 1, 1).sendToTarget();
+ }
}
if (mStatusBar != null) {
@@ -5851,6 +5870,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
+ private void updateDreamingSleepToken(boolean acquire) {
+ if (acquire) {
+ if (mDreamingSleepToken == null) {
+ mDreamingSleepToken = mActivityManagerInternal.acquireSleepToken("Dream");
+ }
+ } else {
+ if (mDreamingSleepToken != null) {
+ mDreamingSleepToken.release();
+ }
+ }
+ }
+
/** {@inheritDoc} */
@Override
public void enableScreenAfterBoot() {
@@ -6487,7 +6518,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
pw.print(" mStatusBarLayer="); pw.println(mStatusBarLayer);
pw.print(prefix); pw.print("mShowingLockscreen="); pw.print(mShowingLockscreen);
pw.print(" mShowingDream="); pw.print(mShowingDream);
- pw.print(" mDreamingLockscreen="); pw.println(mDreamingLockscreen);
+ pw.print(" mDreamingLockscreen="); pw.print(mDreamingLockscreen);
+ pw.print(" mDreamingSleepToken="); pw.println(mDreamingSleepToken);
if (mLastInputMethodWindow != null) {
pw.print(prefix); pw.print("mLastInputMethodWindow=");
pw.println(mLastInputMethodWindow);