From 5e004f2798c81a0d24d4416afc5680ac0d6f4fe1 Mon Sep 17 00:00:00 2001 From: chaviw Date: Fri, 11 May 2018 09:32:22 -0700 Subject: [PATCH] Prevent IME from targeting home when closing app is still animating There were a few issues that caused the IME target to get set to home. 1. Home is considered above the other apps since it's getting launched. However, the visual representation is actually below the closing app. IME tries to target the highest app, but it's not necessarily the highest visual app 2. computeIme was called before all apps were set up. This caused the IME target to get recomputed before adding the closing apps 3. The condition for a WS.isClosing was based on previous versions so it was incorrect Test: IME closes on top of current target when going home with IME open Change-Id: Id3bee8b8b6c0fba98159b65784b4b8c5b66c27fb Fixes: 78214125 --- .../android/server/am/ActivityDisplay.java | 14 ++++ .../com/android/server/am/ActivityStack.java | 78 +++++++++++-------- .../com/android/server/wm/DisplayContent.java | 55 ++++++++++--- .../server/wm/DisplayWindowController.java | 25 ++++++ .../com/android/server/wm/WindowState.java | 2 +- 5 files changed, 131 insertions(+), 43 deletions(-) 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) {