summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ben Lin <linben@google.com> 2020-09-30 15:41:24 -0700
committer Ben Lin <linben@google.com> 2020-11-10 14:54:13 -0800
commit577cf49a149ea034b4c294f9cb92acf0d538d24a (patch)
tree5cee1f225d0d80f8c7fd1b1f0a7942b3ce5d81c5
parentbea090f330de8181bb5206e6469ceea66fe9ef56 (diff)
Check visibility when moving task to front.
Currently when we move a task to the front, we try to resume its top-most activity and pause the back stacks. However, in a multi-resume world, it's possible that this becomes a resume -> resume operation, which no-ops and exits early without pausing the back stack. Instead, we should check visibility before trying to resume the activity, in order to update any other tasks that are now no longer visible and thus should be STOPPED or PAUSED. Bug: 168852384 Test: atest PinnedStackTests#testAutoEnterPictureInPictureOnUserLeaveHintWhenPipRequestedNotOverridden Change-Id: I4dfdaab1f2b0c2116121e460cf3e3183107662e2
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java10
-rw-r--r--services/core/java/com/android/server/wm/ActivityStackSupervisor.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java2
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java4
-rw-r--r--services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java12
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java10
-rw-r--r--services/core/java/com/android/server/wm/Task.java16
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java7
-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.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java9
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java2
13 files changed, 54 insertions, 33 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 33df8b88fc2c..354fbbbf5704 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2738,7 +2738,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (ensureVisibility) {
mDisplayContent.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
- false /* preserveWindows */, true /* notifyClients */);
+ false /* preserveWindows */, true /* notifyClients */,
+ mStackSupervisor.mUserLeaving);
}
}
@@ -4752,7 +4753,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
handleAlreadyVisible();
}
- void makeInvisible() {
+ void makeInvisible(boolean userLeaving) {
if (!mVisibleRequested) {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + this);
return;
@@ -4793,9 +4794,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// If the app is capable of entering PIP, we should try pausing it now
// so it can PIP correctly.
if (deferHidingClient) {
- getRootTask().startPausingLocked(
- mStackSupervisor.mUserLeaving /* userLeaving */,
- false /* uiSleeping */, null /* resuming */, "makeInvisible");
+ getRootTask().startPausingLocked(userLeaving, false /* uiSleeping */,
+ null /* resuming */, "makeInvisible");
break;
}
case INITIALIZING:
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 17209ebad92f..e2a7afb64fca 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -2189,7 +2189,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
.notifyActivityDismissingDockedStack();
taskDisplayArea.onSplitScreenModeDismissed(task);
taskDisplayArea.mDisplayContent.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS,
- true /* notifyClients */);
+ true /* notifyClients */, mUserLeaving);
}
return;
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 84255c71346f..2cbc5148a4e1 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2460,7 +2460,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
} else {
stack.setWindowingMode(windowingMode);
stack.mDisplayContent.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS,
- true /* notifyClients */);
+ true /* notifyClients */, mStackSupervisor.mUserLeaving);
}
return true;
} finally {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 90c0c6f7f1d3..0eac2cb18fc8 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -5308,7 +5308,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
- boolean preserveWindows, boolean notifyClients) {
+ boolean preserveWindows, boolean notifyClients, boolean userLeaving) {
if (mInEnsureActivitiesVisible) {
// Don't do recursive work.
return;
@@ -5317,7 +5317,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
try {
forAllTaskDisplayAreas(taskDisplayArea -> {
taskDisplayArea.ensureActivitiesVisible(starting, configChanges,
- preserveWindows, notifyClients);
+ preserveWindows, notifyClients, userLeaving);
});
} finally {
mInEnsureActivitiesVisible = false;
diff --git a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
index 231cc9745ce1..e1d5b1d57197 100644
--- a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
+++ b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
@@ -33,6 +33,7 @@ class EnsureActivitiesVisibleHelper {
private int mConfigChanges;
private boolean mPreserveWindows;
private boolean mNotifyClients;
+ private boolean mUserLeaving;
EnsureActivitiesVisibleHelper(Task container) {
mTask = container;
@@ -49,7 +50,7 @@ class EnsureActivitiesVisibleHelper {
* be sent to the clients.
*/
void reset(ActivityRecord starting, int configChanges, boolean preserveWindows,
- boolean notifyClients) {
+ boolean notifyClients, boolean userLeaving) {
mStarting = starting;
mTop = mTask.topRunningActivity();
// If the top activity is not fullscreen, then we need to make sure any activities under it
@@ -60,6 +61,7 @@ class EnsureActivitiesVisibleHelper {
mConfigChanges = configChanges;
mPreserveWindows = preserveWindows;
mNotifyClients = notifyClients;
+ mUserLeaving = userLeaving;
}
/**
@@ -76,10 +78,12 @@ class EnsureActivitiesVisibleHelper {
* @param preserveWindows Flag indicating whether windows should be preserved when updating.
* @param notifyClients Flag indicating whether the configuration and visibility changes shoulc
* be sent to the clients.
+ * @param userLeaving Flag indicating whether a userLeaving callback should be issued in the
+ * case the activity is being set to invisible.
*/
void process(@Nullable ActivityRecord starting, int configChanges, boolean preserveWindows,
- boolean notifyClients) {
- reset(starting, configChanges, preserveWindows, notifyClients);
+ boolean notifyClients, boolean userLeaving) {
+ reset(starting, configChanges, preserveWindows, notifyClients, userLeaving);
if (DEBUG_VISIBILITY) {
Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + mTop
@@ -173,7 +177,7 @@ class EnsureActivitiesVisibleHelper {
+ " behindFullscreenActivity=" + mBehindFullscreenActivity
+ " mLaunchTaskBehind=" + r.mLaunchTaskBehind);
}
- r.makeInvisible();
+ r.makeInvisible(mUserLeaving);
}
if (!mBehindFullscreenActivity && mTask.isActivityTypeHome() && r.isRootOfTask()) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 2749cc9e37fd..2ab871e11679 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -1812,7 +1812,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// Passing null here for 'starting' param value, so that visibility of actual starting
// activity will be properly updated.
ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
- false /* preserveWindows */, false /* notifyClients */);
+ false /* preserveWindows */, false /* notifyClients */,
+ mStackSupervisor.mUserLeaving);
if (displayId == INVALID_DISPLAY) {
// The caller didn't provide a valid display id, skip updating config.
@@ -2005,14 +2006,15 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
*/
void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
boolean preserveWindows) {
- ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */);
+ ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */,
+ mStackSupervisor.mUserLeaving);
}
/**
* @see #ensureActivitiesVisible(ActivityRecord, int, boolean)
*/
void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
- boolean preserveWindows, boolean notifyClients) {
+ boolean preserveWindows, boolean notifyClients, boolean userLeaving) {
if (mStackSupervisor.inActivityVisibilityUpdate()) {
// Don't do recursive work.
return;
@@ -2024,7 +2026,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
final DisplayContent display = getChildAt(displayNdx);
display.ensureActivitiesVisible(starting, configChanges, preserveWindows,
- notifyClients);
+ notifyClients, userLeaving);
}
} finally {
mStackSupervisor.endActivityVisibilityUpdate();
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 86f1cf71e2e0..827634f72ca4 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -5734,7 +5734,8 @@ class Task extends WindowContainer<WindowContainer> {
*/
void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges,
boolean preserveWindows) {
- ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */);
+ ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */,
+ mStackSupervisor.mUserLeaving);
}
/**
@@ -5751,14 +5752,16 @@ class Task extends WindowContainer<WindowContainer> {
* @param configChanges Parts of the configuration that changed for this activity for evaluating
* if the screen should be frozen as part of
* {@link mEnsureActivitiesVisibleHelper}.
+ * @param userLeaving Flag indicating whether a userLeaving callback should be issued in the
+ * case an activity is being set to invisible.
*/
// TODO: Should be re-worked based on the fact that each task as a stack in most cases.
void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges,
- boolean preserveWindows, boolean notifyClients) {
+ boolean preserveWindows, boolean notifyClients, boolean userLeaving) {
mStackSupervisor.beginActivityVisibilityUpdate();
try {
forAllLeafTasks(task -> task.mEnsureActivitiesVisibleHelper.process(
- starting, configChanges, preserveWindows, notifyClients),
+ starting, configChanges, preserveWindows, notifyClients, userLeaving),
true /* traverseTopToBottom */);
if (mTranslucentActivityWaiting != null &&
@@ -5951,6 +5954,13 @@ class Task extends WindowContainer<WindowContainer> {
// Make sure we have executed any pending transitions, since there
// should be nothing left to do at this point.
executeAppTransition(options);
+ // For devices that are not in fullscreen mode (e.g. freeform windows), it's possible
+ // we still want to check if the visibility of other windows have changed (e.g. bringing
+ // a fullscreen window forward to cover another freeform activity.)
+ if (taskDisplayArea.inMultiWindowMode()) {
+ taskDisplayArea.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
+ false /* preserveWindows */, true /* notifyClients */, userLeaving);
+ }
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Top activity "
+ "resumed %s", next);
return false;
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 9d14e0d5d984..802c8f9f1ec9 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -1806,13 +1806,13 @@ final class TaskDisplayArea extends DisplayArea<Task> {
}
void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
- boolean preserveWindows, boolean notifyClients) {
+ boolean preserveWindows, boolean notifyClients, boolean userLeaving) {
mAtmService.mStackSupervisor.beginActivityVisibilityUpdate();
try {
for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) {
final Task stack = getStackAt(stackNdx);
stack.ensureActivitiesVisible(starting, configChanges, preserveWindows,
- notifyClients);
+ notifyClients, userLeaving);
}
} finally {
mAtmService.mStackSupervisor.endActivityVisibilityUpdate();
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 cf7f741021fb..7b9ccae794f3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -1127,7 +1127,8 @@ public class ActivityRecordTests extends WindowTestsBase {
topActivity.setState(RESUMED, "true");
doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible(
any() /* starting */, anyInt() /* configChanges */,
- anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */);
+ anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */,
+ anyBoolean() /* userLeaving */);
topActivity.setShowWhenLocked(true);
// Verify the stack-top activity is occluded keyguard.
@@ -1173,7 +1174,7 @@ public class ActivityRecordTests extends WindowTestsBase {
secondActivity.completeFinishing("test");
verify(secondActivity.mDisplayContent).ensureActivitiesVisible(null /* starting */,
0 /* configChanges */ , false /* preserveWindows */,
- true /* notifyClients */);
+ true /* notifyClients */, false /* userLeaving */);
// Finish the first activity
firstActivity.finishing = true;
@@ -1181,7 +1182,7 @@ public class ActivityRecordTests extends WindowTestsBase {
firstActivity.completeFinishing("test");
verify(firstActivity.mDisplayContent, times(2)).ensureActivitiesVisible(null /* starting */,
0 /* configChanges */ , false /* preserveWindows */,
- true /* notifyClients */);
+ true /* notifyClients */, false /* userLeaving */);
}
/**
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 fbfc0e09584b..dc33b75ec57a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -1533,11 +1533,12 @@ public class DisplayContentTests extends WindowTestsBase {
// The assertion will fail if DisplayArea#ensureActivitiesVisible is called twice.
assertFalse(called[0]);
called[0] = true;
- mDisplayContent.ensureActivitiesVisible(null, 0, false, false);
+ mDisplayContent.ensureActivitiesVisible(null, 0, false, false, false);
return null;
- }).when(mockTda).ensureActivitiesVisible(any(), anyInt(), anyBoolean(), anyBoolean());
+ }).when(mockTda).ensureActivitiesVisible(any(), anyInt(), anyBoolean(), anyBoolean(),
+ anyBoolean());
- mDisplayContent.ensureActivitiesVisible(null, 0, false, false);
+ mDisplayContent.ensureActivitiesVisible(null, 0, false, false, false);
}
@Test
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 d348389a44b1..80bffd17ab43 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -294,7 +294,7 @@ public class RecentTasksTest extends WindowTestsBase {
}).when(mSupervisor).endActivityVisibilityUpdate();
mTaskContainer.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
- false /* preserveWindows */, false /* notifyClients */);
+ false /* preserveWindows */, false /* notifyClients */, false /* userLeaving */);
assertFalse(mSupervisor.inActivityVisibilityUpdate());
assertThat(mCallbacksRecorder.mAdded).hasSize(2);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index 137cedde11cf..542747033765 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -100,7 +100,8 @@ public class RecentsAnimationTest extends WindowTestsBase {
doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible(
any() /* starting */, anyInt() /* configChanges */,
- anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */);
+ anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */,
+ anyBoolean() /* userLeaving */);
RecentsAnimationCallbacks recentsAnimation = startRecentsActivity(
mRecentsComponent, true /* getRecentsAnimation */);
@@ -191,7 +192,8 @@ public class RecentsAnimationTest extends WindowTestsBase {
doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible(
any() /* starting */, anyInt() /* configChanges */,
- anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */);
+ anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */,
+ anyBoolean() /* userLeaving */);
doReturn(app).when(mAtm).getProcessController(eq(recentActivity.processName), anyInt());
ClientLifecycleManager lifecycleManager = mAtm.getLifecycleManager();
doNothing().when(lifecycleManager).scheduleTransaction(any());
@@ -347,7 +349,8 @@ public class RecentsAnimationTest extends WindowTestsBase {
doReturn(TEST_USER_ID).when(mAtm).getCurrentUserId();
doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible(
any() /* starting */, anyInt() /* configChanges */,
- anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */);
+ anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */,
+ anyBoolean() /* userLeaving */);
startRecentsActivity(otherUserHomeActivity.getTask().getBaseIntent().getComponent(),
true);
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 a79a5194c51c..a8c24c9b2f1b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -297,7 +297,7 @@ public class SystemServicesTestRule implements TestRule {
doReturn(true).when(mWmService.mRoot).hasAwakeDisplay();
// Called when moving activity to pinned stack.
doNothing().when(mWmService.mRoot).ensureActivitiesVisible(any(),
- anyInt(), anyBoolean(), anyBoolean());
+ anyInt(), anyBoolean(), anyBoolean(), anyBoolean());
spyOn(mWmService.mDisplayWindowSettings);
// Setup factory classes to prevent calls to native code.