summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java4
-rw-r--r--services/core/java/com/android/server/wm/ActivityStack.java104
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java5
-rw-r--r--services/core/java/com/android/server/wm/Task.java27
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java34
5 files changed, 49 insertions, 125 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index c687bbf107b2..a87fe615e4df 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -4605,8 +4605,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return false;
}
- final boolean behindFullscreenActivity = stack.checkBehindFullscreenActivity(
- this, null /* handleBehindFullscreenActivity */);
+ final boolean behindFullscreenActivity = !stack.shouldBeVisible(null /* starting */)
+ || stack.getOccludingActivityAbove(this) != null;
return shouldBeVisible(behindFullscreenActivity, false /* ignoringKeyguard */);
}
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 601d64b24439..ea9aab71bcb0 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -328,81 +328,6 @@ class ActivityStack extends Task {
}
}
- private final CheckBehindFullscreenActivityHelper mCheckBehindFullscreenActivityHelper =
- new CheckBehindFullscreenActivityHelper();
- private class CheckBehindFullscreenActivityHelper {
- private boolean mAboveTop;
- private boolean mBehindFullscreenActivity;
- private ActivityRecord mToCheck;
- private Consumer<ActivityRecord> mHandleBehindFullscreenActivity;
- private boolean mHandlingOccluded;
-
- private void reset(ActivityRecord toCheck,
- Consumer<ActivityRecord> handleBehindFullscreenActivity) {
- mToCheck = toCheck;
- mHandleBehindFullscreenActivity = handleBehindFullscreenActivity;
- mAboveTop = true;
- mBehindFullscreenActivity = false;
-
- if (!shouldBeVisible(null)) {
- // The stack is not visible, so no activity in it should be displaying a starting
- // window. Mark all activities below top and behind fullscreen.
- mAboveTop = false;
- mBehindFullscreenActivity = true;
- }
-
- mHandlingOccluded = mToCheck == null && mHandleBehindFullscreenActivity != null;
- }
-
- boolean process(ActivityRecord toCheck,
- Consumer<ActivityRecord> handleBehindFullscreenActivity) {
- reset(toCheck, handleBehindFullscreenActivity);
-
- if (!mHandlingOccluded && mBehindFullscreenActivity) {
- return true;
- }
-
- final ActivityRecord topActivity = topRunningActivity();
- final PooledFunction f = PooledLambda.obtainFunction(
- CheckBehindFullscreenActivityHelper::processActivity, this,
- PooledLambda.__(ActivityRecord.class), topActivity);
- forAllActivities(f);
- f.recycle();
-
- return mBehindFullscreenActivity;
- }
-
- /** Returns {@code true} to stop the outer loop and indicate the result is computed. */
- private boolean processActivity(ActivityRecord r, ActivityRecord topActivity) {
- if (mAboveTop) {
- if (r == topActivity) {
- if (r == mToCheck) {
- // It is the top activity in a visible stack.
- mBehindFullscreenActivity = false;
- return true;
- }
- mAboveTop = false;
- }
- mBehindFullscreenActivity |= r.occludesParent();
- return false;
- }
-
- if (mHandlingOccluded) {
- // Iterating through all occluded activities.
- if (mBehindFullscreenActivity) {
- mHandleBehindFullscreenActivity.accept(r);
- }
- } else if (r == mToCheck) {
- return true;
- } else if (mBehindFullscreenActivity) {
- // It is occluded before {@param toCheck} is found.
- return true;
- }
- mBehindFullscreenActivity |= r.occludesParent();
- return false;
- }
- }
-
// TODO: Can we just loop through WindowProcessController#mActivities instead of doing this?
private final RemoveHistoryRecordsForApp mRemoveHistoryRecordsForApp =
new RemoveHistoryRecordsForApp();
@@ -1434,25 +1359,6 @@ class ActivityStack extends Task {
}
}
- /** @see ActivityRecord#cancelInitializing() */
- void cancelInitializingActivities() {
- // We don't want to clear starting window for activities that aren't behind fullscreen
- // activities as we need to display their starting window until they are done initializing.
- checkBehindFullscreenActivity(null /* toCheck */, ActivityRecord::cancelInitializing);
- }
-
- /**
- * If an activity {@param toCheck} is given, this method returns {@code true} if the activity
- * is occluded by any fullscreen activity. If there is no {@param toCheck} and the handling
- * function {@param handleBehindFullscreenActivity} is given, this method will pass all occluded
- * activities to the function.
- */
- boolean checkBehindFullscreenActivity(ActivityRecord toCheck,
- Consumer<ActivityRecord> handleBehindFullscreenActivity) {
- return mCheckBehindFullscreenActivityHelper.process(
- toCheck, handleBehindFullscreenActivity);
- }
-
/**
* Ensure that the top activity in the stack is resumed.
*
@@ -2660,16 +2566,6 @@ class ActivityStack extends Task {
task.setBounds(task.isResizeable() ? bounds : null);
}
- /**
- * Returns the top-most activity that occludes the given one, or @{code null} if none.
- */
- @Nullable
- private ActivityRecord getOccludingActivityAbove(ActivityRecord activity) {
- ActivityRecord top = getActivity((ar) -> ar.occludesParent(),
- true /* traverseTopToBottom */, activity);
- return top != activity ? top : null;
- }
-
boolean willActivityBeVisible(IBinder token) {
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r == null) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 8bc98ce2d2d3..40f8fab510ba 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -3353,7 +3353,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
void cancelInitializingActivities() {
forAllTaskDisplayAreas(taskDisplayArea -> {
for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
- taskDisplayArea.getStackAt(sNdx).cancelInitializingActivities();
+ // We don't want to clear starting window for activities that aren't occluded
+ // as we need to display their starting window until they are done initializing.
+ taskDisplayArea.getStackAt(sNdx).forAllOccludedActivities(
+ ActivityRecord::cancelInitializing);
}
});
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index bcd71c9ba74e..970520aff81f 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -3175,6 +3175,33 @@ class Task extends WindowContainer<WindowContainer> {
return false;
}
+ /** Returns the top-most activity that occludes the given one, or {@code null} if none. */
+ @Nullable
+ ActivityRecord getOccludingActivityAbove(ActivityRecord activity) {
+ final ActivityRecord top = getActivity(ActivityRecord::occludesParent,
+ true /* traverseTopToBottom */, activity);
+ return top != activity ? top : null;
+ }
+
+ /** Iterates through all occluded activities. */
+ void forAllOccludedActivities(Consumer<ActivityRecord> handleOccludedActivity) {
+ if (!shouldBeVisible(null /* starting */)) {
+ // The stack is invisible so all activities are occluded.
+ forAllActivities(handleOccludedActivity);
+ return;
+ }
+ final ActivityRecord topOccluding = getOccludingActivityAbove(null);
+ if (topOccluding == null) {
+ // No activities are occluded.
+ return;
+ }
+ // Invoke the callback on the activities behind the top occluding activity.
+ forAllActivities(r -> {
+ handleOccludedActivity.accept(r);
+ return false;
+ }, topOccluding, false /* includeBoundary */, true /* traverseTopToBottom */);
+ }
+
@Override
public SurfaceControl.Builder makeAnimationLeash() {
return super.makeAnimationLeash().setMetadata(METADATA_TASK_ID, mTaskId);
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 1b42a0466cf7..373eed921580 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -1331,42 +1331,40 @@ public class ActivityStackTests extends ActivityTestsBase {
}
@Test
- public void testCheckBehindFullscreenActivity() {
+ public void testIterateOccludedActivity() {
final ArrayList<ActivityRecord> occludedActivities = new ArrayList<>();
- final Consumer<ActivityRecord> handleBehindFullscreenActivity = occludedActivities::add;
+ final Consumer<ActivityRecord> handleOccludedActivity = occludedActivities::add;
final ActivityRecord bottomActivity =
new ActivityBuilder(mService).setStack(mStack).setTask(mTask).build();
final ActivityRecord topActivity =
new ActivityBuilder(mService).setStack(mStack).setTask(mTask).build();
+ // Top activity occludes bottom activity.
doReturn(true).when(mStack).shouldBeVisible(any());
- assertTrue(mStack.checkBehindFullscreenActivity(bottomActivity,
- null /* handleBehindFullscreenActivity */));
- assertFalse(mStack.checkBehindFullscreenActivity(topActivity,
- null /* handleBehindFullscreenActivity */));
+ assertTrue(topActivity.shouldBeVisible());
+ assertFalse(bottomActivity.shouldBeVisible());
- // Top activity occludes bottom activity.
- mStack.checkBehindFullscreenActivity(null /* toCheck */, handleBehindFullscreenActivity);
+ mStack.forAllOccludedActivities(handleOccludedActivity);
assertThat(occludedActivities).containsExactly(bottomActivity);
+ // Top activity doesn't occlude parent, so the bottom activity is not occluded.
doReturn(false).when(topActivity).occludesParent();
- assertFalse(mStack.checkBehindFullscreenActivity(bottomActivity,
- null /* handleBehindFullscreenActivity */));
- assertFalse(mStack.checkBehindFullscreenActivity(topActivity,
- null /* handleBehindFullscreenActivity */));
+ assertTrue(bottomActivity.shouldBeVisible());
occludedActivities.clear();
- // Top activity doesn't occlude parent, so the bottom activity is not occluded.
- mStack.checkBehindFullscreenActivity(null /* toCheck */, handleBehindFullscreenActivity);
+ mStack.forAllOccludedActivities(handleOccludedActivity);
assertThat(occludedActivities).isEmpty();
+ // A finishing activity should not occlude other activities behind.
final ActivityRecord finishingActivity =
new ActivityBuilder(mService).setStack(mStack).setTask(mTask).build();
finishingActivity.finishing = true;
doCallRealMethod().when(finishingActivity).occludesParent();
- assertFalse(mStack.checkBehindFullscreenActivity(bottomActivity,
- null /* handleBehindFullscreenActivity */));
- assertFalse(mStack.checkBehindFullscreenActivity(topActivity,
- null /* handleBehindFullscreenActivity */));
+ assertTrue(topActivity.shouldBeVisible());
+ assertTrue(bottomActivity.shouldBeVisible());
+
+ occludedActivities.clear();
+ mStack.forAllOccludedActivities(handleOccludedActivity);
+ assertThat(occludedActivities).isEmpty();
}
@Test