diff options
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. |