summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/WindowManager.java7
-rw-r--r--core/proto/android/server/windowmanagerservice.proto1
-rw-r--r--services/core/java/com/android/server/policy/WindowManagerPolicy.java9
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java388
-rw-r--r--services/core/java/com/android/server/wm/ScreenRotationAnimation.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java7
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java2
7 files changed, 226 insertions, 190 deletions
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index d40f8325c320..62a824d759f7 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1106,6 +1106,13 @@ public interface WindowManager extends ViewManager {
public static final int TYPE_APPLICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 38;
/**
+ * Window type: Window for adding accessibility window magnification above other windows.
+ * This will place the window in the overlay windows.
+ * @hide
+ */
+ public static final int TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 39;
+
+ /**
* End of types of system windows.
*/
public static final int LAST_SYSTEM_WINDOW = 2999;
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 24456d80625d..0c7484216367 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -163,6 +163,7 @@ message DisplayContentProto {
repeated IdentifierProto opening_apps = 17;
repeated IdentifierProto closing_apps = 18;
repeated IdentifierProto changing_apps = 19;
+ repeated WindowTokenProto overlay_windows = 20;
}
/* represents DisplayFrames */
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 95a5f52e5efb..b28a112f84d8 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -18,6 +18,7 @@ package com.android.server.policy;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
@@ -876,13 +877,15 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
case TYPE_ACCESSIBILITY_OVERLAY:
// overlay put by accessibility services to intercept user interaction
return 30;
+ case TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY:
+ return 31;
case TYPE_SECURE_SYSTEM_OVERLAY:
- return 31;
- case TYPE_BOOT_PROGRESS:
return 32;
+ case TYPE_BOOT_PROGRESS:
+ return 33;
case TYPE_POINTER:
// the (mouse) pointer layer
- return 33;
+ return 34;
default:
Slog.e("WindowManager", "Unknown window type: " + type);
return APPLICATION_LAYER;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 8e126b56a736..70f5fec04e69 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -58,6 +58,7 @@ import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
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.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
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;
@@ -93,6 +94,7 @@ import static com.android.server.wm.DisplayContentProto.FOCUSED_APP;
import static com.android.server.wm.DisplayContentProto.ID;
import static com.android.server.wm.DisplayContentProto.IME_WINDOWS;
import static com.android.server.wm.DisplayContentProto.OPENING_APPS;
+import static com.android.server.wm.DisplayContentProto.OVERLAY_WINDOWS;
import static com.android.server.wm.DisplayContentProto.PINNED_STACK_CONTROLLER;
import static com.android.server.wm.DisplayContentProto.ROTATION;
import static com.android.server.wm.DisplayContentProto.SCREEN_ROTATION_ANIMATION;
@@ -240,7 +242,21 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
/** Unique identifier of this display. */
private final int mDisplayId;
- /** The containers below are the only child containers the display can have. */
+ /**
+ * Most surfaces will be a child of this window. There are some special layers and windows
+ * which are always on top of others and omitted from Screen-Magnification, for example the
+ * strict mode flash or the magnification overlay itself. Those layers will be children of
+ * {@link #mOverlayContainers} where mWindowContainers contains everything else.
+ */
+ private final WindowContainers mWindowContainers =
+ new WindowContainers("mWindowContainers", mWmService);
+
+ // Contains some special windows which are always on top of others and omitted from
+ // Screen-Magnification, for example the WindowMagnification windows.
+ private final NonAppWindowContainers mOverlayContainers =
+ new NonAppWindowContainers("mOverlayContainers", mWmService);
+
+ /** The containers below are the only child containers {@link #mWindowContainers} can have. */
// Contains all window containers that are related to apps (Activities)
private final TaskStackContainers mTaskStackContainers = new TaskStackContainers(mWmService);
// Contains all non-app window containers that should be displayed above the app containers
@@ -260,7 +276,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
private WindowState mTmpWindow;
private WindowState mTmpWindow2;
- private boolean mTmpRecoveringMemory;
private boolean mUpdateImeTarget;
private boolean mTmpInitial;
private int mMaxUiWidth;
@@ -490,20 +505,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
private ScreenRotationAnimation mScreenRotationAnimation;
/**
- * We organize all top-level Surfaces in to the following layers.
- * mOverlayLayer contains a few Surfaces which are always on top of others
- * and omitted from Screen-Magnification, for example the strict mode flash or
- * the magnification overlay itself.
- * {@link #mWindowingLayer} contains everything else.
- */
- private SurfaceControl mOverlayLayer;
-
- /**
- * See {@link #mOverlayLayer}
- */
- private SurfaceControl mWindowingLayer;
-
- /**
* Sequence number for the current layout pass.
*/
int mLayoutSeq = 0;
@@ -910,24 +911,19 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
.setOpaque(true)
.setContainerLayer();
mSurfaceControl = b.setName("Root").setContainerLayer().build();
- mWindowingLayer = b.setName("Display Windows").setParent(mSurfaceControl).build();
- mOverlayLayer = b.setName("Display Overlays").setParent(mSurfaceControl).build();
getPendingTransaction()
.setLayer(mSurfaceControl, 0)
.setLayerStack(mSurfaceControl, mDisplayId)
- .show(mSurfaceControl)
- .setLayer(mWindowingLayer, 0)
- .show(mWindowingLayer)
- .setLayer(mOverlayLayer, 1)
- .show(mOverlayLayer);
+ .show(mSurfaceControl);
getPendingTransaction().apply();
// These are the only direct children we should ever have and they are permanent.
- super.addChild(mBelowAppWindowsContainers, null);
- super.addChild(mTaskStackContainers, null);
- super.addChild(mAboveAppWindowsContainers, null);
- super.addChild(mImeWindowsContainers, null);
+ super.addChild(mWindowContainers, null);
+ super.addChild(mOverlayContainers, null);
+
+ mWindowContainers.addChildren();
+
// Sets the display content for the children.
onDisplayChanged(this);
@@ -1001,6 +997,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
case TYPE_INPUT_METHOD_DIALOG:
mImeWindowsContainers.addChild(token);
break;
+ case TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY:
+ mOverlayContainers.addChild(token);
+ break;
default:
mAboveAppWindowsContainers.addChild(token);
break;
@@ -1878,8 +1877,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
if (lastOrientation != getConfiguration().orientation) {
getMetricsLogger().write(
new LogMaker(MetricsEvent.ACTION_PHONE_ORIENTATION_CHANGED)
- .setSubtype(getConfiguration().orientation)
- .addTaggedData(MetricsEvent.FIELD_DISPLAY_ID, getDisplayId()));
+ .setSubtype(getConfiguration().orientation)
+ .addTaggedData(MetricsEvent.FIELD_DISPLAY_ID, getDisplayId()));
}
// If there was no pinned stack, we still need to notify the controller of the display info
@@ -1936,49 +1935,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
setWindowingMode(windowingMode);
}
- /**
- * In split-screen mode we process the IME containers above the docked divider
- * rather than directly above their target.
- */
- private boolean skipTraverseChild(WindowContainer child) {
- if (child == mImeWindowsContainers && mInputMethodTarget != null
- && !hasSplitScreenPrimaryStack()) {
- return true;
- }
- return false;
- }
-
- @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 DisplayChildWindowContainer 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 DisplayChildWindowContainer child = mChildren.get(i);
- if (skipTraverseChild(child)) {
- continue;
- }
-
- if (child.forAllWindows(callback, traverseTopToBottom)) {
- return true;
- }
- }
- }
- return false;
- }
-
boolean forAllImeWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
return mImeWindowsContainers.forAllWindows(callback, traverseTopToBottom);
}
@@ -2000,7 +1956,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
if (mLastWindowForcedOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
ProtoLog.v(WM_DEBUG_ORIENTATION,
"Display id=%d is frozen, return %d", mDisplayId,
- mLastWindowForcedOrientation);
+ mLastWindowForcedOrientation);
// If the display is frozen, some activities may be in the middle of restarting, and
// thus have removed their old window. If the window has the flag to hide the lock
// screen, then the lock screen can re-appear and inflict its own orientation on us.
@@ -2014,7 +1970,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
// momentarily unavailable due to activity relaunch.
ProtoLog.v(WM_DEBUG_ORIENTATION,
"Display id=%d is frozen while keyguard locked, return %d",
- mDisplayId, getLastOrientation());
+ mDisplayId, getLastOrientation());
return getLastOrientation();
}
} else {
@@ -2268,7 +2224,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
forAllWindows(fn, true /* traverseTopToBottom */);
fn.recycle();
return FIRST_APPLICATION_WINDOW <= targetWindowType[0]
- && targetWindowType[0] <= LAST_APPLICATION_WINDOW;
+ && targetWindowType[0] <= LAST_APPLICATION_WINDOW;
}
/**
@@ -2383,8 +2339,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
mPointerEventDispatcher.dispose();
setRotationAnimation(null);
mWmService.mAnimator.removeDisplayLocked(mDisplayId);
- mWindowingLayer.release();
- mOverlayLayer.release();
mInputMonitor.onDisplayRemoved();
// TODO(display-merge): Remove cast
mWmService.mDisplayNotificationController
@@ -2499,7 +2453,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
// the minimized docked stack bounds.
final boolean dockMinimized = mDividerControllerLocked.isMinimizedDock()
|| (topDockedTask != null && imeOnBottom && !dockedStack.isAdjustedForIme()
- && dockedStack.getBounds().height() < topDockedTask.getBounds().height());
+ && dockedStack.getBounds().height() < topDockedTask.getBounds().height());
// The divider could be adjusted for IME position, or be thinner than usual,
// or both. There are three possible cases:
@@ -2630,6 +2584,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
final WindowToken windowToken = mImeWindowsContainers.getChildAt(i);
windowToken.dumpDebug(proto, IME_WINDOWS, logLevel);
}
+ for (int i = mOverlayContainers.getChildCount() - 1; i >= 0; --i) {
+ final WindowToken windowToken = mOverlayContainers.getChildAt(i);
+ windowToken.dumpDebug(proto, OVERLAY_WINDOWS, logLevel);
+ }
proto.write(DPI, mBaseDisplayDensity);
mDisplayInfo.dumpDebug(proto, DISPLAY_INFO);
proto.write(ROTATION, getRotation());
@@ -2660,31 +2618,31 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId);
final String subPrefix = " " + prefix;
pw.print(subPrefix); pw.print("init="); pw.print(mInitialDisplayWidth); pw.print("x");
- pw.print(mInitialDisplayHeight); pw.print(" "); pw.print(mInitialDisplayDensity);
- pw.print("dpi");
- if (mInitialDisplayWidth != mBaseDisplayWidth
- || mInitialDisplayHeight != mBaseDisplayHeight
- || mInitialDisplayDensity != mBaseDisplayDensity) {
- pw.print(" base=");
- pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
- pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi");
- }
- if (mDisplayScalingDisabled) {
- pw.println(" noscale");
- }
- pw.print(" cur=");
- pw.print(mDisplayInfo.logicalWidth);
- pw.print("x"); pw.print(mDisplayInfo.logicalHeight);
- pw.print(" app=");
- pw.print(mDisplayInfo.appWidth);
- pw.print("x"); pw.print(mDisplayInfo.appHeight);
- pw.print(" rng="); pw.print(mDisplayInfo.smallestNominalAppWidth);
- pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
- pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
- pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
- pw.print(subPrefix + "deferred=" + mDeferredRemoval
- + " mLayoutNeeded=" + mLayoutNeeded);
- pw.println(" mTouchExcludeRegion=" + mTouchExcludeRegion);
+ pw.print(mInitialDisplayHeight); pw.print(" "); pw.print(mInitialDisplayDensity);
+ pw.print("dpi");
+ if (mInitialDisplayWidth != mBaseDisplayWidth
+ || mInitialDisplayHeight != mBaseDisplayHeight
+ || mInitialDisplayDensity != mBaseDisplayDensity) {
+ pw.print(" base=");
+ pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
+ pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi");
+ }
+ if (mDisplayScalingDisabled) {
+ pw.println(" noscale");
+ }
+ pw.print(" cur=");
+ pw.print(mDisplayInfo.logicalWidth);
+ pw.print("x"); pw.print(mDisplayInfo.logicalHeight);
+ pw.print(" app=");
+ pw.print(mDisplayInfo.appWidth);
+ pw.print("x"); pw.print(mDisplayInfo.appHeight);
+ pw.print(" rng="); pw.print(mDisplayInfo.smallestNominalAppWidth);
+ pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
+ pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
+ pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
+ pw.print(subPrefix + "deferred=" + mDeferredRemoval
+ + " mLayoutNeeded=" + mLayoutNeeded);
+ pw.println(" mTouchExcludeRegion=" + mTouchExcludeRegion);
pw.println();
pw.print(prefix); pw.print("mLayoutSeq="); pw.println(mLayoutSeq);
@@ -2841,7 +2799,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
final WindowState win = getWindow(w ->
w.mAttrs.type == TYPE_TOAST && w.mOwnerUid == uid && !w.mPermanentlyHidden
- && !w.mWindowRemovalAllowed);
+ && !w.mWindowRemovalAllowed);
return win == null;
}
@@ -2921,7 +2879,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Changing focus from %s to %s displayId=%d Callers=%s",
- mCurrentFocus, newFocus, getDisplayId(), Debug.getCallers(4));
+ mCurrentFocus, newFocus, getDisplayId(), Debug.getCallers(4));
final WindowState oldFocus = mCurrentFocus;
mCurrentFocus = newFocus;
mLosingFocus.remove(newFocus);
@@ -3223,7 +3181,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
// target app together.
final boolean shouldAttachToDisplay = (mMagnificationSpec != null);
final SurfaceControl newParent =
- shouldAttachToDisplay ? mWindowingLayer : computeImeParent();
+ shouldAttachToDisplay ? mWindowContainers.getSurfaceControl() : computeImeParent();
if (newParent != null) {
getPendingTransaction().reparent(mImeWindowsContainers.mSurfaceControl, newParent);
scheduleAnimation();
@@ -3248,7 +3206,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
// Otherwise, we just attach it to the display.
- return mWindowingLayer;
+ return mWindowContainers.getSurfaceControl();
}
boolean getNeedsMenu(WindowState top, WindowManagerPolicy.WindowState bottom) {
@@ -3395,7 +3353,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
boolean wallpaperEnabled = mWmService.mContext.getResources().getBoolean(
com.android.internal.R.bool.config_enableWallpaperService)
&& mWmService.mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_checkWallpaperAtBoot)
+ com.android.internal.R.bool.config_checkWallpaperAtBoot)
&& !mWmService.mOnlyCore;
final boolean haveBootMsg = drawnWindowTypes.get(TYPE_BOOT_PROGRESS);
@@ -3586,13 +3544,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
"after finishPostLayoutPolicyLw", pendingLayoutChanges);
- mInsetsStateController.onPostLayout();
+ mInsetsStateController.onPostLayout();
} while (pendingLayoutChanges != 0);
mTmpApplySurfaceChangesTransactionState.reset();
- mTmpRecoveringMemory = recoveringMemory;
-
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyWindowSurfaceChanges");
try {
forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */);
@@ -4297,7 +4253,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
if (mHomeStack != null && mHomeStack.isVisible()
&& mDividerControllerLocked.isMinimizedDock()
&& !(mDividerControllerLocked.isHomeStackResizable()
- && mHomeStack.matchParentBounds())) {
+ && mHomeStack.matchParentBounds())) {
final int orientation = mHomeStack.getOrientation();
if (orientation != SCREEN_ORIENTATION_UNSET) {
return orientation;
@@ -4310,14 +4266,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
if (orientation != SCREEN_ORIENTATION_UNSET
&& orientation != SCREEN_ORIENTATION_BEHIND) {
ProtoLog.v(WM_DEBUG_ORIENTATION,
- "App is requesting an orientation, return %d for display id=%d",
- orientation, mDisplayId);
+ "App is requesting an orientation, return %d for display id=%d",
+ orientation, mDisplayId);
return orientation;
}
ProtoLog.v(WM_DEBUG_ORIENTATION,
- "No app is requesting an orientation, return %d for display id=%d",
- getLastOrientation(), mDisplayId);
+ "No app is requesting an orientation, return %d for display id=%d",
+ getLastOrientation(), mDisplayId);
// The next app has not been requested to be visible, so we keep the current orientation
// to prevent freezing/unfreezing the display too early.
return getLastOrientation();
@@ -4486,7 +4442,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
wt.windowType, wt.mOwnerCanManageAppTokens);
if (needAssignIme && layer >= mWmService.mPolicy.getWindowLayerFromTypeLw(
- TYPE_INPUT_METHOD_DIALOG, true)) {
+ TYPE_INPUT_METHOD_DIALOG, true)) {
imeContainer.assignRelativeLayer(t, wt.getSurfaceControl(), -1);
needAssignIme = false;
}
@@ -4497,6 +4453,126 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
}
+ private class WindowContainers extends DisplayChildWindowContainer<WindowContainer> {
+ private final String mName;
+
+ WindowContainers(String name, WindowManagerService service) {
+ super(service);
+ mName = name;
+ }
+
+ @Override
+ void assignChildLayers(SurfaceControl.Transaction t) {
+ mBelowAppWindowsContainers.assignLayer(t, 0);
+ mTaskStackContainers.assignLayer(t, 1);
+ mAboveAppWindowsContainers.assignLayer(t, 2);
+
+ final WindowState imeTarget = mInputMethodTarget;
+ boolean needAssignIme = true;
+
+ // In the case where we have an IME target that is not in split-screen mode IME
+ // assignment is easy. We just need the IME to go directly above the target. This way
+ // children of the target will naturally go above the IME and everyone is happy.
+ //
+ // In the case of split-screen windowing mode, we need to elevate the IME above the
+ // docked divider while keeping the app itself below the docked divider, so instead
+ // we use relative layering of the IME targets child windows, and place the IME in
+ // the non-app layer (see {@link AboveAppWindowContainers#assignChildLayers}).
+ //
+ // In the case the IME target is animating, the animation Z order may be different
+ // than the WindowContainer Z order, so it's difficult to be sure we have the correct
+ // IME target. In this case we just layer the IME over all transitions by placing it
+ // in the above applications layer.
+ //
+ // In the case where we have no IME target we assign it where its base layer would
+ // place it in the AboveAppWindowContainers.
+ //
+ // Keep IME window in mAboveAppWindowsContainers as long as app's starting window
+ // exists so it get's layered above the starting window.
+ if (imeTarget != null && !(imeTarget.mActivityRecord != null
+ && imeTarget.mActivityRecord.hasStartingWindow()) && (
+ !(imeTarget.inSplitScreenWindowingMode()
+ || imeTarget.mToken.isAppTransitioning()) && (
+ imeTarget.getSurfaceControl() != null))) {
+ mImeWindowsContainers.assignRelativeLayer(t, imeTarget.getSurfaceControl(),
+ // 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);
+ mImeWindowsContainers.assignChildLayers(t);
+ }
+
+ @Override
+ String getName() {
+ return mName;
+ }
+
+ void addChildren() {
+ addChild(mBelowAppWindowsContainers, null);
+ addChild(mTaskStackContainers, null);
+ addChild(mAboveAppWindowsContainers, null);
+ 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++) {
+ Slog.d(TAG, "child " + mChildren.get(i));
+ final WindowContainer child = mChildren.get(i);
+ if (skipTraverseChild(child)) {
+ Slog.d(TAG, "child skipped");
+ 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
+ // is to perform the operation on the display and not the static direct children.
+ getParent().positionChildAt(position, this, includingParents);
+ }
+ }
+
/**
* Window container class that contains all containers on this display that are not related to
* Apps. E.g. status bar.
@@ -4510,7 +4586,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
// Tokens with higher base layer are z-ordered on-top.
mWmService.mPolicy.getWindowLayerFromTypeLw(token1.windowType,
token1.mOwnerCanManageAppTokens)
- < mWmService.mPolicy.getWindowLayerFromTypeLw(token2.windowType,
+ < mWmService.mPolicy.getWindowLayerFromTypeLw(token2.windowType,
token2.mOwnerCanManageAppTokens) ? -1 : 1;
private final Predicate<WindowState> mGetOrientingWindow = w -> {
@@ -4562,7 +4638,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
ProtoLog.v(WM_DEBUG_ORIENTATION,
"%s forcing orientation to %d for display id=%d", win, req,
- mDisplayId);
+ mDisplayId);
return (mLastWindowForcedOrientation = req);
}
@@ -4602,11 +4678,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
}
- SurfaceControl.Builder makeSurface(SurfaceSession s) {
- return mWmService.makeSurfaceBuilder(s)
- .setParent(mWindowingLayer);
- }
-
@Override
SurfaceSession getSession() {
return mSession;
@@ -4621,7 +4692,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
return b.setName(child.getName())
- .setParent(mWindowingLayer);
+ .setParent(mSurfaceControl);
}
/**
@@ -4632,14 +4703,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
*/
SurfaceControl.Builder makeOverlay() {
return mWmService.makeSurfaceBuilder(mSession)
- .setParent(mOverlayLayer);
+ .setParent(mOverlayContainers.getSurfaceControl());
}
/**
- * Reparents the given surface to mOverlayLayer.
+ * Reparents the given surface to {@link #mOverlayContainers}' SurfaceControl.
*/
void reparentToOverlay(Transaction transaction, SurfaceControl surface) {
- transaction.reparent(surface, mOverlayLayer);
+ transaction.reparent(surface, mOverlayContainers.getSurfaceControl());
}
void applyMagnificationSpec(MagnificationSpec spec) {
@@ -4671,54 +4742,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
@Override
void assignChildLayers(SurfaceControl.Transaction t) {
+ mWindowContainers.assignLayer(t, 0);
+ mOverlayContainers.assignLayer(t, 1);
- // These are layers as children of "mWindowingLayer"
- mBelowAppWindowsContainers.assignLayer(t, 0);
- mTaskStackContainers.assignLayer(t, 1);
- mAboveAppWindowsContainers.assignLayer(t, 2);
-
- final WindowState imeTarget = mInputMethodTarget;
- boolean needAssignIme = true;
-
- // In the case where we have an IME target that is not in split-screen
- // mode IME assignment is easy. We just need the IME to go directly above
- // the target. This way children of the target will naturally go above the IME
- // and everyone is happy.
- //
- // In the case of split-screen windowing mode, we need to elevate the IME above the
- // docked divider while keeping the app itself below the docked divider, so instead
- // we use relative layering of the IME targets child windows, and place the
- // IME in the non-app layer (see {@link AboveAppWindowContainers#assignChildLayers}).
- //
- // In the case the IME target is animating, the animation Z order may be different
- // than the WindowContainer Z order, so it's difficult to be sure we have the correct
- // IME target. In this case we just layer the IME over all transitions by placing it in the
- // above applications layer.
- //
- // In the case where we have no IME target we assign it where it's base layer would
- // place it in the AboveAppWindowContainers.
- //
- // Keep IME window in mAboveAppWindowsContainers as long as app's starting window exists
- // so it get's layered above the starting window.
- if (imeTarget != null
- && !(imeTarget.mActivityRecord != null && imeTarget.mActivityRecord.hasStartingWindow())
- && (!(imeTarget.inSplitScreenWindowingMode()
- || imeTarget.mToken.isAppTransitioning())
- && (imeTarget.getSurfaceControl() != null))) {
- mImeWindowsContainers.assignRelativeLayer(t, imeTarget.getSurfaceControl(),
- // 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 == true ? mImeWindowsContainers : null);
- mImeWindowsContainers.assignChildLayers(t);
+ mWindowContainers.assignChildLayers(t);
+ mOverlayContainers.assignChildLayers(t);
}
/**
@@ -4820,7 +4848,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
if (mAppTransition.isTransitionSet()) {
ProtoLog.w(WM_DEBUG_APP_TRANSITIONS,
"Execute app transition: %s, displayId: %d Callers=%s",
- mAppTransition, mDisplayId, Debug.getCallers(5));
+ mAppTransition, mDisplayId, Debug.getCallers(5));
mAppTransition.setReady();
mWmService.mWindowPlacerLocked.requestTraversal();
}
@@ -4885,8 +4913,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
/**
- * Re-parent the DisplayContent's top surfaces, {@link #mWindowingLayer} and
- * {@link #mOverlayLayer} to the specified SurfaceControl.
+ * Re-parent the DisplayContent's top surface, {@link #mSurfaceControl} to the specified
+ * SurfaceControl.
*
* @param win The window which owns the SurfaceControl. This indicates the z-order of the
* windows of this display against the windows on the parent display.
@@ -4964,11 +4992,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
@VisibleForTesting
SurfaceControl getWindowingLayer() {
- return mWindowingLayer;
+ return mWindowContainers.getSurfaceControl();
}
SurfaceControl getOverlayLayer() {
- return mOverlayLayer;
+ return mOverlayContainers.getSurfaceControl();
}
/**
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index 1a7d21406e55..399c5d3ae45f 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -172,7 +172,7 @@ class ScreenRotationAnimation {
.setContainerLayer()
.build();
- mSurfaceControl = displayContent.makeSurface(null)
+ mSurfaceControl = mService.makeSurfaceBuilder(null)
.setName("ScreenshotSurface")
.setParent(mRotationLayer)
.setBufferSize(mWidth, mHeight)
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 95eb4ddceb45..f45eb50f7f6c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -16,7 +16,6 @@
package com.android.server.wm;
-import static android.Manifest.permission.ACCESS_SURFACE_FLINGER;
import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
@@ -7815,8 +7814,8 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public boolean mirrorDisplay(int displayId, SurfaceControl outSurfaceControl) {
- if (!checkCallingPermission(ACCESS_SURFACE_FLINGER, "mirrorDisplay()")) {
- throw new SecurityException("Requires ACCESS_SURFACE_FLINGER permission");
+ if (!checkCallingPermission(READ_FRAME_BUFFER, "mirrorDisplay()")) {
+ throw new SecurityException("Requires READ_FRAME_BUFFER permission");
}
final SurfaceControl displaySc;
@@ -7827,7 +7826,7 @@ public class WindowManagerService extends IWindowManager.Stub
return false;
}
- displaySc = displayContent.getSurfaceControl();
+ displaySc = displayContent.getWindowingLayer();
}
final SurfaceControl mirror = SurfaceControl.mirrorSurface(displaySc);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 716e777ab779..a29c8cb5e9b6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -244,7 +244,6 @@ public class DisplayContentTests extends WindowTestsBase {
// Add stack with activity.
final ActivityStack stack = createTaskStackOnDisplay(dc);
assertEquals(dc.getDisplayId(), stack.getDisplayContent().getDisplayId());
- assertEquals(dc, stack.getParent().getParent());
assertEquals(dc, stack.getDisplayContent());
final Task task = createTaskInStack(stack, 0 /* userId */);
@@ -256,7 +255,6 @@ public class DisplayContentTests extends WindowTestsBase {
// Move stack to first display.
mDisplayContent.moveStackToDisplay(stack, true /* onTop */);
assertEquals(mDisplayContent.getDisplayId(), stack.getDisplayContent().getDisplayId());
- assertEquals(mDisplayContent, stack.getParent().getParent());
assertEquals(mDisplayContent, stack.getDisplayContent());
assertEquals(mDisplayContent, task.getDisplayContent());
assertEquals(mDisplayContent, activity.getDisplayContent());