diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java index 27eae57302b0e..698b6f7d99f2d 100644 --- a/services/core/java/com/android/server/am/ActivityDisplay.java +++ b/services/core/java/com/android/server/am/ActivityDisplay.java @@ -800,6 +800,20 @@ class ActivityDisplay extends ConfigurationContainer } } + /** + * See {@link DisplayWindowController#deferUpdateImeTarget()} + */ + public void deferUpdateImeTarget() { + mWindowContainerController.deferUpdateImeTarget(); + } + + /** + * See {@link DisplayWindowController#deferUpdateImeTarget()} + */ + public void continueUpdateImeTarget() { + mWindowContainerController.continueUpdateImeTarget(); + } + public void dump(PrintWriter pw, String prefix) { pw.println(prefix + "displayId=" + mDisplayId + " stacks=" + mStacks.size()); final String myPrefix = prefix + " "; diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index a85df03e97f68..235a15a60bfe9 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -4592,46 +4592,58 @@ class ActivityStack extends ConfigurationContai } } - // Shift all activities with this task up to the top - // of the stack, keeping them in the same internal order. - insertTaskAtTop(tr, null); + try { + // Defer updating the IME target since the new IME target will try to get computed + // before updating all closing and opening apps, which can cause the ime target to + // get calculated incorrectly. + getDisplay().deferUpdateImeTarget(); - // Don't refocus if invisible to current user - final ActivityRecord top = tr.getTopActivity(); - if (top == null || !top.okToShowLocked()) { - if (top != null) { - mStackSupervisor.mRecentTasks.add(top.getTask()); + // Shift all activities with this task up to the top + // of the stack, keeping them in the same internal order. + insertTaskAtTop(tr, null); + + // Don't refocus if invisible to current user + final ActivityRecord top = tr.getTopActivity(); + if (top == null || !top.okToShowLocked()) { + if (top != null) { + mStackSupervisor.mRecentTasks.add(top.getTask()); + } + ActivityOptions.abort(options); + return; } - ActivityOptions.abort(options); - return; - } - // Set focus to the top running activity of this stack. - final ActivityRecord r = topRunningActivityLocked(); - mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, reason); + // Set focus to the top running activity of this stack. + final ActivityRecord r = topRunningActivityLocked(); + mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, reason); - if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr); - if (noAnimation) { - mWindowManager.prepareAppTransition(TRANSIT_NONE, false); - if (r != null) { - mStackSupervisor.mNoAnimActivities.add(r); + if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr); + if (noAnimation) { + mWindowManager.prepareAppTransition(TRANSIT_NONE, false); + if (r != null) { + mStackSupervisor.mNoAnimActivities.add(r); + } + ActivityOptions.abort(options); + } else { + updateTransitLocked(TRANSIT_TASK_TO_FRONT, options); } - ActivityOptions.abort(options); - } else { - updateTransitLocked(TRANSIT_TASK_TO_FRONT, options); - } - // If a new task is moved to the front, then mark the existing top activity as supporting - // picture-in-picture while paused only if the task would not be considered an oerlay on top - // of the current activity (eg. not fullscreen, or the assistant) - if (canEnterPipOnTaskSwitch(topActivity, tr, null /* toFrontActivity */, - options)) { - topActivity.supportsEnterPipOnTaskSwitch = true; - } + // If a new task is moved to the front, then mark the existing top activity as + // supporting - mStackSupervisor.resumeFocusedStackTopActivityLocked(); - EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId); + // picture-in-picture while paused only if the task would not be considered an oerlay + // on top + // of the current activity (eg. not fullscreen, or the assistant) + if (canEnterPipOnTaskSwitch(topActivity, tr, null /* toFrontActivity */, + options)) { + topActivity.supportsEnterPipOnTaskSwitch = true; + } - mService.mTaskChangeNotificationController.notifyTaskMovedToFront(tr.taskId); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); + EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId); + + mService.mTaskChangeNotificationController.notifyTaskMovedToFront(tr.taskId); + } finally { + getDisplay().continueUpdateImeTarget(); + } } /** diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index c0dc750949bcd..f3423c63e270f 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -390,6 +390,11 @@ class DisplayContent extends WindowContainer target.mWinAnimator.mAnimLayer)) { - if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Current target higher, not changing"); + && (target == null || target.isActivityTypeHome())) { + if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "New target is home while current target is" + + "closing, not changing"); return curTarget; } @@ -3958,4 +3966,33 @@ class DisplayContent extends WindowContainer implements WindowManagerP } boolean isClosing() { - return mAnimatingExit || (mService.mClosingApps.contains(mAppToken)); + return mAnimatingExit || (mAppToken.isAnimating() && mAppToken.hiddenRequested); } void addWinAnimatorToList(ArrayList animators) {