Decouple display area from windowing layer

FEATURE_WINDOWED_MAGNIFICATION was a necessary feature of a display.
Because screen level surface animation needs a layer containing
all non-overlay window for reparenting leash. But that seems to
restrict the customizability of non-default display.

This change makes the feature optional by creating an additional
layer if the feature doesn't exist. So a display can create without
any display area features.

Also remove some unused fields.

Bug: 175179353
Test: DisplayContentTests#testValidWindowingLayer
Change-Id: I5c8712e7650a51fc57ea2dc5c60176d7dcafe1d1
This commit is contained in:
Riddle Hsu
2020-12-22 00:02:44 +08:00
parent a0334be887
commit 941ad3a5f0
2 changed files with 46 additions and 24 deletions

View File

@@ -283,6 +283,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
*/
private SurfaceControl mOverlayLayer;
/**
* The direct child layer of the display to put all non-overlay windows. This is also used for
* screen rotation animation so that there is a parent layer to put the animation leash.
*/
private final SurfaceControl mWindowingLayer;
// Contains all IME window containers. Note that the z-ordering of the IME windows will depend
// 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
@@ -294,7 +300,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
final DisplayAreaPolicy mDisplayAreaPolicy;
private WindowState mTmpWindow;
private WindowState mTmpWindow2;
private boolean mUpdateImeTarget;
private boolean mTmpInitial;
private int mMaxUiWidth;
@@ -459,10 +464,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
private final ApplySurfaceChangesTransactionState mTmpApplySurfaceChangesTransactionState =
new ApplySurfaceChangesTransactionState();
// True if this display is in the process of being removed. Used to determine if the removal of
// the display's direct children should be allowed.
private boolean mRemovingDisplay = false;
// {@code false} if this display is in the processing of being created.
private boolean mDisplayReady = false;
@@ -1023,6 +1024,27 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
.setContainerLayer()
.setCallsite("DisplayContent");
mSurfaceControl = b.setName("Root").setContainerLayer().build();
// Setup the policy and build the display area hierarchy.
mDisplayAreaPolicy = mWmService.getDisplayAreaPolicyProvider().instantiate(
mWmService, this /* content */, this /* root */, mImeWindowsContainers);
final List<DisplayArea<? extends WindowContainer>> areas =
mDisplayAreaPolicy.getDisplayAreas(FEATURE_WINDOWED_MAGNIFICATION);
final DisplayArea<?> area = areas.size() == 1 ? areas.get(0) : null;
if (area != null && area.getParent() == this) {
// The windowed magnification area should contain all non-overlay windows, so just use
// it as the windowing layer.
mWindowingLayer = area.mSurfaceControl;
} else {
// Need an additional layer for screen level animation, so move the layer containing
// the windows to the new root.
mWindowingLayer = mSurfaceControl;
mSurfaceControl = b.setName("RootWrapper").build();
getPendingTransaction().reparent(mWindowingLayer, mSurfaceControl)
.show(mWindowingLayer);
}
mOverlayLayer = b.setName("Display Overlays").setParent(mSurfaceControl).build();
getPendingTransaction()
@@ -1033,10 +1055,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
.show(mOverlayLayer);
getPendingTransaction().apply();
// Setup the policy and build the display area hierarchy.
mDisplayAreaPolicy = mWmService.getDisplayAreaPolicyProvider().instantiate(
mWmService, this /* content */, this /* root */, mImeWindowsContainers);
// Sets the display content for the children.
onDisplayChanged(this);
@@ -2796,7 +2814,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
@Override
void removeImmediately() {
mRemovingDisplay = true;
mDeferredRemoval = false;
try {
if (mParentWindow != null) {
@@ -2820,7 +2837,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mWmService.mDisplayNotificationController.dispatchDisplayRemoved(this);
} finally {
mDisplayReady = false;
mRemovingDisplay = false;
}
// Apply the pending transaction here since we may not be able to reach the DisplayContent
@@ -4190,7 +4206,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// Used to indicate that we have processed the dream window and all additional attached
// windows are behind it.
mTmpWindow2 = mTmpWindow;
mTmpWindow = null;
// Now perform layout of attached windows, which usually depend on the position of the
@@ -4860,19 +4875,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}, false /* traverseTopToBottom */);
}
private DisplayArea getWindowContainers() {
List<DisplayArea<? extends WindowContainer>> windowContainers =
mDisplayAreaPolicy.getDisplayAreas(FEATURE_WINDOWED_MAGNIFICATION);
if (windowContainers.size() != 1) {
throw new IllegalStateException("There should be only one DisplayArea for "
+ "FEATURE_WINDOWED_MAGNIFICATION");
}
return windowContainers.get(0);
}
@VisibleForTesting
SurfaceControl getWindowingLayer() {
return getWindowContainers().getSurfaceControl();
return mWindowingLayer;
}
DisplayArea.Tokens getImeContainer() {

View File

@@ -50,6 +50,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
@@ -106,6 +107,7 @@ import android.view.IWindowManager;
import android.view.InsetsState;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.WindowManager;
@@ -1533,6 +1535,22 @@ public class DisplayContentTests extends WindowTestsBase {
assertNull(taskDisplayArea.getOrCreateRootHomeTask());
}
@Test
public void testValidWindowingLayer() {
final SurfaceControl windowingLayer = mDisplayContent.getWindowingLayer();
assertNotNull(windowingLayer);
final List<DisplayArea<?>> windowedMagnificationAreas =
mDisplayContent.mDisplayAreaPolicy.getDisplayAreas(FEATURE_WINDOWED_MAGNIFICATION);
if (windowedMagnificationAreas != null) {
assertEquals("There should be only one DisplayArea for FEATURE_WINDOWED_MAGNIFICATION",
1, windowedMagnificationAreas.size());
assertEquals(windowedMagnificationAreas.get(0).mSurfaceControl, windowingLayer);
} else {
assertNotEquals(mDisplayContent.mSurfaceControl, windowingLayer);
}
}
@Test
public void testFindScrollCaptureTargetWindow_behindWindow() {
DisplayContent display = createNewDisplay();