summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java52
-rw-r--r--services/core/java/com/android/server/wm/ActivityStackSupervisor.java13
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java9
-rw-r--r--services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java124
-rw-r--r--services/core/java/com/android/server/wm/KeyguardController.java58
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java14
-rw-r--r--services/core/java/com/android/server/wm/Task.java89
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java7
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java5
13 files changed, 237 insertions, 148 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index e79587776412..ad281247a719 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -4628,18 +4628,26 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(this);
}
- /** @return {@code true} if this activity should be made visible. */
- boolean shouldBeVisible(boolean behindFullscreenActivity, boolean ignoringKeyguard) {
+ private void updateVisibleIgnoringKeyguard(boolean behindFullscreenActivity) {
// Check whether activity should be visible without Keyguard influence
visibleIgnoringKeyguard = (!behindFullscreenActivity || mLaunchTaskBehind)
&& okToShowLocked();
+ }
+
+ /** @return {@code true} if this activity should be made visible. */
+ private boolean shouldBeVisible(boolean behindFullscreenActivity, boolean ignoringKeyguard) {
+ updateVisibleIgnoringKeyguard(behindFullscreenActivity);
if (ignoringKeyguard) {
return visibleIgnoringKeyguard;
}
+ return shouldBeVisibleUnchecked();
+ }
+
+ boolean shouldBeVisibleUnchecked() {
final Task stack = getRootTask();
- if (stack == null) {
+ if (stack == null || !visibleIgnoringKeyguard) {
return false;
}
@@ -4652,26 +4660,30 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return false;
}
- // Check if the activity is on a sleeping display, and if it can turn it ON.
- if (mDisplayContent.isSleeping()) {
- final boolean canTurnScreenOn = !mSetToSleep || canTurnScreenOn()
- || canShowWhenLocked() || containsDismissKeyguardWindow();
- if (!canTurnScreenOn) {
- return false;
- }
+ // Check if the activity is on a sleeping display
+ // TODO b/163993448 mSetToSleep is required when restarting an existing activity, try to
+ // remove it if possible.
+ if (mSetToSleep && mDisplayContent.isSleeping()) {
+ return false;
}
+ return mStackSupervisor.getKeyguardController().checkKeyguardVisibility(this);
+ }
+
+ void updateVisibility(boolean behindFullscreenActivity) {
+ updateVisibleIgnoringKeyguard(behindFullscreenActivity);
+ final Task task = getRootTask();
+ if (task == null || !visibleIgnoringKeyguard) {
+ return;
+ }
// Now check whether it's really visible depending on Keyguard state, and update
// {@link ActivityStack} internal states.
// Inform the method if this activity is the top activity of this stack, but exclude the
// case where this is the top activity in a pinned stack.
- final boolean isTop = this == stack.getTopNonFinishingActivity();
- final boolean isTopNotPinnedStack = stack.isAttached()
- && stack.getDisplayArea().isTopNotFinishNotPinnedStack(stack);
- final boolean visibleIgnoringDisplayStatus = stack.checkKeyguardVisibility(this,
- visibleIgnoringKeyguard, isTop && isTopNotPinnedStack);
-
- return visibleIgnoringDisplayStatus;
+ final boolean isTop = this == task.getTopNonFinishingActivity();
+ final boolean isTopNotPinnedStack = task.isAttached()
+ && task.getDisplayArea().isTopNotFinishNotPinnedStack(task);
+ task.updateKeyguardVisibility(this, isTop && isTopNotPinnedStack);
}
boolean shouldBeVisible() {
@@ -7537,10 +7549,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return false;
}
final Task stack = getRootTask();
- return stack != null
- && !stack.inMultiWindowMode()
- && stack.checkKeyguardVisibility(this, true /* shouldBeVisible */,
- stack.topRunningActivity() == this /* isTop */);
+ return stack != null && !stack.inMultiWindowMode()
+ && mStackSupervisor.getKeyguardController().checkKeyguardVisibility(this);
}
void setTurnScreenOn(boolean turnScreenOn) {
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 9df192b76f9a..5196416e2cd3 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -759,8 +759,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
false /* markFrozenIfConfigChanged */, true /* deferResume */);
}
- if (r.getRootTask().checkKeyguardVisibility(r, true /* shouldBeVisible */,
- true /* isTop */) && r.allowMoveToFront()) {
+ if (mKeyguardController.checkKeyguardVisibility(r) && r.allowMoveToFront()) {
// We only set the visibility to true if the activity is not being launched in
// background, and is allowed to be visible based on keyguard state. This avoids
// setting this into motion in window manager that is later cancelled due to later
@@ -2298,11 +2297,15 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
}
/** Ends a batch of visibility updates. */
- void endActivityVisibilityUpdate() {
- mVisibilityTransactionDepth--;
- if (mVisibilityTransactionDepth == 0) {
+ void endActivityVisibilityUpdate(ActivityRecord starting, int configChanges,
+ boolean preserveWindows, boolean notifyClients) {
+ if (mVisibilityTransactionDepth == 1) {
getKeyguardController().visibilitiesUpdated();
+ // commit visibility to activities
+ mRootWindowContainer.commitActivitiesVisible(starting, configChanges, preserveWindows,
+ notifyClients);
}
+ mVisibilityTransactionDepth--;
}
/** Returns {@code true} if the caller is on the path to update visibility. */
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index c96509e5ef51..4db121b6ea33 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -35,6 +35,7 @@ import static android.os.Build.VERSION_CODES.N;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.util.DisplayMetrics.DENSITY_DEFAULT;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
import static android.view.Display.FLAG_PRIVATE;
import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
import static android.view.Display.INVALID_DISPLAY;
@@ -5271,6 +5272,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mSingleTaskInstance = true;
}
+ /**
+ * Check if the display has {@link Display#FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD} applied.
+ */
+ boolean canShowWithInsecureKeyguard() {
+ final int flags = mDisplay.getFlags();
+ return (flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0;
+ }
+
/** Returns true if the display can only contain one task */
boolean isSingleTaskInstance() {
return mSingleTaskInstance;
diff --git a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
index e2c07491db01..251c01469c6a 100644
--- a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
+++ b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
@@ -22,12 +22,9 @@ import static com.android.server.wm.Task.TAG_VISIBILITY;
import android.annotation.Nullable;
import android.util.Slog;
-import com.android.internal.util.function.pooled.PooledConsumer;
-import com.android.internal.util.function.pooled.PooledLambda;
-
/** Helper class to ensure activities are in the right visible state for a container. */
class EnsureActivitiesVisibleHelper {
- private final Task mContiner;
+ private final Task mTask;
private ActivityRecord mTop;
private ActivityRecord mStarting;
private boolean mAboveTop;
@@ -38,11 +35,11 @@ class EnsureActivitiesVisibleHelper {
private boolean mNotifyClients;
EnsureActivitiesVisibleHelper(Task container) {
- mContiner = container;
+ mTask = container;
}
/**
- * Update all attributes except {@link mContiner} to use in subsequent calculations.
+ * Update all attributes except {@link mTask} to use in subsequent calculations.
*
* @param starting The activity that is being started
* @param configChanges Parts of the configuration that changed for this activity for evaluating
@@ -54,11 +51,11 @@ class EnsureActivitiesVisibleHelper {
void reset(ActivityRecord starting, int configChanges, boolean preserveWindows,
boolean notifyClients) {
mStarting = starting;
- mTop = mContiner.topRunningActivity();
+ mTop = mTask.topRunningActivity();
// If the top activity is not fullscreen, then we need to make sure any activities under it
// are now visible.
mAboveTop = mTop != null;
- mContainerShouldBeVisible = mContiner.shouldBeVisible(mStarting);
+ mContainerShouldBeVisible = mTask.shouldBeVisible(mStarting);
mBehindFullscreenActivity = !mContainerShouldBeVisible;
mConfigChanges = configChanges;
mPreserveWindows = preserveWindows;
@@ -66,7 +63,26 @@ class EnsureActivitiesVisibleHelper {
}
/**
- * Ensure visibility with an option to also update the configuration of visible activities.
+ * Update visibility to activities.
+ * @see Task#ensureActivitiesVisible(ActivityRecord, int, boolean)
+ * @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean)
+ * @param starting The top most activity in the task.
+ * The activity is either starting or resuming.
+ * Caller should ensure starting activity is visible.
+ *
+ */
+ void processUpdate(@Nullable ActivityRecord starting) {
+ reset(starting, 0 /* configChanges */, false /* preserveWindows */,
+ false /* notifyClients */);
+ if (DEBUG_VISIBILITY) {
+ Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible processUpdate behind " + mTop);
+ }
+
+ mTask.forAllActivities(this::updateActivityVisibility);
+ }
+
+ /**
+ * Commit visibility with an option to also update the configuration of visible activities.
* @see Task#ensureActivitiesVisible(ActivityRecord, int, boolean)
* @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean)
* @param starting The top most activity in the task.
@@ -79,54 +95,84 @@ class EnsureActivitiesVisibleHelper {
* @param notifyClients Flag indicating whether the configuration and visibility changes shoulc
* be sent to the clients.
*/
- void process(@Nullable ActivityRecord starting, int configChanges, boolean preserveWindows,
- boolean notifyClients) {
+ void processCommit(ActivityRecord starting, int configChanges,
+ boolean preserveWindows, boolean notifyClients) {
reset(starting, configChanges, preserveWindows, notifyClients);
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + mTop
- + " configChanges=0x" + Integer.toHexString(configChanges));
+ if (DEBUG_VISIBILITY) {
+ Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible processCommit behind " + mTop);
+ }
if (mTop != null) {
- mContiner.checkTranslucentActivityWaiting(mTop);
+ mTask.checkTranslucentActivityWaiting(mTop);
}
// We should not resume activities that being launched behind because these
// activities are actually behind other fullscreen activities, but still required
// to be visible (such as performing Recents animation).
final boolean resumeTopActivity = mTop != null && !mTop.mLaunchTaskBehind
- && mContiner.isTopActivityFocusable()
- && (starting == null || !starting.isDescendantOf(mContiner));
-
- final PooledConsumer f = PooledLambda.obtainConsumer(
- EnsureActivitiesVisibleHelper::setActivityVisibilityState, this,
- PooledLambda.__(ActivityRecord.class), starting, resumeTopActivity);
- mContiner.forAllActivities(f);
- f.recycle();
+ && mTask.isTopActivityFocusable()
+ && (starting == null || !starting.isDescendantOf(mTask));
+
+ mTask.forAllActivities(a -> {
+ commitActivityVisibility(a, starting, resumeTopActivity);
+ });
}
- private void setActivityVisibilityState(ActivityRecord r, ActivityRecord starting,
- final boolean resumeTopActivity) {
- final boolean isTop = r == mTop;
+ private boolean isAboveTop(boolean isTop) {
if (mAboveTop && !isTop) {
- return;
+ return true;
}
mAboveTop = false;
+ return false;
+ }
+
+ private void updateActivityVisibility(ActivityRecord r) {
+ final boolean isTop = r == mTop;
+ if (isAboveTop(isTop)) {
+ return;
+ }
- final boolean reallyVisible = r.shouldBeVisible(
- mBehindFullscreenActivity, false /* ignoringKeyguard */);
+ r.updateVisibility(mBehindFullscreenActivity);
// Check whether activity should be visible without Keyguard influence
if (r.visibleIgnoringKeyguard) {
if (r.occludesParent()) {
// At this point, nothing else needs to be shown in this task.
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r
- + " stackVisible=" + mContainerShouldBeVisible
- + " behindFullscreen=" + mBehindFullscreenActivity);
+ if (DEBUG_VISIBILITY) {
+ Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r
+ + " stackVisible=" + mContainerShouldBeVisible
+ + " behindFullscreen=" + mBehindFullscreenActivity);
+ }
mBehindFullscreenActivity = true;
} else {
mBehindFullscreenActivity = false;
}
}
+ if (!mBehindFullscreenActivity && mTask.isActivityTypeHome() && r.isRootOfTask()) {
+ if (DEBUG_VISIBILITY) {
+ Slog.v(TAG_VISIBILITY, "Home task: at " + mTask
+ + " stackShouldBeVisible=" + mContainerShouldBeVisible
+ + " behindFullscreenActivity=" + mBehindFullscreenActivity);
+ }
+ // No other task in the home stack should be visible behind the home activity.
+ // Home activities is usually a translucent activity with the wallpaper behind
+ // them. However, when they don't have the wallpaper behind them, we want to
+ // show activities in the next application stack behind them vs. another
+ // task in the home stack like recents.
+ mBehindFullscreenActivity = true;
+ }
+ }
+
+ private void commitActivityVisibility(ActivityRecord r, ActivityRecord starting,
+ final boolean resumeTopActivity) {
+ final boolean isTop = r == mTop;
+ if (isAboveTop(isTop)) {
+ return;
+ }
+
+ final boolean reallyVisible = r.shouldBeVisibleUnchecked();
+
if (reallyVisible) {
if (r.finishing) {
return;
@@ -170,20 +216,6 @@ class EnsureActivitiesVisibleHelper {
+ " mLaunchTaskBehind=" + r.mLaunchTaskBehind);
r.makeInvisible();
}
-
- final int windowingMode = mContiner.getWindowingMode();
- if (!mBehindFullscreenActivity && mContiner.isActivityTypeHome()
- && r.isRootOfTask()) {
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + mContiner
- + " stackShouldBeVisible=" + mContainerShouldBeVisible
- + " behindFullscreenActivity=" + mBehindFullscreenActivity);
- // No other task in the home stack should be visible behind the home activity.
- // Home activities is usually a translucent activity with the wallpaper behind
- // them. However, when they don't have the wallpaper behind them, we want to
- // show activities in the next application stack behind them vs. another
- // task in the home stack like recents.
- mBehindFullscreenActivity = true;
- }
}
private void makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
@@ -207,7 +239,7 @@ class EnsureActivitiesVisibleHelper {
r.setVisibility(true);
}
if (r != starting) {
- mContiner.mStackSupervisor.startSpecificActivity(r, andResume, true /* checkConfig */);
+ mTask.mStackSupervisor.startSpecificActivity(r, andResume, true /* checkConfig */);
}
}
}
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 69e8c57a489c..bad28ba333ba 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -278,6 +278,27 @@ class KeyguardController {
}
/**
+ * Checks whether {@param r} should be visible depending on Keyguard state.
+ *
+ * @return true if {@param r} is visible taken Keyguard state into account, false otherwise
+ */
+ boolean checkKeyguardVisibility(ActivityRecord r) {
+ if (r.mDisplayContent.canShowWithInsecureKeyguard() && canDismissKeyguard()) {
+ return true;
+ }
+
+ if (isKeyguardOrAodShowing(r.mDisplayContent.getDisplayId())) {
+ // If keyguard is showing, nothing is visible, except if we are able to dismiss Keyguard
+ // right away and AOD isn't visible.
+ return canShowActivityWhileKeyguardShowing(r, r.containsDismissKeyguardWindow());
+ } else if (isKeyguardLocked()) {
+ return canShowWhileOccluded(r.containsDismissKeyguardWindow(), r.canShowWhenLocked());
+ } else {
+ return true;
+ }
+ }
+
+ /**
* Makes sure to update lockscreen occluded/dismiss state if needed after completing all
* visibility updates ({@link ActivityStackSupervisor#endActivityVisibilityUpdate}).
*/
@@ -442,6 +463,7 @@ class KeyguardController {
private final int mDisplayId;
private boolean mOccluded;
private ActivityRecord mDismissingKeyguardActivity;
+ private ActivityRecord mTopTurnScreenOnActivity;
private boolean mRequestDismissKeyguard;
private final ActivityTaskManagerService mService;
private final ActivityTaskManagerInternal.SleepTokenAcquirer mSleepTokenAcquirer;
@@ -455,30 +477,38 @@ class KeyguardController {
void onRemoved() {
mDismissingKeyguardActivity = null;
+ mTopTurnScreenOnActivity = null;
mSleepTokenAcquirer.release(mDisplayId);
}
void visibilitiesUpdated(KeyguardController controller, DisplayContent display) {
final boolean lastOccluded = mOccluded;
final ActivityRecord lastDismissActivity = mDismissingKeyguardActivity;
+ final ActivityRecord lastTurnScreenOnActivity = mTopTurnScreenOnActivity;
mRequestDismissKeyguard = false;
mOccluded = false;
mDismissingKeyguardActivity = null;
+ mTopTurnScreenOnActivity = null;
+ // only top + focusable + visible task can control occluding.
final Task stack = getStackForControllingOccluding(display);
if (stack != null) {
final ActivityRecord topDismissing = stack.getTopDismissingKeyguardActivity();
+ final ActivityRecord topTurnScreenOn = stack.getTopTurnScreenOnActivity();
mOccluded = stack.topActivityOccludesKeyguard() || (topDismissing != null
&& stack.topRunningActivity() == topDismissing
&& controller.canShowWhileOccluded(
true /* dismissKeyguard */,
false /* showWhenLocked */));
- if (stack.getTopDismissingKeyguardActivity() != null) {
- mDismissingKeyguardActivity = stack.getTopDismissingKeyguardActivity();
+ if (topDismissing != null) {
+ mDismissingKeyguardActivity = topDismissing;
+ }
+ if (topTurnScreenOn != null) {
+ mTopTurnScreenOnActivity = topTurnScreenOn;
}
// FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD only apply for secondary display.
- if (mDisplayId != DEFAULT_DISPLAY) {
- mOccluded |= stack.canShowWithInsecureKeyguard()
+ if (mDisplayId != DEFAULT_DISPLAY && stack.mDisplayContent != null) {
+ mOccluded |= stack.mDisplayContent.canShowWithInsecureKeyguard()
&& controller.canDismissKeyguard();
}
}
@@ -488,14 +518,20 @@ class KeyguardController {
.getDisplayPolicy().isShowingDreamLw();
}
- if (lastOccluded != mOccluded) {
- controller.handleOccludedChanged(mDisplayId);
- }
- if (lastDismissActivity != mDismissingKeyguardActivity && !mOccluded
+ mRequestDismissKeyguard = lastDismissActivity != mDismissingKeyguardActivity
+ && !mOccluded
&& mDismissingKeyguardActivity != null
&& controller.mWindowManager.isKeyguardSecure(
- controller.mService.getCurrentUserId())) {
- mRequestDismissKeyguard = true;
+ controller.mService.getCurrentUserId());
+
+ if (mTopTurnScreenOnActivity != null
+ && mTopTurnScreenOnActivity != lastTurnScreenOnActivity
+ && !mService.mWindowManager.mPowerManager.isInteractive()) {
+ controller.mStackSupervisor.wakeUp("handleTurnScreenOn");
+ }
+
+ if (lastOccluded != mOccluded) {
+ controller.handleOccludedChanged(mDisplayId);
}
}
@@ -525,6 +561,8 @@ class KeyguardController {
sb.append(" Occluded=").append(mOccluded)
.append(" DismissingKeyguardActivity=")
.append(mDismissingKeyguardActivity)
+ .append(" TurnScreenOnActivity=")
+ .append(mTopTurnScreenOnActivity)
.append(" at display=")
.append(mDisplayId);
pw.println(sb.toString());
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index ee9886b4a98f..d149db6b676f 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -1983,10 +1983,22 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
notifyClients);
}
} finally {
- mStackSupervisor.endActivityVisibilityUpdate();
+ mStackSupervisor.endActivityVisibilityUpdate(starting, configChanges, preserveWindows,
+ notifyClients);
}
}
+ void commitActivitiesVisible(ActivityRecord starting, int configChanges,
+ boolean preserveWindows, boolean notifyClients) {
+ forAllTaskDisplayAreas(taskDisplayArea -> {
+ for (int stackNdx = taskDisplayArea.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
+ final Task task = taskDisplayArea.getStackAt(stackNdx);
+ task.commitActivitiesVisible(starting, configChanges, preserveWindows,
+ notifyClients);
+ }
+ });
+ }
+
boolean switchUser(int userId, UserState uss) {
final Task topFocusedStack = getTopDisplayFocusedStack();
final int focusStackId = topFocusedStack != null
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index bc607bf4175a..c4ca4cd637e3 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -61,7 +61,6 @@ import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.SurfaceControl.METADATA_TASK_ID;
import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
@@ -197,7 +196,6 @@ import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
-import android.view.Display;
import android.view.DisplayInfo;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationTarget;
@@ -600,6 +598,7 @@ class Task extends WindowContainer<WindowContainer> {
private boolean mTopActivityOccludesKeyguard;
private ActivityRecord mTopDismissingKeyguardActivity;
+ private ActivityRecord mTopTurnScreenOnActivity;
private static final int TRANSLUCENT_TIMEOUT_MSG = FIRST_ACTIVITY_STACK_MSG + 1;
@@ -5664,21 +5663,29 @@ class Task extends WindowContainer<WindowContainer> {
boolean preserveWindows, boolean notifyClients) {
mTopActivityOccludesKeyguard = false;
mTopDismissingKeyguardActivity = null;
+ mTopTurnScreenOnActivity = null;
mStackSupervisor.beginActivityVisibilityUpdate();
try {
- mEnsureActivitiesVisibleHelper.process(
- starting, configChanges, preserveWindows, notifyClients);
+ mEnsureActivitiesVisibleHelper.processUpdate(starting);
if (mTranslucentActivityWaiting != null &&
mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
- // Nothing is getting drawn or everything was already visible, don't wait for timeout.
+ // Nothing is getting drawn or everything was already visible, don't wait for
+ // timeout.
notifyActivityDrawnLocked(null);
}
} finally {
- mStackSupervisor.endActivityVisibilityUpdate();
+ mStackSupervisor.endActivityVisibilityUpdate(starting, configChanges, preserveWindows,
+ notifyClients);
}
}
+ void commitActivitiesVisible(ActivityRecord starting, int configChanges,
+ boolean preserveWindows, boolean notifyClients) {
+ mEnsureActivitiesVisibleHelper.processCommit(starting, configChanges, preserveWindows,
+ notifyClients);
+ }
+
/**
* @return true if the top visible activity wants to occlude the Keyguard, false otherwise
*/
@@ -5712,64 +5719,34 @@ class Task extends WindowContainer<WindowContainer> {
}
/**
- * Checks whether {@param r} should be visible depending on Keyguard state and updates
- * {@link #mTopActivityOccludesKeyguard} and {@link #mTopDismissingKeyguardActivity} if
- * necessary.
- *
- * @return true if {@param r} is visible taken Keyguard state into account, false otherwise
+ * @return the top most visible activity that wants to turn screen on
*/
- boolean checkKeyguardVisibility(ActivityRecord r, boolean shouldBeVisible, boolean isTop) {
- int displayId = getDisplayId();
- if (displayId == INVALID_DISPLAY) displayId = DEFAULT_DISPLAY;
+ ActivityRecord getTopTurnScreenOnActivity() {
+ return mTopTurnScreenOnActivity;
+ }
- final boolean keyguardOrAodShowing = mStackSupervisor.getKeyguardController()
- .isKeyguardOrAodShowing(displayId);
- final boolean keyguardLocked = mStackSupervisor.getKeyguardController().isKeyguardLocked();
+ /**
+ * Updates {@link #mTopActivityOccludesKeyguard}, {@link #mTopTurnScreenOnActivity} and
+ * {@link #mTopDismissingKeyguardActivity} if this task could be visible.
+ *
+ */
+ void updateKeyguardVisibility(ActivityRecord r, boolean isTop) {
final boolean showWhenLocked = r.canShowWhenLocked();
final boolean dismissKeyguard = r.containsDismissKeyguardWindow();
- if (shouldBeVisible) {
- if (dismissKeyguard && mTopDismissingKeyguardActivity == null) {
- mTopDismissingKeyguardActivity = r;
- }
-
- // Only the top activity may control occluded, as we can't occlude the Keyguard if the
- // top app doesn't want to occlude it.
- if (isTop) {
- mTopActivityOccludesKeyguard |= showWhenLocked;
- }
-
- final boolean canShowWithKeyguard = canShowWithInsecureKeyguard()
- && mStackSupervisor.getKeyguardController().canDismissKeyguard();
- if (canShowWithKeyguard) {
- return true;
- }
- }
- if (keyguardOrAodShowing) {
- // If keyguard is showing, nothing is visible, except if we are able to dismiss Keyguard
- // right away and AOD isn't visible.
- return shouldBeVisible && mStackSupervisor.getKeyguardController()
- .canShowActivityWhileKeyguardShowing(r, dismissKeyguard);
- } else if (keyguardLocked) {
- return shouldBeVisible && mStackSupervisor.getKeyguardController().canShowWhileOccluded(
- dismissKeyguard, showWhenLocked);
- } else {
- return shouldBeVisible;
+ final boolean turnScreenOn = r.canTurnScreenOn();
+ if (dismissKeyguard && mTopDismissingKeyguardActivity == null) {
+ mTopDismissingKeyguardActivity = r;
}
- }
- /**
- * Check if the display to which this stack is attached has
- * {@link Display#FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD} applied.
- */
- boolean canShowWithInsecureKeyguard() {
- final DisplayContent displayContent = mDisplayContent;
- if (displayContent == null) {
- throw new IllegalStateException("Stack is not attached to any display, stackId="
- + getRootTaskId());
+ if (turnScreenOn && mTopTurnScreenOnActivity == null) {
+ mTopTurnScreenOnActivity = r;
}
- final int flags = displayContent.mDisplay.getFlags();
- return (flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0;
+ // Only the top activity may control occluded, as we can't occlude the Keyguard if the
+ // top app doesn't want to occlude it.
+ if (isTop) {
+ mTopActivityOccludesKeyguard |= showWhenLocked;
+ }
}
void checkTranslucentActivityWaiting(ActivityRecord top) {
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 6550167683a0..2b32e40f7332 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -1779,7 +1779,8 @@ final class TaskDisplayArea extends DisplayArea<Task> {
notifyClients);
}
} finally {
- mAtmService.mStackSupervisor.endActivityVisibilityUpdate();
+ mAtmService.mStackSupervisor.endActivityVisibilityUpdate(starting, configChanges,
+ preserveWindows, notifyClients);
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 09375db01888..89a0c7c4885e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -73,7 +73,6 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
@@ -1671,8 +1670,6 @@ public class ActivityRecordTests extends WindowTestsBase {
@Test
public void testCanTurnScreenOn() {
mStack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
- doReturn(true).when(mStack).checkKeyguardVisibility(
- same(mActivity), eq(true) /* shouldBeVisible */, anyBoolean());
doReturn(true).when(mActivity).getTurnScreenOnFlag();
assertTrue(mActivity.canTurnScreenOn());
@@ -1681,8 +1678,6 @@ public class ActivityRecordTests extends WindowTestsBase {
@Test
public void testFreeformWindowCantTurnScreenOn() {
mStack.setWindowingMode(WINDOWING_MODE_FREEFORM);
- doReturn(true).when(mStack).checkKeyguardVisibility(
- same(mActivity), eq(true) /* shouldBeVisible */, anyBoolean());
doReturn(true).when(mActivity).getTurnScreenOnFlag();
assertFalse(mActivity.canTurnScreenOn());
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index 4951658bbd78..a60f93a3b14a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -1410,7 +1410,7 @@ public class ActivityStackTests extends WindowTestsBase {
new ActivityBuilder(mAtm).setTask(mTask).build();
new ActivityBuilder(mAtm).setTask(mTask).build();
doReturn(false).when(nonTopVisibleActivity).attachedToProcess();
- doReturn(true).when(nonTopVisibleActivity).shouldBeVisible(anyBoolean(), anyBoolean());
+ doReturn(true).when(nonTopVisibleActivity).shouldBeVisibleUnchecked();
doNothing().when(mSupervisor).startSpecificActivity(any(), anyBoolean(),
anyBoolean());
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 2791234031da..89a34cfc77f3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -823,7 +823,14 @@ public class DisplayContentTests extends WindowTestsBase {
final DisplayContent newDisplay = createNewDisplay();
final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
+ final Task stack = mDisplayContent.getTopStack();
+ final ActivityRecord activity = stack.topRunningActivity();
+ doReturn(true).when(activity).shouldBeVisibleUnchecked();
+
final WindowState appWin1 = createWindow(null, TYPE_APPLICATION, newDisplay, "appWin1");
+ final Task stack1 = newDisplay.getTopStack();
+ final ActivityRecord activity1 = stack1.topRunningActivity();
+ doReturn(true).when(activity1).shouldBeVisibleUnchecked();
appWin.setHasSurface(true);
appWin1.setHasSurface(true);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index f4f172d8e5b5..58d994c6cae3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -44,6 +44,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
@@ -291,7 +292,8 @@ public class RecentTasksTest extends WindowTestsBase {
mRecentTasks.add(mTasks.get(1));
invocation.callRealMethod();
return null;
- }).when(mSupervisor).endActivityVisibilityUpdate();
+ }).when(mSupervisor).endActivityVisibilityUpdate(any(), anyInt(), anyBoolean(),
+ anyBoolean());
mTaskContainer.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
false /* preserveWindows */, false /* notifyClients */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index eb7d9c2d3c32..6a29c5b5424a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -534,11 +534,14 @@ public class SystemServicesTestRule implements TestRule {
doNothing().when(this).scheduleIdleTimeout(any());
// unit test version does not handle launch wake lock
doNothing().when(this).acquireLaunchWakelock();
- doReturn(mock(KeyguardController.class)).when(this).getKeyguardController();
mLaunchingActivityWakeLock = mock(PowerManager.WakeLock.class);
initialize();
+
+ final KeyguardController controller = getKeyguardController();
+ spyOn(controller);
+ doReturn(true).when(controller).checkKeyguardVisibility(any());
}
}