summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Dohyun Lee <dohyun.lee@lge.com> 2024-09-16 17:58:07 +0000
committer Rachit Jain <jainrachit@google.com> 2024-09-16 18:00:39 +0000
commit87327dd2da5e47f15fe74d54ee1ae4eb09e52266 (patch)
tree21de968b242e3321bfdb56030f6eb8642690b98c
parentc3b59309957f1b25d2709f7c5e05cdeca57a4cc5 (diff)
Fix InvalidDisplayException on display removal for visible background users
In the automotive multi-user, multi-display environment that supports background users with UI access on assigned displays (a.k.a. visible background users), it's not allowed to create a window or launch an activity on an unassigned display. The crash happens when the test removes the overlay display during its teardown while a test activity is running in it. When the display is removed, the root tasks in its task display area are reparented to the task display area of the default display, which is not assigned to their user, causing the crash. Therefore, it is modified to reparent the root tasks to the display where their user is assigned when removing the display. Flag: EXEMPT (bug fix) Bug: 362325749 Test: atest CtsWindowManagerDeviceActivity:ActivityLifecycleTopResumedStateTests#testFinishOnDifferentDisplay_nonFocused Test: atest --user-type secondary_user CtsWindowManagerDeviceActivity:ActivityLifecycleTopResumedStateTests#testFinishOnDifferentDisplay_nonFocused Test: atest --user-type secondary_user_on_secondary_display CtsWindowManagerDeviceActivity:ActivityLifecycleTopResumedStateTests#testFinishOnDifferentDisplay_nonFocused Signed-off-by: Dohyun Lee <dohyun.lee@lge.com> (cherry picked from https://partner-android-review.googlesource.com/q/commit:d2f6a39ce402c8ed88e46d47961bbbf31266bb60) Merged-In: I223d4c33d7bcc09b06517dee7e07086cf06db736 Change-Id: I223d4c33d7bcc09b06517dee7e07086cf06db736
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java39
1 files changed, 38 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 638e92f112c7..42ea5a88a09b 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -28,6 +28,7 @@ import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.view.Display.INVALID_DISPLAY;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.server.wm.ActivityRecord.State.RESUMED;
@@ -57,6 +58,7 @@ import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.util.function.pooled.PooledPredicate;
+import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.LaunchParamsController.LaunchParams;
import java.io.PrintWriter;
@@ -1761,10 +1763,10 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
* @return last reparented root task, or {@code null} if the root tasks had to be destroyed.
*/
Task remove() {
+ final TaskDisplayArea toDisplayArea = getReparentToTaskDisplayArea(getFocusedRootTask());
mPreferredTopFocusableRootTask = null;
// TODO(b/153090332): Allow setting content removal mode per task display area
final boolean destroyContentOnRemoval = mDisplayContent.shouldDestroyContentOnRemove();
- final TaskDisplayArea toDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
Task lastReparentedRootTask = null;
// Root tasks could be reparented from the removed display area to other display area. After
@@ -1830,6 +1832,41 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
return lastReparentedRootTask;
}
+ /**
+ * Returns the {@link TaskDisplayArea} to which root tasks should be reparented.
+ *
+ * <p>In the automotive multi-user multi-display environment where background users have
+ * UI access on their assigned displays (a.k.a. visible background users), it's not allowed to
+ * launch an activity on an unassigned display. If an activity is attempted to launch on an
+ * unassigned display, it throws an exception.
+ * <p>This method determines the appropriate {@link TaskDisplayArea} for reparenting root tasks
+ * when a display is removed, in order to avoid the exception. If the root task is null,
+ * the visible background user is not supported or the user associated with the root task is
+ * not a visible background user, it returns the default {@link TaskDisplayArea} of the default
+ * display. Otherwise, it returns the default {@link TaskDisplayArea} of the main display
+ * assigned to the user.
+ *
+ * @param rootTask The root task whose {@link TaskDisplayArea} needs to be determined.
+ * @return The {@link TaskDisplayArea} where the root tasks should be reparented to.
+ */
+ private TaskDisplayArea getReparentToTaskDisplayArea(Task rootTask) {
+ final TaskDisplayArea defaultTaskDisplayArea =
+ mRootWindowContainer.getDefaultTaskDisplayArea();
+ if (rootTask == null) {
+ return defaultTaskDisplayArea;
+ }
+ UserManagerInternal userManagerInternal = mAtmService.mWindowManager.mUmInternal;
+ if (!userManagerInternal.isVisibleBackgroundFullUser(rootTask.mUserId)) {
+ return defaultTaskDisplayArea;
+ }
+ int toDisplayId = userManagerInternal.getMainDisplayAssignedToUser(rootTask.mUserId);
+ if (toDisplayId == INVALID_DISPLAY) {
+ return defaultTaskDisplayArea;
+ }
+ DisplayContent dc = mRootWindowContainer.getDisplayContent(toDisplayId);
+ return dc != null ? dc.getDefaultTaskDisplayArea() : defaultTaskDisplayArea;
+ }
+
/** Whether this task display area can request orientation. */
boolean canSpecifyOrientation(@ScreenOrientation int orientation) {
// Only allow to specify orientation if this TDA is the last focused one on this logical