summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java186
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowToken.java28
3 files changed, 121 insertions, 97 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 7f944454ecdf..f35a7e623665 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -70,7 +70,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFI
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_BOOT_PROGRESS;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
@@ -304,8 +303,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
// on the IME target. We mainly have this container grouping so we can keep track of all the IME
// window containers together and move them in-sync if/when needed. We use a subclass of
// WindowContainer which is omitted from screen magnification, as the IME is never magnified.
- private final NonAppWindowContainers mImeWindowsContainers =
- new NonAppWindowContainers("mImeWindowsContainers", mWmService);
+ // TODO(display-area): is "no magnification" in the comment still true?
+ private final ImeContainer mImeWindowsContainers = new ImeContainer(mWmService);
private WindowState mTmpWindow;
private WindowState mTmpWindow2;
@@ -1995,6 +1994,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
return mTaskStackContainers.getVisibleTasks();
}
+ SurfaceControl getSplitScreenDividerAnchor() {
+ return mTaskStackContainers.getSplitScreenDividerAnchor();
+ }
+
void onStackWindowingModeChanged(ActivityStack stack) {
mTaskStackContainers.onStackWindowingModeChanged(stack);
}
@@ -2081,7 +2084,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
boolean forAllImeWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
- return mImeWindowsContainers.forAllWindows(callback, traverseTopToBottom);
+ return mImeWindowsContainers.forAllWindowForce(callback, traverseTopToBottom);
}
/**
@@ -2339,11 +2342,15 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
throw new UnsupportedOperationException("See DisplayChildWindowContainer");
}
+ void positionDisplayAt(int position, boolean includingParents) {
+ getParent().positionChildAt(position, this, includingParents);
+ }
+
@Override
void positionChildAt(int position, DisplayChildWindowContainer child, boolean includingParents) {
// Children of the display are statically ordered, so the real intention here is to perform
// the operation on the display and not the static direct children.
- getParent().positionChildAt(position, this, includingParents);
+ positionDisplayAt(position, includingParents);
}
void positionStackAt(int position, ActivityStack child, boolean includingParents) {
@@ -4289,8 +4296,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
@Override
void positionChildAt(int position, ActivityStack child, boolean includingParents) {
- if (child.getWindowConfiguration().isAlwaysOnTop()
- && position != POSITION_TOP && position != mChildren.size()) {
+ final boolean moveToTop = (position == POSITION_TOP || position == getChildCount());
+ final boolean moveToBottom = (position == POSITION_BOTTOM || position == 0);
+ if (child.getWindowConfiguration().isAlwaysOnTop() && !moveToTop) {
// This stack is always-on-top, override the default behavior.
Slog.w(TAG_WM, "Ignoring move of always-on-top stack=" + this + " to bottom");
@@ -4306,18 +4314,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
includingParents = false;
}
final int targetPosition = findPositionForStack(position, child, false /* adding */);
- super.positionChildAt(targetPosition, child, includingParents);
-
- if (includingParents) {
- // We still want to move the display of this stack container to top because even the
- // target position is adjusted to non-top, the intention of the condition is to have
- // higher z-order to gain focus (e.g. moving a task of a fullscreen stack to front
- // in a non-top display which is using picture-in-picture mode).
- final int topChildPosition = getChildCount() - 1;
- if (targetPosition < topChildPosition && position >= topChildPosition) {
- getParent().positionChildAt(POSITION_TOP, this /* child */,
- true /* includingParents */);
- }
+ super.positionChildAt(targetPosition, child, false /* includingParents */);
+
+ if (includingParents && (moveToTop || moveToBottom)) {
+ // The DisplayContent children do not re-order, but we still want to move the
+ // display of this stack container because the intention of positioning is to have
+ // higher z-order to gain focus.
+ positionDisplayAt(moveToTop ? POSITION_TOP : POSITION_BOTTOM,
+ true /* includingParents */);
}
setLayoutNeeded();
@@ -4637,38 +4641,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
@Override
- SurfaceControl.Builder makeChildSurface(WindowContainer child) {
- final SurfaceControl.Builder builder = super.makeChildSurface(child);
- if (child instanceof WindowToken && ((WindowToken) child).mRoundedCornerOverlay) {
- // To draw above the ColorFade layer during the screen off transition, the
- // rounded corner overlays need to be at the root of the surface hierarchy.
- // TODO: move the ColorLayer into the display overlay layer such that this is not
- // necessary anymore.
- builder.setParent(null);
- }
- return builder;
- }
-
- @Override
void assignChildLayers(SurfaceControl.Transaction t) {
- assignChildLayers(t, null /* imeContainer */);
- }
-
- void assignChildLayers(SurfaceControl.Transaction t, WindowContainer imeContainer) {
- boolean needAssignIme = imeContainer != null
- && imeContainer.getSurfaceControl() != null;
+ boolean needAssignIme = mImeWindowsContainers.getSurfaceControl() != null;
for (int j = 0; j < mChildren.size(); ++j) {
final WindowToken wt = mChildren.get(j);
- // See {@link mSplitScreenDividerAnchor}
- if (wt.windowType == TYPE_DOCK_DIVIDER) {
- wt.assignRelativeLayer(t, mTaskStackContainers.getSplitScreenDividerAnchor(), 1);
- continue;
- }
- if (wt.mRoundedCornerOverlay) {
- wt.assignLayer(t, WindowManagerPolicy.COLOR_FADE_LAYER + 1);
- continue;
- }
wt.assignLayer(t, j);
wt.assignChildLayers(t);
@@ -4677,13 +4654,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
if (needAssignIme && layer >= mWmService.mPolicy.getWindowLayerFromTypeLw(
TYPE_INPUT_METHOD_DIALOG, true)) {
- imeContainer.assignRelativeLayer(t, wt.getSurfaceControl(), -1);
+ mImeWindowsContainers.assignRelativeLayer(t, wt.getSurfaceControl(), -1);
needAssignIme = false;
}
}
- if (needAssignIme) {
- imeContainer.assignRelativeLayer(t, getSurfaceControl(), Integer.MAX_VALUE);
- }
}
}
@@ -4697,6 +4671,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
@Override
void assignChildLayers(SurfaceControl.Transaction t) {
+ mImeWindowsContainers.setNeedsLayer();
mBelowAppWindowsContainers.assignLayer(t, 0);
mTaskStackContainers.assignLayer(t, 1);
mAboveAppWindowsContainers.assignLayer(t, 2);
@@ -4732,15 +4707,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
// TODO: We need to use an extra level on the app surface to ensure
// this is always above SurfaceView but always below attached window.
1);
- needAssignIme = false;
}
// Above we have assigned layers to our children, now we ask them to assign
// layers to their children.
mBelowAppWindowsContainers.assignChildLayers(t);
mTaskStackContainers.assignChildLayers(t);
- mAboveAppWindowsContainers.assignChildLayers(t,
- needAssignIme ? mImeWindowsContainers : null);
+ mAboveAppWindowsContainers.assignChildLayers(t);
+ mImeWindowsContainers.assignRelativeLayer(t, getSurfaceControl(), Integer.MAX_VALUE);
mImeWindowsContainers.assignChildLayers(t);
}
@@ -4756,47 +4730,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
addChild(mImeWindowsContainers, null);
}
- /**
- * In split-screen mode we process the IME containers above the docked divider
- * rather than directly above their target.
- */
- private boolean skipTraverseChild(WindowContainer child) {
- return child == mImeWindowsContainers && mInputMethodTarget != null
- && !hasSplitScreenPrimaryStack();
- }
-
- @Override
- boolean forAllWindows(ToBooleanFunction<WindowState> callback,
- boolean traverseTopToBottom) {
- // Special handling so we can process IME windows with #forAllImeWindows above their IME
- // target, or here in order if there isn't an IME target.
- if (traverseTopToBottom) {
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final WindowContainer child = mChildren.get(i);
- if (skipTraverseChild(child)) {
- continue;
- }
-
- if (child.forAllWindows(callback, traverseTopToBottom)) {
- return true;
- }
- }
- } else {
- final int count = mChildren.size();
- for (int i = 0; i < count; i++) {
- final WindowContainer child = mChildren.get(i);
- if (skipTraverseChild(child)) {
- continue;
- }
-
- if (child.forAllWindows(callback, traverseTopToBottom)) {
- return true;
- }
- }
- }
- return false;
- }
-
@Override
void positionChildAt(int position, WindowContainer child, boolean includingParents) {
// Children of the WindowContainers are statically ordered, so the real intention here
@@ -4910,6 +4843,68 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
}
+ /**
+ * Container for IME windows.
+ *
+ * This has some special behaviors:
+ * - layers assignment is ignored except if setNeedsLayer() has been called before (and no
+ * layer has been assigned since), to facilitate assigning the layer from the IME target, or
+ * fall back if there is no target.
+ * - the container doesn't always participate in window traversal, according to
+ * {@link #skipImeWindowsDuringTraversal()}
+ */
+ private class ImeContainer extends NonAppWindowContainers {
+ boolean mNeedsLayer = false;
+
+ ImeContainer(WindowManagerService wms) {
+ super("ImeContainer", wms);
+ }
+
+ public void setNeedsLayer() {
+ mNeedsLayer = true;
+ }
+
+ @Override
+ boolean forAllWindows(ToBooleanFunction<WindowState> callback,
+ boolean traverseTopToBottom) {
+ final DisplayContent dc = mDisplayContent;
+ if (skipImeWindowsDuringTraversal(dc)) {
+ return false;
+ }
+ return super.forAllWindows(callback, traverseTopToBottom);
+ }
+
+ private boolean skipImeWindowsDuringTraversal(DisplayContent dc) {
+ // We skip IME windows so they're processed just above their target, except
+ // in split-screen mode where we process the IME containers above the docked divider.
+ return dc.mInputMethodTarget != null && !dc.hasSplitScreenPrimaryStack();
+ }
+
+ /** Like {@link #forAllWindows}, but ignores {@link #skipImeWindowsDuringTraversal} */
+ boolean forAllWindowForce(ToBooleanFunction<WindowState> callback,
+ boolean traverseTopToBottom) {
+ return super.forAllWindows(callback, traverseTopToBottom);
+ }
+
+ @Override
+ void assignLayer(Transaction t, int layer) {
+ if (!mNeedsLayer) {
+ return;
+ }
+ super.assignLayer(t, layer);
+ mNeedsLayer = false;
+ }
+
+ @Override
+ void assignRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
+ if (!mNeedsLayer) {
+ return;
+ }
+ super.assignRelativeLayer(t, relativeTo, layer);
+ mNeedsLayer = false;
+ }
+ }
+
@Override
SurfaceSession getSession() {
return mSession;
@@ -5013,6 +5008,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
* with {@link WindowState#assignLayer}
*/
void assignRelativeLayerForImeTargetChild(SurfaceControl.Transaction t, WindowContainer child) {
+ mImeWindowsContainers.setNeedsLayer();
child.assignRelativeLayer(t, mImeWindowsContainers.getSurfaceControl(), 1);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 223e9b9e3df2..c78de42b84ae 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2764,7 +2764,7 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized (mGlobalLock) {
final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null && mRoot.getTopChild() != displayContent) {
- mRoot.positionChildAt(WindowContainer.POSITION_TOP, displayContent,
+ displayContent.positionDisplayAt(WindowContainer.POSITION_TOP,
true /* includingParents */);
}
}
@@ -7647,7 +7647,7 @@ public class WindowManagerService extends IWindowManager.Stub
final DisplayContent displayContent = touchedWindow.getDisplayContent();
if (!displayContent.isOnTop()) {
- displayContent.getParent().positionChildAt(WindowContainer.POSITION_TOP, displayContent,
+ displayContent.positionDisplayAt(WindowContainer.POSITION_TOP,
true /* includingParents */);
}
handleTaskFocusChange(touchedWindow.getTask());
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 2a1e980dfb3d..b9bd4e003993 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
@@ -38,7 +39,9 @@ import android.annotation.CallSuper;
import android.os.Debug;
import android.os.IBinder;
import android.util.proto.ProtoOutputStream;
+import android.view.SurfaceControl;
+import com.android.server.policy.WindowManagerPolicy;
import com.android.server.protolog.common.ProtoLog;
import java.io.PrintWriter;
@@ -256,6 +259,27 @@ class WindowToken extends WindowContainer<WindowState> {
super.onDisplayChanged(dc);
}
+ @Override
+ void assignLayer(SurfaceControl.Transaction t, int layer) {
+ if (windowType == TYPE_DOCK_DIVIDER) {
+ // See {@link DisplayContent#mSplitScreenDividerAnchor}
+ super.assignRelativeLayer(t, mDisplayContent.getSplitScreenDividerAnchor(), 1);
+ } else if (mRoundedCornerOverlay) {
+ super.assignLayer(t, WindowManagerPolicy.COLOR_FADE_LAYER + 1);
+ } else {
+ super.assignLayer(t, layer);
+ }
+ }
+
+ @Override
+ SurfaceControl.Builder makeSurface() {
+ final SurfaceControl.Builder builder = super.makeSurface();
+ if (mRoundedCornerOverlay) {
+ builder.setParent(null);
+ }
+ return builder;
+ }
+
@CallSuper
@Override
public void dumpDebug(ProtoOutputStream proto, long fieldId,
@@ -315,4 +339,8 @@ class WindowToken extends WindowContainer<WindowState> {
mOwnerCanManageAppTokens);
return mOwnerCanManageAppTokens && (layer > navLayer);
}
+
+ int getWindowLayerFromType() {
+ return mWmService.mPolicy.getWindowLayerFromTypeLw(windowType, mOwnerCanManageAppTokens);
+ }
}