summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/AppWindowAnimator.java3
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java417
-rw-r--r--services/core/java/com/android/server/wm/TaskStack.java5
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java413
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java78
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfacePlacer.java8
-rw-r--r--services/core/java/com/android/server/wm/WindowToken.java6
7 files changed, 472 insertions, 458 deletions
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index 429cb2d3637c..e774259b811e 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -31,7 +31,6 @@ import android.util.TimeUtils;
import android.view.Choreographer;
import android.view.Display;
import android.view.SurfaceControl;
-import android.view.WindowManagerPolicy;
import android.view.animation.Animation;
import android.view.animation.Transformation;
@@ -394,7 +393,7 @@ public class AppWindowAnimator {
}
if (mService.mInputMethodTarget != null
&& mService.mInputMethodTarget.mAppToken == mAppToken) {
- mService.moveInputMethodWindowsIfNeededLocked(true);
+ mAppToken.getDisplayContent().moveInputMethodWindowsIfNeeded(true);
}
if (DEBUG_ANIM) Slog.v(TAG, "Animation done in " + mAppToken
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 7299bdf29402..e6f281da5e66 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -32,9 +32,12 @@ import static android.view.Surface.ROTATION_90;
import static android.view.WindowManager.DOCKED_BOTTOM;
import static android.view.WindowManager.DOCKED_INVALID;
import static android.view.WindowManager.DOCKED_TOP;
+import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+import static android.view.WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE;
+import static android.view.WindowManager.LayoutParams.NEEDS_MENU_UNSET;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
@@ -44,11 +47,13 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.H.WINDOW_HIDE_TIMEOUT;
import static com.android.server.wm.WindowManagerService.dipToPixel;
@@ -72,6 +77,8 @@ import android.util.Slog;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.IWindow;
+import android.view.WindowManager;
+import android.view.WindowManagerPolicy;
import com.android.internal.util.FastPrintWriter;
@@ -717,6 +724,21 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
}
+ /**
+ * If a window that has an animation specifying a colored background and the current wallpaper
+ * is visible, then the color goes *below* the wallpaper so we don't cause the wallpaper to
+ * suddenly disappear.
+ */
+ int getLayerForAnimationBackground(WindowStateAnimator winAnimator) {
+ for (int i = mWindows.size() - 1; i >= 0; --i) {
+ final WindowState win = mWindows.get(i);
+ if (win.mIsWallpaper && win.isVisibleNow()) {
+ return win.mWinAnimator.mAnimLayer;
+ }
+ }
+ return winAnimator.mAnimLayer;
+ }
+
void prepareFreezingTaskBounds() {
for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
final TaskStack stack = mTaskStackContainers.get(stackNdx);
@@ -1102,6 +1124,36 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
mWindows.add(index, win);
}
+ boolean removeFromWindowList(WindowState win) {
+ return mWindows.remove(win);
+ }
+
+ private int removeWindowAndChildrenFromWindowList(WindowState win, int interestingPos) {
+ final WindowList windows = getWindowList();
+ int wpos = windows.indexOf(win);
+ if (wpos < 0) {
+ return interestingPos;
+ }
+
+ if (wpos < interestingPos) interestingPos--;
+ if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Temp removing at " + wpos + ": " + this);
+ windows.remove(wpos);
+ mService.mWindowsChanged = true;
+ int childWinCount = win.mChildren.size();
+ while (childWinCount > 0) {
+ childWinCount--;
+ final WindowState cw = win.mChildren.get(childWinCount);
+ int cpos = windows.indexOf(cw);
+ if (cpos >= 0) {
+ if (cpos < interestingPos) interestingPos--;
+ if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM,
+ "Temp removing child at " + cpos + ": " + cw);
+ windows.remove(cpos);
+ }
+ }
+ return interestingPos;
+ }
+
void addChildWindowToWindowList(WindowState win) {
final WindowState parentWindow = win.getParentWindow();
@@ -1257,6 +1309,371 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
return windowList;
}
+ private void reAddToWindowList(WindowState win) {
+ win.mToken.addWindow(win);
+ // This is a hack to get all of the child windows added as well at the right position. Child
+ // windows should be rare and this case should be rare, so it shouldn't be that big a deal.
+ int wpos = mWindows.indexOf(win);
+ if (wpos >= 0) {
+ if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "ReAdd removing from " + wpos + ": " + win);
+ mWindows.remove(wpos);
+ mService.mWindowsChanged = true;
+ win.reAddWindow(wpos);
+ }
+ }
+
+ void moveInputMethodDialogs(int pos) {
+ ArrayList<WindowState> dialogs = mService.mInputMethodDialogs;
+
+ final int N = dialogs.size();
+ if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Removing " + N + " dialogs w/pos=" + pos);
+ for (int i = 0; i < N; i++) {
+ pos = removeWindowAndChildrenFromWindowList(dialogs.get(i), pos);
+ }
+ if (DEBUG_INPUT_METHOD) {
+ Slog.v(TAG_WM, "Window list w/pos=" + pos);
+ logWindowList(mWindows, " ");
+ }
+
+ WindowState ime = mService.mInputMethodWindow;
+ if (pos >= 0) {
+ // Skip windows owned by the input method.
+ if (ime != null) {
+ while (pos < mWindows.size()) {
+ WindowState wp = mWindows.get(pos);
+ if (wp == ime || wp.getParentWindow() == ime) {
+ pos++;
+ continue;
+ }
+ break;
+ }
+ }
+ if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Adding " + N + " dialogs at pos=" + pos);
+ for (int i=0; i<N; i++) {
+ WindowState win = dialogs.get(i);
+ pos = win.reAddWindow(pos);
+ }
+ if (DEBUG_INPUT_METHOD) {
+ Slog.v(TAG_WM, "Final window list:");
+ logWindowList(mWindows, " ");
+ }
+ return;
+ }
+ for (int i=0; i<N; i++) {
+ WindowState win = dialogs.get(i);
+ reAddToWindowList(win);
+ if (DEBUG_INPUT_METHOD) {
+ Slog.v(TAG_WM, "No IM target, final list:");
+ logWindowList(mWindows, " ");
+ }
+ }
+ }
+
+ boolean moveInputMethodWindowsIfNeeded(boolean needAssignLayers) {
+ final WindowState imWin = mService.mInputMethodWindow;
+ final int DN = mService.mInputMethodDialogs.size();
+ if (imWin == null && DN == 0) {
+ return false;
+ }
+
+ // TODO(multidisplay): IMEs are only supported on the default display.
+ WindowList windows = mWindows;
+
+ int imPos = findDesiredInputMethodWindowIndex(true);
+ if (imPos >= 0) {
+ // In this case, the input method windows are to be placed
+ // immediately above the window they are targeting.
+
+ // First check to see if the input method windows are already
+ // located here, and contiguous.
+ final int N = windows.size();
+ final WindowState firstImWin = imPos < N ? windows.get(imPos) : null;
+
+ // Figure out the actual input method window that should be
+ // at the bottom of their stack.
+ WindowState baseImWin = imWin != null ? imWin : mService.mInputMethodDialogs.get(0);
+ final WindowState cw = baseImWin.getBottomChild();
+ if (cw != null && cw.mSubLayer < 0) {
+ baseImWin = cw;
+ }
+
+ if (firstImWin == baseImWin) {
+ // The windows haven't moved... but are they still contiguous?
+ // First find the top IM window.
+ int pos = imPos+1;
+ while (pos < N) {
+ if (!(windows.get(pos)).mIsImWindow) {
+ break;
+ }
+ pos++;
+ }
+ pos++;
+ // Now there should be no more input method windows above.
+ while (pos < N) {
+ if ((windows.get(pos)).mIsImWindow) {
+ break;
+ }
+ pos++;
+ }
+ if (pos >= N) {
+ return false;
+ }
+ }
+
+ if (imWin != null) {
+ if (DEBUG_INPUT_METHOD) {
+ Slog.v(TAG_WM, "Moving IM from " + imPos);
+ logWindowList(windows, " ");
+ }
+ imPos = removeWindowAndChildrenFromWindowList(imWin, imPos);
+ if (DEBUG_INPUT_METHOD) {
+ Slog.v(TAG_WM, "List after removing with new pos " + imPos + ":");
+ logWindowList(windows, " ");
+ }
+ imWin.reAddWindow(imPos);
+ if (DEBUG_INPUT_METHOD) {
+ Slog.v(TAG_WM, "List after moving IM to " + imPos + ":");
+ logWindowList(windows, " ");
+ }
+ if (DN > 0) moveInputMethodDialogs(imPos+1);
+ } else {
+ moveInputMethodDialogs(imPos);
+ }
+
+ } else {
+ // In this case, the input method windows go in a fixed layer,
+ // because they aren't currently associated with a focus window.
+
+ if (imWin != null) {
+ if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Moving IM from " + imPos);
+ removeWindowAndChildrenFromWindowList(imWin, 0);
+ reAddToWindowList(imWin);
+ if (DEBUG_INPUT_METHOD) {
+ Slog.v(TAG_WM, "List with no IM target:");
+ logWindowList(windows, " ");
+ }
+ if (DN > 0) moveInputMethodDialogs(-1);
+ } else {
+ moveInputMethodDialogs(-1);
+ }
+
+ }
+
+ if (needAssignLayers) {
+ assignWindowLayers(false /* setLayoutNeeded */);
+ }
+
+ return true;
+ }
+
+ /**
+ * Dig through the WindowStates and find the one that the Input Method will target.
+ * @param willMove
+ * @return The index+1 in mWindows of the discovered target.
+ */
+ int findDesiredInputMethodWindowIndex(boolean willMove) {
+ // 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.
+ final WindowList windows = getWindowList();
+ WindowState w = null;
+ int i;
+ for (i = windows.size() - 1; i >= 0; --i) {
+ WindowState win = windows.get(i);
+
+ if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG_WM, "Checking window @" + i
+ + " " + win + " fl=0x" + Integer.toHexString(win.mAttrs.flags));
+ if (canBeImeTarget(win)) {
+ w = win;
+ //Slog.i(TAG_WM, "Putting input method here!");
+
+ // Yet more tricksyness! If this window is a "starting" window, we do actually want
+ // to be on top of it, but it is not -really- where input will go. So if the caller
+ // is not actually looking to move the IME, look down below for a real window to
+ // target...
+ if (!willMove && w.mAttrs.type == TYPE_APPLICATION_STARTING && i > 0) {
+ WindowState wb = windows.get(i-1);
+ if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
+ i--;
+ w = wb;
+ }
+ }
+ break;
+ }
+ }
+
+ // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
+
+ if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG_WM, "Proposed new IME target: " + w);
+
+ // 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;
+ if (curTarget != null
+ && curTarget.isDisplayedLw()
+ && curTarget.isClosing()
+ && (w == null || curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
+ if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Current target higher, not changing");
+ return windows.indexOf(curTarget) + 1;
+ }
+
+ if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Desired input method target="
+ + w + " willMove=" + willMove);
+
+ if (willMove && w != null) {
+ AppWindowToken token = curTarget == null ? null : curTarget.mAppToken;
+ if (token != null) {
+
+ // Now some fun for dealing with window animations that modify the Z order. We need
+ // to look at all windows below the current target that are in this app, finding the
+ // highest visible one in layering.
+ WindowState highestTarget = null;
+ int highestPos = 0;
+ if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
+ WindowList curWindows = token.getDisplayContent().getWindowList();
+ int pos = curWindows.indexOf(curTarget);
+ while (pos >= 0) {
+ WindowState win = curWindows.get(pos);
+ if (win.mAppToken != token) {
+ break;
+ }
+ if (!win.mRemoved) {
+ if (highestTarget == null || win.mWinAnimator.mAnimLayer >
+ highestTarget.mWinAnimator.mAnimLayer) {
+ highestTarget = win;
+ highestPos = pos;
+ }
+ }
+ pos--;
+ }
+ }
+
+ if (highestTarget != null) {
+ final AppTransition appTransition = mService.mAppTransition;
+ if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, appTransition + " " + highestTarget
+ + " animating=" + highestTarget.mWinAnimator.isAnimationSet()
+ + " layer=" + highestTarget.mWinAnimator.mAnimLayer
+ + " new layer=" + w.mWinAnimator.mAnimLayer);
+
+ if (appTransition.isTransitionSet()) {
+ // If we are currently setting up for an animation, hold everything until we
+ // can find out what will happen.
+ mService.mInputMethodTargetWaitingAnim = true;
+ mService.mInputMethodTarget = highestTarget;
+ return highestPos + 1;
+ } else if (highestTarget.mWinAnimator.isAnimationSet() &&
+ highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
+ // If the window we are currently targeting is involved with an animation,
+ // and it is on top of the next target we will be over, then hold off on
+ // moving until that is done.
+ mService.mInputMethodTargetWaitingAnim = true;
+ mService.mInputMethodTarget = highestTarget;
+ return highestPos + 1;
+ }
+ }
+ }
+ }
+
+ //Slog.i(TAG_WM, "Placing input method @" + (i+1));
+ if (w != null) {
+ if (willMove) {
+ if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to "
+ + w + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
+ mService.mInputMethodTarget = w;
+ mService.mInputMethodTargetWaitingAnim = false;
+ if (w.mAppToken != null) {
+ setInputMethodAnimLayerAdjustment(
+ w.mAppToken.mAppAnimator.animLayerAdjustment);
+ } else {
+ setInputMethodAnimLayerAdjustment(0);
+ }
+ }
+
+ // If the docked divider is visible, we still need to go through this whole excercise to
+ // find the appropriate input method target (used for animations and dialog
+ // adjustments), but for purposes of Z ordering we simply wish to place it above the
+ // docked divider. Unless it is already above the divider.
+ final WindowState dockedDivider = mDividerControllerLocked.getWindow();
+ if (dockedDivider != null && dockedDivider.isVisibleLw()) {
+ int dividerIndex = windows.indexOf(dockedDivider);
+ if (dividerIndex > 0 && dividerIndex > i) {
+ return dividerIndex + 1;
+ }
+ }
+ return i+1;
+ }
+ if (willMove) {
+ if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget
+ + " to null." + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
+ mService.mInputMethodTarget = null;
+ setInputMethodAnimLayerAdjustment(0);
+ }
+ return -1;
+ }
+
+ private static boolean canBeImeTarget(WindowState w) {
+ final int fl = w.mAttrs.flags & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
+ final int type = w.mAttrs.type;
+
+ if (fl != 0 && fl != (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM)
+ && type != TYPE_APPLICATION_STARTING) {
+ return false;
+ }
+
+ if (DEBUG_INPUT_METHOD) {
+ Slog.i(TAG_WM, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
+ if (!w.isVisibleOrAdding()) {
+ Slog.i(TAG_WM, " mSurfaceController=" + w.mWinAnimator.mSurfaceController
+ + " relayoutCalled=" + w.mRelayoutCalled
+ + " viewVis=" + w.mViewVisibility
+ + " policyVis=" + w.mPolicyVisibility
+ + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
+ + " parentHidden=" + w.isParentWindowHidden()
+ + " exiting=" + w.mAnimatingExit + " destroying=" + w.mDestroying);
+ if (w.mAppToken != null) {
+ Slog.i(TAG_WM, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
+ }
+ }
+ }
+ return w.isVisibleOrAdding();
+ }
+
+ private void logWindowList(final WindowList windows, String prefix) {
+ int N = windows.size();
+ while (N > 0) {
+ N--;
+ Slog.v(TAG_WM, prefix + "#" + N + ": " + windows.get(N));
+ }
+ }
+
+ boolean getNeedsMenu(WindowState win, WindowManagerPolicy.WindowState bottom) {
+ int index = -1;
+ WindowList windows = getWindowList();
+ while (true) {
+ if (win.mAttrs.needsMenuKey != NEEDS_MENU_UNSET) {
+ return win.mAttrs.needsMenuKey == NEEDS_MENU_SET_TRUE;
+ }
+ // If we reached the bottom of the range of windows we are considering,
+ // assume no menu is needed.
+ if (win == bottom) {
+ return false;
+ }
+ // The current window hasn't specified whether menu key is needed; look behind it.
+ // First, we may need to determine the starting position.
+ if (index < 0) {
+ index = windows.indexOf(win);
+ }
+ index--;
+ if (index < 0) {
+ return false;
+ }
+ win = windows.get(index);
+ }
+ }
+
void setLayoutNeeded() {
if (DEBUG_LAYOUT) Slog.w(TAG_WM, "setLayoutNeeded: callers=" + Debug.getCallers(3));
mLayoutNeeded = true;
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 7c39bd28fdf8..9effb8dc6c0a 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -35,6 +35,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.H.RESIZE_STACK;
+import static com.android.server.wm.WindowManagerService.LAYER_OFFSET_DIM;
import android.app.ActivityManager.StackId;
import android.content.res.Configuration;
@@ -802,8 +803,8 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye
if (mAnimationBackgroundAnimator == null
|| animLayer < mAnimationBackgroundAnimator.mAnimLayer) {
mAnimationBackgroundAnimator = winAnimator;
- animLayer = mService.adjustAnimationBackground(winAnimator);
- mAnimationBackgroundSurface.show(animLayer - WindowManagerService.LAYER_OFFSET_DIM,
+ animLayer = mDisplayContent.getLayerForAnimationBackground(winAnimator);
+ mAnimationBackgroundSurface.show(animLayer - LAYER_OFFSET_DIM,
((color >> 24) & 0xff) / 255f, 0);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2b5603dedc5a..d6320140ffd8 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -607,6 +607,16 @@ public class WindowManagerService extends IWindowManager.Stub
boolean mInputMethodTargetWaitingAnim;
WindowState mInputMethodWindow = null;
+ // TODO: Remove with extreme prejudice! This list is maintained so that we can keep track of
+ // dialogs that should go on top of the IME so they can be re-arranged in the window list any
+ // time the IME changes position in the window list. Normally you would have a dialog be a child
+ // window of the IME, but they don't share the same token since they are added by different
+ // clients. This doesn't really affect what the user sees on screen since this dialogs have an
+ // higher base layer than the IME window, but it will affect users of the window list that
+ // expect the list to represent the order of things on-screen (e.g input service). This makes
+ // the code for managing the window list hard to follow (see all the places it is used).
+ // We can remove the use of this field when we automatically assign layers and z-order the
+ // window list before it is used whenever window container order changes.
final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<>();
/** Temporary list for comparison. Always clear this after use so we don't end up with
@@ -1087,354 +1097,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- static boolean canBeImeTarget(WindowState w) {
- final int fl = w.mAttrs.flags
- & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
- final int type = w.mAttrs.type;
- if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)
- || type == TYPE_APPLICATION_STARTING) {
- if (DEBUG_INPUT_METHOD) {
- Slog.i(TAG_WM, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
- if (!w.isVisibleOrAdding()) {
- Slog.i(TAG_WM, " mSurfaceController=" + w.mWinAnimator.mSurfaceController
- + " relayoutCalled=" + w.mRelayoutCalled
- + " viewVis=" + w.mViewVisibility
- + " policyVis=" + w.mPolicyVisibility
- + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
- + " parentHidden=" + w.isParentWindowHidden()
- + " exiting=" + w.mAnimatingExit + " destroying=" + w.mDestroying);
- if (w.mAppToken != null) {
- Slog.i(TAG_WM, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
- }
- }
- }
- return w.isVisibleOrAdding();
- }
- return false;
- }
-
- /**
- * Dig through the WindowStates and find the one that the Input Method will target.
- * @param willMove
- * @return The index+1 in mWindows of the discovered target.
- */
- int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
- // 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.
- final DisplayContent dc = getDefaultDisplayContentLocked();
- final WindowList windows = dc.getWindowList();
- WindowState w = null;
- int i;
- for (i = windows.size() - 1; i >= 0; --i) {
- WindowState win = windows.get(i);
-
- if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG_WM, "Checking window @" + i
- + " " + win + " fl=0x" + Integer.toHexString(win.mAttrs.flags));
- if (canBeImeTarget(win)) {
- w = win;
- //Slog.i(TAG_WM, "Putting input method here!");
-
- // Yet more tricksyness! If this window is a "starting"
- // window, we do actually want to be on top of it, but
- // it is not -really- where input will go. So if the caller
- // is not actually looking to move the IME, look down below
- // for a real window to target...
- if (!willMove
- && w.mAttrs.type == TYPE_APPLICATION_STARTING
- && i > 0) {
- WindowState wb = windows.get(i-1);
- if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
- i--;
- w = wb;
- }
- }
- break;
- }
- }
-
- // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
-
- if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG_WM, "Proposed new IME target: " + w);
-
- // 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 = mInputMethodTarget;
- if (curTarget != null
- && curTarget.isDisplayedLw()
- && curTarget.isClosing()
- && (w == null || curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
- if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Current target higher, not changing");
- return windows.indexOf(curTarget) + 1;
- }
-
- if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Desired input method target="
- + w + " willMove=" + willMove);
-
- if (willMove && w != null) {
- AppWindowToken token = curTarget == null ? null : curTarget.mAppToken;
- if (token != null) {
-
- // Now some fun for dealing with window animations that
- // modify the Z order. We need to look at all windows below
- // the current target that are in this app, finding the highest
- // visible one in layering.
- WindowState highestTarget = null;
- int highestPos = 0;
- if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
- WindowList curWindows = token.getDisplayContent().getWindowList();
- int pos = curWindows.indexOf(curTarget);
- while (pos >= 0) {
- WindowState win = curWindows.get(pos);
- if (win.mAppToken != token) {
- break;
- }
- if (!win.mRemoved) {
- if (highestTarget == null || win.mWinAnimator.mAnimLayer >
- highestTarget.mWinAnimator.mAnimLayer) {
- highestTarget = win;
- highestPos = pos;
- }
- }
- pos--;
- }
- }
-
- if (highestTarget != null) {
- if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, mAppTransition + " " + highestTarget
- + " animating=" + highestTarget.mWinAnimator.isAnimationSet()
- + " layer=" + highestTarget.mWinAnimator.mAnimLayer
- + " new layer=" + w.mWinAnimator.mAnimLayer);
-
- if (mAppTransition.isTransitionSet()) {
- // If we are currently setting up for an animation,
- // hold everything until we can find out what will happen.
- mInputMethodTargetWaitingAnim = true;
- mInputMethodTarget = highestTarget;
- return highestPos + 1;
- } else if (highestTarget.mWinAnimator.isAnimationSet() &&
- highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
- // If the window we are currently targeting is involved
- // with an animation, and it is on top of the next target
- // we will be over, then hold off on moving until
- // that is done.
- mInputMethodTargetWaitingAnim = true;
- mInputMethodTarget = highestTarget;
- return highestPos + 1;
- }
- }
- }
- }
-
- //Slog.i(TAG_WM, "Placing input method @" + (i+1));
- if (w != null) {
- if (willMove) {
- if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to "
- + w + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
- mInputMethodTarget = w;
- mInputMethodTargetWaitingAnim = false;
- if (w.mAppToken != null) {
- dc.setInputMethodAnimLayerAdjustment(
- w.mAppToken.mAppAnimator.animLayerAdjustment);
- } else {
- dc.setInputMethodAnimLayerAdjustment(0);
- }
- }
-
- // If the docked divider is visible, we still need to go through this whole
- // excercise to find the appropriate input method target (used for animations
- // and dialog adjustments), but for purposes of Z ordering we simply wish to
- // place it above the docked divider. Unless it is already above the divider.
- final WindowState dockedDivider =
- w.getDisplayContent().mDividerControllerLocked.getWindow();
- if (dockedDivider != null && dockedDivider.isVisibleLw()) {
- int dividerIndex = windows.indexOf(dockedDivider);
- if (dividerIndex > 0 && dividerIndex > i) {
- return dividerIndex + 1;
- }
- }
- return i+1;
- }
- if (willMove) {
- if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to null."
- + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
- mInputMethodTarget = null;
- dc.setInputMethodAnimLayerAdjustment(0);
- }
- return -1;
- }
-
- private void reAddWindowToListInOrderLocked(WindowState win) {
- win.mToken.addWindow(win);
- // This is a hack to get all of the child windows added as well at the right position. Child
- // windows should be rare and this case should be rare, so it shouldn't be that big a deal.
- WindowList windows = win.getWindowList();
- int wpos = windows.indexOf(win);
- if (wpos >= 0) {
- if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "ReAdd removing from " + wpos + ": " + win);
- windows.remove(wpos);
- mWindowsChanged = true;
- win.reAddWindow(wpos);
- }
- }
-
- private void logWindowList(final WindowList windows, String prefix) {
- int N = windows.size();
- while (N > 0) {
- N--;
- Slog.v(TAG_WM, prefix + "#" + N + ": " + windows.get(N));
- }
- }
-
- void moveInputMethodDialogsLocked(int pos) {
- ArrayList<WindowState> dialogs = mInputMethodDialogs;
-
- // TODO(multidisplay): IMEs are only supported on the default display.
- WindowList windows = getDefaultWindowListLocked();
- final int N = dialogs.size();
- if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Removing " + N + " dialogs w/pos=" + pos);
- for (int i=0; i<N; i++) {
- pos = dialogs.get(i).removeFromWindowList(pos);
- }
- if (DEBUG_INPUT_METHOD) {
- Slog.v(TAG_WM, "Window list w/pos=" + pos);
- logWindowList(windows, " ");
- }
-
- if (pos >= 0) {
- // Skip windows owned by the input method.
- if (mInputMethodWindow != null) {
- while (pos < windows.size()) {
- WindowState wp = windows.get(pos);
- if (wp == mInputMethodWindow || wp.getParentWindow() == mInputMethodWindow) {
- pos++;
- continue;
- }
- break;
- }
- }
- if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Adding " + N + " dialogs at pos=" + pos);
- for (int i=0; i<N; i++) {
- WindowState win = dialogs.get(i);
- pos = win.reAddWindow(pos);
- }
- if (DEBUG_INPUT_METHOD) {
- Slog.v(TAG_WM, "Final window list:");
- logWindowList(windows, " ");
- }
- return;
- }
- for (int i=0; i<N; i++) {
- WindowState win = dialogs.get(i);
- reAddWindowToListInOrderLocked(win);
- if (DEBUG_INPUT_METHOD) {
- Slog.v(TAG_WM, "No IM target, final list:");
- logWindowList(windows, " ");
- }
- }
- }
-
- boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
- final WindowState imWin = mInputMethodWindow;
- final int DN = mInputMethodDialogs.size();
- if (imWin == null && DN == 0) {
- return false;
- }
-
- // TODO(multidisplay): IMEs are only supported on the default display.
- WindowList windows = getDefaultWindowListLocked();
-
- int imPos = findDesiredInputMethodWindowIndexLocked(true);
- if (imPos >= 0) {
- // In this case, the input method windows are to be placed
- // immediately above the window they are targeting.
-
- // First check to see if the input method windows are already
- // located here, and contiguous.
- final int N = windows.size();
- final WindowState firstImWin = imPos < N ? windows.get(imPos) : null;
-
- // Figure out the actual input method window that should be
- // at the bottom of their stack.
- WindowState baseImWin = imWin != null ? imWin : mInputMethodDialogs.get(0);
- final WindowState cw = baseImWin.getBottomChild();
- if (cw != null && cw.mSubLayer < 0) {
- baseImWin = cw;
- }
-
- if (firstImWin == baseImWin) {
- // The windows haven't moved... but are they still contiguous?
- // First find the top IM window.
- int pos = imPos+1;
- while (pos < N) {
- if (!(windows.get(pos)).mIsImWindow) {
- break;
- }
- pos++;
- }
- pos++;
- // Now there should be no more input method windows above.
- while (pos < N) {
- if ((windows.get(pos)).mIsImWindow) {
- break;
- }
- pos++;
- }
- if (pos >= N) {
- return false;
- }
- }
-
- if (imWin != null) {
- if (DEBUG_INPUT_METHOD) {
- Slog.v(TAG_WM, "Moving IM from " + imPos);
- logWindowList(windows, " ");
- }
- imPos = imWin.removeFromWindowList(imPos);
- if (DEBUG_INPUT_METHOD) {
- Slog.v(TAG_WM, "List after removing with new pos " + imPos + ":");
- logWindowList(windows, " ");
- }
- imWin.reAddWindow(imPos);
- if (DEBUG_INPUT_METHOD) {
- Slog.v(TAG_WM, "List after moving IM to " + imPos + ":");
- logWindowList(windows, " ");
- }
- if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
- } else {
- moveInputMethodDialogsLocked(imPos);
- }
-
- } else {
- // In this case, the input method windows go in a fixed layer,
- // because they aren't currently associated with a focus window.
-
- if (imWin != null) {
- if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Moving IM from " + imPos);
- imWin.removeFromWindowList(0);
- reAddWindowToListInOrderLocked(imWin);
- if (DEBUG_INPUT_METHOD) {
- Slog.v(TAG_WM, "List with no IM target:");
- logWindowList(windows, " ");
- }
- if (DN > 0) moveInputMethodDialogsLocked(-1);
- } else {
- moveInputMethodDialogsLocked(-1);
- }
-
- }
-
- if (needAssignLayers) {
- getDefaultDisplayContentLocked().assignWindowLayers(false /* setLayoutNeeded */);
- }
-
- return true;
- }
-
static boolean excludeWindowTypeFromTapOutTask(int windowType) {
switch (windowType) {
case TYPE_STATUS_BAR:
@@ -1728,7 +1390,8 @@ public class WindowManagerService extends IWindowManager.Stub
} else if (type == TYPE_INPUT_METHOD_DIALOG) {
mInputMethodDialogs.add(win);
win.mToken.addWindow(win);
- moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
+ displayContent.moveInputMethodDialogs(
+ displayContent.findDesiredInputMethodWindowIndex(true));
imMayMove = false;
} else {
win.mToken.addWindow(win);
@@ -1804,7 +1467,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
if (imMayMove) {
- moveInputMethodWindowsIfNeededLocked(false);
+ displayContent.moveInputMethodWindowsIfNeeded(false);
}
// Don't do layout here, the window must call
@@ -2018,11 +1681,10 @@ public class WindowManagerService extends IWindowManager.Stub
getDefaultDisplayContentLocked().pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
}
- final WindowList windows = win.getWindowList();
- if (windows != null) {
- windows.remove(win);
+ final DisplayContent dc = win.getDisplayContent();
+ if (dc != null && dc.removeFromWindowList(win)) {
if (!mWindowPlacerLocked.isInLayout()) {
- win.getDisplayContent().assignWindowLayers(true /* setLayoutNeeded */);
+ dc.assignWindowLayers(true /* setLayoutNeeded */);
mWindowPlacerLocked.performSurfacePlacement();
if (win.mAppToken != null) {
win.mAppToken.updateReportedVisibilityLocked();
@@ -2033,7 +1695,7 @@ public class WindowManagerService extends IWindowManager.Stub
mInputMonitor.updateInputWindowsLw(true /*force*/);
}
- public void updateAppOpsState() {
+ private void updateAppOpsState() {
synchronized(mWindowMap) {
mRoot.updateAppOpsState();
}
@@ -2394,13 +2056,15 @@ public class WindowManagerService extends IWindowManager.Stub
// updateFocusedWindowLocked() already assigned layers so we only need to
// reassign them at this point if the IM window state gets shuffled
boolean toBeDisplayed = (result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0;
- if (imMayMove && (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed)) {
- // Little hack here -- we -should- be able to rely on the
- // function to return true if the IME has moved and needs
- // its layer recomputed. However, if the IME was hidden
- // and isn't actually moved in the list, its layer may be
- // out of data so we make sure to recompute it.
- win.getDisplayContent().assignWindowLayers(false /* setLayoutNeeded */);
+ final DisplayContent dc = win.getDisplayContent();
+ if (imMayMove && (dc.moveInputMethodWindowsIfNeeded(false) || toBeDisplayed)) {
+ // Little hack here -- we -should- be able to rely on the function to return true if
+ // the IME has moved and needs its layer recomputed. However, if the IME was hidden
+ // and isn't actually moved in the list, its layer may be out of data so we make
+ // sure to recompute it.
+ // TODO: Probably not needed once the window list always has the right z-ordering
+ // when the window hierarchy is updated.
+ dc.assignWindowLayers(false /* setLayoutNeeded */);
}
if (wallpaperMayMove) {
@@ -7487,7 +7151,8 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized (mWindowMap) {
// The focus for the client is the window immediately below
// where we would place the input method window.
- int idx = findDesiredInputMethodWindowIndexLocked(false);
+ // TODO: multi-display
+ int idx = getDefaultDisplayContentLocked().findDesiredInputMethodWindowIndex(false);
if (idx > 0) {
// TODO(multidisplay): IMEs are only supported on the default display.
WindowState imFocus = getDefaultWindowListLocked().get(idx-1);
@@ -7964,12 +7629,14 @@ public class WindowManagerService extends IWindowManager.Stub
mWallpaperControllerLocked.hideDeferredWallpapersIfNeeded();
- getDefaultDisplayContentLocked().onAppTransitionDone();
+ // TODO: multi-display.
+ final DisplayContent dc = getDefaultDisplayContentLocked();
+ dc.onAppTransitionDone();
changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG_WM,
"Wallpaper layer changed: assigning layers + relayout");
- moveInputMethodWindowsIfNeededLocked(true);
+ dc.moveInputMethodWindowsIfNeeded(true);
mRoot.mWallpaperMayChange = true;
// Since the window list has been rebuilt, focus might have to be recomputed since the
// actual order of windows might have changed again.
@@ -8051,20 +7718,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- /** If a window that has an animation specifying a colored background and the current wallpaper
- * is visible, then the color goes *below* the wallpaper so we don't cause the wallpaper to
- * suddenly disappear. */
- int adjustAnimationBackground(WindowStateAnimator winAnimator) {
- WindowList windows = winAnimator.mWin.getWindowList();
- for (int i = windows.size() - 1; i >= 0; --i) {
- WindowState testWin = windows.get(i);
- if (testWin.mIsWallpaper && testWin.isVisibleNow()) {
- return testWin.mWinAnimator.mAnimLayer;
- }
- }
- return winAnimator.mAnimLayer;
- }
-
boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
WindowState newFocus = mRoot.computeFocusedWindow();
if (mCurrentFocus != newFocus) {
@@ -8075,7 +7728,7 @@ public class WindowManagerService extends IWindowManager.Stub
mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
// TODO(multidisplay): Focused windows on default display only.
final DisplayContent displayContent = getDefaultDisplayContentLocked();
- final boolean imWindowChanged = moveInputMethodWindowsIfNeededLocked(
+ final boolean imWindowChanged = displayContent.moveInputMethodWindowsIfNeeded(
mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS
&& mode != UPDATE_FOCUS_WILL_PLACE_SURFACES);
if (imWindowChanged) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 617c1450e8df..e2c608f6e8a2 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -86,7 +86,6 @@ import static android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH;
@@ -1009,30 +1008,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
@Override
public boolean getNeedsMenuLw(WindowManagerPolicy.WindowState bottom) {
- int index = -1;
- WindowState ws = this;
- WindowList windows = getWindowList();
- while (true) {
- if (ws.mAttrs.needsMenuKey != WindowManager.LayoutParams.NEEDS_MENU_UNSET) {
- return ws.mAttrs.needsMenuKey == WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE;
- }
- // If we reached the bottom of the range of windows we are considering,
- // assume no menu is needed.
- if (ws == bottom) {
- return false;
- }
- // The current window hasn't specified whether menu key is needed;
- // look behind it.
- // First, we may need to determine the starting position.
- if (index < 0) {
- index = windows.indexOf(ws);
- }
- index--;
- if (index < 0) {
- return false;
- }
- ws = windows.get(index);
- }
+ return getDisplayContent().getNeedsMenu(this, bottom);
}
@Override
@@ -1784,14 +1760,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mReplacementWindow.mSkipEnterAnimationForSeamlessReplacement = false;
}
+ final DisplayContent dc = getDisplayContent();
if (mService.mInputMethodTarget == this) {
- mService.moveInputMethodWindowsIfNeededLocked(false);
+ dc.moveInputMethodWindowsIfNeeded(false);
}
final int type = mAttrs.type;
if (WindowManagerService.excludeWindowTypeFromTapOutTask(type)) {
- final DisplayContent displaycontent = getDisplayContent();
- displaycontent.mTapExcludedWindows.remove(this);
+ dc.mTapExcludedWindows.remove(this);
}
mPolicy.removeWindowLw(this);
@@ -2959,8 +2935,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
applyInsets(outRegion, frame, mGivenVisibleInsets);
break;
case TOUCHABLE_INSETS_REGION: {
- final Region givenTouchableRegion = mGivenTouchableRegion;
- outRegion.set(givenTouchableRegion);
+ outRegion.set(mGivenTouchableRegion);
outRegion.translate(frame.left, frame.top);
break;
}
@@ -2968,7 +2943,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
cropRegionToStackBoundsIfNeeded(outRegion);
}
- void cropRegionToStackBoundsIfNeeded(Region region) {
+ private void cropRegionToStackBoundsIfNeeded(Region region) {
final Task task = getTask();
if (task == null || !task.cropWindowsToStackBounds()) {
return;
@@ -2983,13 +2958,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
region.op(mTmpRect, Region.Op.INTERSECT);
}
- // TODO: This is one reason why WindowList are bad...prime candidate for removal once we
- // figure-out a good way to replace WindowList with WindowContainer hierarchy.
- WindowList getWindowList() {
- final DisplayContent displayContent = getDisplayContent();
- return displayContent == null ? null : displayContent.getWindowList();
- }
-
/**
* Report a focus change. Must be called with no locks held, and consistently
* from the same serialized thread (such as dispatched from a handler).
@@ -3878,7 +3846,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// Or, it is probably not going to matter anyways if we are successful in getting rid of
// the WindowList concept.
int reAddWindow(int index) {
- final WindowList windows = getWindowList();
+ final DisplayContent dc = getDisplayContent();
// Adding child windows relies on child windows being ordered by mSubLayer using
// {@link #sWindowSubLayerComparator}.
final int childCount = mChildren.size();
@@ -3889,51 +3857,25 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM,
"Re-adding child window at " + index + ": " + child);
mRebuilding = false;
- windows.add(index, this);
+ dc.addToWindowList(this, index);
index++;
winAdded = true;
}
if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Re-adding window at " + index + ": " + child);
child.mRebuilding = false;
- windows.add(index, child);
+ dc.addToWindowList(child, index);
index++;
}
if (!winAdded) {
if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Re-adding window at " + index + ": " + this);
mRebuilding = false;
- windows.add(index, this);
+ dc.addToWindowList(this, index);
index++;
}
mService.mWindowsChanged = true;
return index;
}
- int removeFromWindowList(int interestingPos) {
- final WindowList windows = getWindowList();
- int wpos = windows.indexOf(this);
- if (wpos < 0) {
- return interestingPos;
- }
-
- if (wpos < interestingPos) interestingPos--;
- if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Temp removing at " + wpos + ": " + this);
- windows.remove(wpos);
- mService.mWindowsChanged = true;
- int childCount = mChildren.size();
- while (childCount > 0) {
- childCount--;
- final WindowState cw = mChildren.get(childCount);
- int cpos = windows.indexOf(cw);
- if (cpos >= 0) {
- if (cpos < interestingPos) interestingPos--;
- if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM,
- "Temp removing child at " + cpos + ": " + cw);
- windows.remove(cpos);
- }
- }
- return interestingPos;
- }
-
boolean isWindowAnimationSet() {
if (mWinAnimator.isWindowAnimationSet()) {
return true;
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 336bc68932ae..352224036ab2 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -530,9 +530,11 @@ class WindowSurfacePlacer {
displayContent.setLayoutNeeded();
// TODO(multidisplay): IMEs are only supported on the default display.
- if (windows == mService.getDefaultWindowListLocked()
- && !mService.moveInputMethodWindowsIfNeededLocked(true)) {
- mService.getDefaultDisplayContentLocked().assignWindowLayers(false /*setLayoutNeeded*/);
+ // TODO: Probably not needed once the window list always has the right z-ordering
+ // when the window hierarchy is updated.
+ final DisplayContent dc = mService.getDefaultDisplayContentLocked();
+ if (windows == dc.getWindowList() && !dc.moveInputMethodWindowsIfNeeded(true)) {
+ dc.assignWindowLayers(false /*setLayoutNeeded*/);
}
mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
true /*updateInputWindows*/);
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 862e8f02eaf7..47366685b44e 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -188,11 +188,11 @@ class WindowToken extends WindowContainer<WindowState> {
}
void addImeWindow(WindowState win) {
- int pos = mService.findDesiredInputMethodWindowIndexLocked(true);
+ int pos = mDisplayContent.findDesiredInputMethodWindowIndex(true);
if (pos < 0) {
addWindow(win);
- mService.moveInputMethodDialogsLocked(pos);
+ mDisplayContent.moveInputMethodDialogs(pos);
return;
}
@@ -203,7 +203,7 @@ class WindowToken extends WindowContainer<WindowState> {
addChild(win, null);
}
mService.mWindowsChanged = true;
- mService.moveInputMethodDialogsLocked(pos + 1);
+ mDisplayContent.moveInputMethodDialogs(pos + 1);
}
/** Return the first window in the token window list that isn't a starting window or null. */