From 3a74855bbb160b2e9240c2268c823916af2dea72 Mon Sep 17 00:00:00 2001 From: Chavi Weingarten Date: Mon, 14 May 2018 17:32:42 +0000 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: Ia9b0cc913eeb76a4af20f9ac7b667c5a3d1eafc7 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 | 3 +- 5 files changed, 132 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 87d3696482335..c18250272b7ee 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -4595,46 +4595,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 != null && mAppToken.isAnimating() + && mAppToken.hiddenRequested); } void addWinAnimatorToList(ArrayList animators) {