Loading services/core/java/com/android/server/am/ActivityDisplay.java +14 −0 Original line number Diff line number Diff line Loading @@ -800,6 +800,20 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> } } /** * 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 + " "; Loading services/core/java/com/android/server/am/ActivityStack.java +46 −34 Original line number Diff line number Diff line Loading @@ -4595,6 +4595,12 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } 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(); // Shift all activities with this task up to the top // of the stack, keeping them in the same internal order. insertTaskAtTop(tr, null); Loading Loading @@ -4623,8 +4629,11 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } 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 // 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)) { Loading @@ -4635,6 +4644,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId); mService.mTaskChangeNotificationController.notifyTaskMovedToFront(tr.taskId); } finally { getDisplay().continueUpdateImeTarget(); } } /** Loading services/core/java/com/android/server/wm/DisplayContent.java +46 −9 Original line number Diff line number Diff line Loading @@ -390,6 +390,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo */ int mLayoutSeq = 0; /** * Specifies the count to determine whether to defer updating the IME target until ready. */ private int mDeferUpdateImeTargetCount; /** Temporary float array to retrieve 3x3 matrix values. */ private final float[] mTmpFloats = new float[9]; Loading Loading @@ -2454,6 +2459,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return null; } final WindowState curTarget = mService.mInputMethodTarget; if (!canUpdateImeTarget()) { if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Defer updating IME target"); return curTarget; } // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the // same display. Or even when the current IME/target are not on the same screen as the next // IME/target. For now only look for input windows on the main screen. Loading @@ -2477,16 +2488,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (DEBUG_INPUT_METHOD && updateImeTarget) Slog.v(TAG_WM, "Proposed new IME target: " + target); // Now, a special case -- if the last target's window is in the process of exiting, and is // above the new target, keep on the last target to avoid flicker. Consider for example a // Dialog with the IME shown: when the Dialog is dismissed, we want to keep the IME above it // until it is completely gone so it doesn't drop behind the dialog or its full-screen // scrim. final WindowState curTarget = mService.mInputMethodTarget; // Now, a special case -- if the last target's window is in the process of exiting, and the // new target is home, keep on the last target to avoid flicker. Home is a special case // since its above other stacks in the ordering list, but layed out below the others. if (curTarget != null && curTarget.isDisplayedLw() && curTarget.isClosing() && (target == null || curTarget.mWinAnimator.mAnimLayer > 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; } Loading Loading @@ -3958,4 +3966,33 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo void assignStackOrdering() { mTaskStackContainers.assignStackOrdering(getPendingTransaction()); } /** * Increment the deferral count to determine whether to update the IME target. */ void deferUpdateImeTarget() { mDeferUpdateImeTargetCount++; } /** * Decrement the deferral count to determine whether to update the IME target. If the count * reaches 0, a new ime target will get computed. */ void continueUpdateImeTarget() { if (mDeferUpdateImeTargetCount == 0) { return; } mDeferUpdateImeTargetCount--; if (mDeferUpdateImeTargetCount == 0) { computeImeTarget(true /* updateImeTarget */); } } /** * @return Whether a new IME target should be computed. */ private boolean canUpdateImeTarget() { return mDeferUpdateImeTargetCount == 0; } } services/core/java/com/android/server/wm/DisplayWindowController.java +25 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,31 @@ public class DisplayWindowController } } /** * Starts deferring the ability to update the IME target. This is needed when a call will * attempt to update the IME target before all information about the Windows have been updated. */ public void deferUpdateImeTarget() { synchronized (mWindowMap) { final DisplayContent dc = mRoot.getDisplayContent(mDisplayId); if (dc != null) { dc.deferUpdateImeTarget(); } } } /** * Resumes updating the IME target after deferring. See {@link #deferUpdateImeTarget()} */ public void continueUpdateImeTarget() { synchronized (mWindowMap) { final DisplayContent dc = mRoot.getDisplayContent(mDisplayId); if (dc != null) { dc.continueUpdateImeTarget(); } } } @Override public String toString() { return "{DisplayWindowController displayId=" + mDisplayId + "}"; Loading services/core/java/com/android/server/wm/WindowState.java +2 −1 Original line number Diff line number Diff line Loading @@ -2726,7 +2726,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } boolean isClosing() { return mAnimatingExit || (mService.mClosingApps.contains(mAppToken)); return mAnimatingExit || (mAppToken != null && mAppToken.isAnimating() && mAppToken.hiddenRequested); } void addWinAnimatorToList(ArrayList<WindowStateAnimator> animators) { Loading Loading
services/core/java/com/android/server/am/ActivityDisplay.java +14 −0 Original line number Diff line number Diff line Loading @@ -800,6 +800,20 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> } } /** * 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 + " "; Loading
services/core/java/com/android/server/am/ActivityStack.java +46 −34 Original line number Diff line number Diff line Loading @@ -4595,6 +4595,12 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } 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(); // Shift all activities with this task up to the top // of the stack, keeping them in the same internal order. insertTaskAtTop(tr, null); Loading Loading @@ -4623,8 +4629,11 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } 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 // 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)) { Loading @@ -4635,6 +4644,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId); mService.mTaskChangeNotificationController.notifyTaskMovedToFront(tr.taskId); } finally { getDisplay().continueUpdateImeTarget(); } } /** Loading
services/core/java/com/android/server/wm/DisplayContent.java +46 −9 Original line number Diff line number Diff line Loading @@ -390,6 +390,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo */ int mLayoutSeq = 0; /** * Specifies the count to determine whether to defer updating the IME target until ready. */ private int mDeferUpdateImeTargetCount; /** Temporary float array to retrieve 3x3 matrix values. */ private final float[] mTmpFloats = new float[9]; Loading Loading @@ -2454,6 +2459,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return null; } final WindowState curTarget = mService.mInputMethodTarget; if (!canUpdateImeTarget()) { if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Defer updating IME target"); return curTarget; } // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the // same display. Or even when the current IME/target are not on the same screen as the next // IME/target. For now only look for input windows on the main screen. Loading @@ -2477,16 +2488,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (DEBUG_INPUT_METHOD && updateImeTarget) Slog.v(TAG_WM, "Proposed new IME target: " + target); // Now, a special case -- if the last target's window is in the process of exiting, and is // above the new target, keep on the last target to avoid flicker. Consider for example a // Dialog with the IME shown: when the Dialog is dismissed, we want to keep the IME above it // until it is completely gone so it doesn't drop behind the dialog or its full-screen // scrim. final WindowState curTarget = mService.mInputMethodTarget; // Now, a special case -- if the last target's window is in the process of exiting, and the // new target is home, keep on the last target to avoid flicker. Home is a special case // since its above other stacks in the ordering list, but layed out below the others. if (curTarget != null && curTarget.isDisplayedLw() && curTarget.isClosing() && (target == null || curTarget.mWinAnimator.mAnimLayer > 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; } Loading Loading @@ -3958,4 +3966,33 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo void assignStackOrdering() { mTaskStackContainers.assignStackOrdering(getPendingTransaction()); } /** * Increment the deferral count to determine whether to update the IME target. */ void deferUpdateImeTarget() { mDeferUpdateImeTargetCount++; } /** * Decrement the deferral count to determine whether to update the IME target. If the count * reaches 0, a new ime target will get computed. */ void continueUpdateImeTarget() { if (mDeferUpdateImeTargetCount == 0) { return; } mDeferUpdateImeTargetCount--; if (mDeferUpdateImeTargetCount == 0) { computeImeTarget(true /* updateImeTarget */); } } /** * @return Whether a new IME target should be computed. */ private boolean canUpdateImeTarget() { return mDeferUpdateImeTargetCount == 0; } }
services/core/java/com/android/server/wm/DisplayWindowController.java +25 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,31 @@ public class DisplayWindowController } } /** * Starts deferring the ability to update the IME target. This is needed when a call will * attempt to update the IME target before all information about the Windows have been updated. */ public void deferUpdateImeTarget() { synchronized (mWindowMap) { final DisplayContent dc = mRoot.getDisplayContent(mDisplayId); if (dc != null) { dc.deferUpdateImeTarget(); } } } /** * Resumes updating the IME target after deferring. See {@link #deferUpdateImeTarget()} */ public void continueUpdateImeTarget() { synchronized (mWindowMap) { final DisplayContent dc = mRoot.getDisplayContent(mDisplayId); if (dc != null) { dc.continueUpdateImeTarget(); } } } @Override public String toString() { return "{DisplayWindowController displayId=" + mDisplayId + "}"; Loading
services/core/java/com/android/server/wm/WindowState.java +2 −1 Original line number Diff line number Diff line Loading @@ -2726,7 +2726,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } boolean isClosing() { return mAnimatingExit || (mService.mClosingApps.contains(mAppToken)); return mAnimatingExit || (mAppToken != null && mAppToken.isAnimating() && mAppToken.hiddenRequested); } void addWinAnimatorToList(ArrayList<WindowStateAnimator> animators) { Loading