Restrict DisplayContent creation.
This changelist limits DisplayContent the display
container/controller creation. All other callpoints now can only
retrieve existing DisplayContents. This removes the chances of
arbitrary calls generating a DisplayContent without the related
ActivityDisplay on the ActivityManager side.
Since display creation is now driven on the ActivityManager side,
the ActivityManagerService must be initialized and associated with
the WindowManagerService before the WindowManagerService can be fully
initialized. This is reflected in changes to SystemServer.
Fixes: 72228411
Test: go/wm-smoke-auto
Change-Id: I8dddb5fc109be4363de5ba87faff9d9885009042
diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java
index 220014f..608352b 100644
--- a/services/core/java/com/android/server/am/ActivityDisplay.java
+++ b/services/core/java/com/android/server/am/ActivityDisplay.java
@@ -657,6 +657,26 @@
return false;
}
+ void remove() {
+ final boolean destroyContentOnRemoval = shouldDestroyContentOnRemove();
+ while (getChildCount() > 0) {
+ final ActivityStack stack = getChildAt(0);
+ if (destroyContentOnRemoval) {
+ mSupervisor.moveStackToDisplayLocked(stack.mStackId, DEFAULT_DISPLAY,
+ false /* onTop */);
+ stack.finishAllActivitiesLocked(true /* immediately */);
+ } else {
+ // Moving all tasks to fullscreen stack, because it's guaranteed to be
+ // a valid launch stack for all activities. This way the task history from
+ // external display will be preserved on primary after move.
+ mSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
+ }
+ }
+
+ mWindowContainerController.removeContainer();
+ mWindowContainerController = null;
+ }
+
/** Update and get all UIDs that are present on the display and have access to it. */
IntArray getPresentUIDs() {
mDisplayAccessUIDs.clear();
@@ -666,7 +686,7 @@
return mDisplayAccessUIDs;
}
- boolean shouldDestroyContentOnRemove() {
+ private boolean shouldDestroyContentOnRemove() {
return mDisplay.getRemoveMode() == REMOVE_MODE_DESTROY_CONTENT;
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index a0f31cd..cdfa066 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -4087,25 +4087,12 @@
if (activityDisplay == null) {
return;
}
- final boolean destroyContentOnRemoval
- = activityDisplay.shouldDestroyContentOnRemove();
- while (activityDisplay.getChildCount() > 0) {
- final ActivityStack stack = activityDisplay.getChildAt(0);
- if (destroyContentOnRemoval) {
- moveStackToDisplayLocked(stack.mStackId, DEFAULT_DISPLAY, false /* onTop */);
- stack.finishAllActivitiesLocked(true /* immediately */);
- } else {
- // Moving all tasks to fullscreen stack, because it's guaranteed to be
- // a valid launch stack for all activities. This way the task history from
- // external display will be preserved on primary after move.
- moveTasksToFullscreenStackLocked(stack, true /* onTop */);
- }
- }
+
+ activityDisplay.remove();
releaseSleepTokens(activityDisplay);
mActivityDisplays.remove(displayId);
- mWindowManager.onDisplayRemoved(displayId);
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 2512dbd..41a6e2b 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -725,8 +725,9 @@
* wallpaper windows in the window list.
*/
DisplayContent(Display display, WindowManagerService service,
- WallpaperController wallpaperController) {
+ WallpaperController wallpaperController, DisplayWindowController controller) {
super(service);
+ setController(controller);
if (service.mRoot.getDisplayContent(display.getDisplayId()) != null) {
throw new IllegalArgumentException("Display with ID=" + display.getDisplayId()
+ " already exists=" + service.mRoot.getDisplayContent(display.getDisplayId())
@@ -1941,6 +1942,8 @@
} finally {
mRemovingDisplay = false;
}
+
+ mService.onDisplayRemoved(mDisplayId);
}
/** Returns true if a removal action is still being deferred. */
@@ -1950,7 +1953,6 @@
if (!stillDeferringRemoval && mDeferredRemoval) {
removeImmediately();
- mService.onDisplayRemoved(mDisplayId);
return false;
}
return true;
diff --git a/services/core/java/com/android/server/wm/DisplayWindowController.java b/services/core/java/com/android/server/wm/DisplayWindowController.java
index ad4957e..0e12838 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowController.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowController.java
@@ -16,11 +16,14 @@
package com.android.server.wm;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.content.res.Configuration;
+import android.os.Binder;
import android.util.Slog;
+import android.view.Display;
/**
* Controller for the display container. This is created by activity manager to link activity
@@ -36,9 +39,16 @@
mDisplayId = displayId;
synchronized (mWindowMap) {
- // TODO: Convert to setContainer() from DisplayContent once everything is hooked up.
- // Currently we are not setup to register for config changes.
- mContainer = mRoot.getDisplayContentOrCreate(displayId);
+ final Display display = mService.mDisplayManager.getDisplay(displayId);
+ if (display != null) {
+ final long callingIdentity = Binder.clearCallingIdentity();
+ try {
+ mRoot.createDisplayContent(display, this /* controller */);
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentity);
+ }
+ }
+
if (mContainer == null) {
throw new IllegalArgumentException("Trying to add displayId=" + displayId);
}
@@ -47,14 +57,22 @@
@Override
public void removeContainer() {
- // TODO: Pipe through from ActivityDisplay to remove the display
- throw new UnsupportedOperationException("To be implemented");
+ synchronized (mWindowMap) {
+ if(mContainer == null) {
+ if (DEBUG_DISPLAY) Slog.i(TAG_WM, "removeDisplay: could not find displayId="
+ + mDisplayId);
+ return;
+ }
+ mContainer.removeIfPossible();
+ super.removeContainer();
+ }
}
@Override
public void onOverrideConfigurationChanged(Configuration overrideConfiguration) {
- // TODO: Pipe through from ActivityDisplay to update the configuration for the display
- throw new UnsupportedOperationException("To be implemented");
+ // TODO: The container receives override configuration changes through other means. enabling
+ // callbacks through the controller causes layout issues. Investigate consolidating
+ // override configuration propagation to just here.
}
/**
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index c535fe5..83bd911 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -193,30 +193,6 @@
}
}
- /**
- * Retrieve the DisplayContent for the specified displayId. Will create a new DisplayContent if
- * there is a Display for the displayId.
- *
- * @param displayId The display the caller is interested in.
- * @return The DisplayContent associated with displayId or null if there is no Display for it.
- */
- DisplayContent getDisplayContentOrCreate(int displayId) {
- DisplayContent dc = getDisplayContent(displayId);
-
- if (dc == null) {
- final Display display = mService.mDisplayManager.getDisplay(displayId);
- if (display != null) {
- final long callingIdentity = Binder.clearCallingIdentity();
- try {
- dc = createDisplayContent(display);
- } finally {
- Binder.restoreCallingIdentity(callingIdentity);
- }
- }
- }
- return dc;
- }
-
DisplayContent getDisplayContent(int displayId) {
for (int i = mChildren.size() - 1; i >= 0; --i) {
final DisplayContent current = mChildren.get(i);
@@ -227,9 +203,9 @@
return null;
}
- private DisplayContent createDisplayContent(final Display display) {
- final DisplayContent dc = new DisplayContent(display, mService,
- mWallpaperController);
+ DisplayContent createDisplayContent(final Display display, DisplayWindowController controller) {
+ final DisplayContent dc =
+ new DisplayContent(display, mService, mWallpaperController, controller);
final int displayId = display.getDisplayId();
if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display);
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index cec13ab..49a30d5 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -161,7 +161,7 @@
final int numDisplays = mDisplayContentsAnimators.size();
for (int i = 0; i < numDisplays; i++) {
final int displayId = mDisplayContentsAnimators.keyAt(i);
- final DisplayContent dc = mService.mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent dc = mService.mRoot.getDisplayContent(displayId);
DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
final ScreenRotationAnimation screenRotationAnimation =
@@ -195,7 +195,7 @@
for (int i = 0; i < numDisplays; i++) {
final int displayId = mDisplayContentsAnimators.keyAt(i);
- final DisplayContent dc = mService.mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent dc = mService.mRoot.getDisplayContent(displayId);
dc.checkAppWindowsReadyToShow();
@@ -228,7 +228,7 @@
final int numDisplays = mDisplayContentsAnimators.size();
for (int i = 0; i < numDisplays; i++) {
final int displayId = mDisplayContentsAnimators.keyAt(i);
- final DisplayContent dc = mService.mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent dc = mService.mRoot.getDisplayContent(displayId);
dc.onPendingTransactionApplied();
}
@@ -305,7 +305,7 @@
pw.println(":");
final DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
final DisplayContent dc =
- mService.mRoot.getDisplayContentOrCreate(mDisplayContentsAnimators.keyAt(i));
+ mService.mRoot.getDisplayContent(mDisplayContentsAnimators.keyAt(i));
dc.dumpWindowAnimators(pw, subPrefix);
if (displayAnimator.mScreenRotationAnimation != null) {
pw.print(subPrefix); pw.println("mScreenRotationAnimation:");
@@ -339,7 +339,7 @@
if (displayId < 0) {
return 0;
}
- final DisplayContent displayContent = mService.mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent displayContent = mService.mRoot.getDisplayContent(displayId);
return (displayContent != null) ? displayContent.pendingLayoutChanges : 0;
}
@@ -347,7 +347,7 @@
if (displayId < 0) {
return;
}
- final DisplayContent displayContent = mService.mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent displayContent = mService.mRoot.getDisplayContent(displayId);
if (displayContent != null) {
displayContent.pendingLayoutChanges |= changes;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 676fb9f..1e069a93 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -737,7 +737,6 @@
final InputManagerService mInputManager;
final DisplayManagerInternal mDisplayManagerInternal;
final DisplayManager mDisplayManager;
- private final Display[] mDisplays;
// Indicates whether this device supports wide color gamut rendering
private boolean mHasWideColorGamutSupport;
@@ -915,7 +914,6 @@
@Override
public void run() {
WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
-
mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
}
}, 0);
@@ -974,10 +972,6 @@
}
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
- mDisplays = mDisplayManager.getDisplays();
- for (Display display : mDisplays) {
- createDisplayContentLocked(display);
- }
mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
@@ -1066,6 +1060,13 @@
mDragDropController = new DragDropController(this, mH.getLooper());
LocalServices.addService(WindowManagerInternal.class, new LocalService());
+ }
+
+ /**
+ * Called after all entities (such as the {@link ActivityManagerService}) have been set up and
+ * associated with the {@link WindowManagerService}.
+ */
+ public void onInitReady() {
initPolicy();
// Add ourself to the Watchdog monitors.
@@ -1081,6 +1082,7 @@
showEmulatorDisplayOverlayIfNeeded();
}
+
public InputMonitor getInputMonitor() {
return mInputMonitor;
}
@@ -1131,7 +1133,7 @@
throw new IllegalStateException("Display has not been initialialized");
}
- final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent == null) {
Slog.w(TAG_WM, "Attempted to add window to a display that does not exist: "
+ displayId + ". Aborting.");
@@ -2277,7 +2279,7 @@
}
synchronized(mWindowMap) {
- final DisplayContent dc = mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent dc = mRoot.getDisplayContent(displayId);
WindowToken token = dc.getWindowToken(binder);
if (token != null) {
Slog.w(TAG_WM, "addWindowToken: Attempted to add binder token: " + binder
@@ -3666,7 +3668,7 @@
boolean wallpaperOnly) {
final DisplayContent displayContent;
synchronized(mWindowMap) {
- displayContent = mRoot.getDisplayContentOrCreate(displayId);
+ displayContent = mRoot.getDisplayContent(displayId);
if (displayContent == null) {
if (DEBUG_SCREENSHOT) Slog.i(TAG_WM, "Screenshot returning null. No Display for "
+ "displayId=" + displayId);
@@ -3885,7 +3887,7 @@
public boolean registerWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
int displayId) {
synchronized (mWindowMap) {
- final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent == null) {
throw new IllegalArgumentException("Trying to register visibility event "
+ "for invalid display: " + displayId);
@@ -4442,10 +4444,13 @@
}
public void displayReady() {
- for (Display display : mDisplays) {
+ final int displayCount = mRoot.mChildren.size();
+ for (int i = 0; i < displayCount; ++i) {
+ final DisplayContent display = mRoot.mChildren.get(i);
displayReady(display.getDisplayId());
}
+
synchronized(mWindowMap) {
final DisplayContent displayContent = getDefaultDisplayContentLocked();
if (mMaxUiWidth > 0) {
@@ -4476,7 +4481,7 @@
private void displayReady(int displayId) {
synchronized(mWindowMap) {
- final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null) {
mAnimator.addDisplayLocked(displayId);
displayContent.initializeDisplayBaseInfo();
@@ -5025,7 +5030,7 @@
@Override
public void getInitialDisplaySize(int displayId, Point size) {
synchronized (mWindowMap) {
- final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
size.x = displayContent.mInitialDisplayWidth;
size.y = displayContent.mInitialDisplayHeight;
@@ -5036,7 +5041,7 @@
@Override
public void getBaseDisplaySize(int displayId, Point size) {
synchronized (mWindowMap) {
- final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
size.x = displayContent.mBaseDisplayWidth;
size.y = displayContent.mBaseDisplayHeight;
@@ -5063,7 +5068,7 @@
final int MIN_WIDTH = 200;
final int MIN_HEIGHT = 200;
final int MAX_SCALE = 2;
- final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null) {
width = Math.min(Math.max(width, MIN_WIDTH),
displayContent.mInitialDisplayWidth * MAX_SCALE);
@@ -5093,7 +5098,7 @@
final long ident = Binder.clearCallingIdentity();
try {
synchronized(mWindowMap) {
- final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null) {
if (mode < 0 || mode > 1) {
mode = 0;
@@ -5175,7 +5180,7 @@
final long ident = Binder.clearCallingIdentity();
try {
synchronized(mWindowMap) {
- final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null) {
setForcedDisplaySizeLocked(displayContent, displayContent.mInitialDisplayWidth,
displayContent.mInitialDisplayHeight);
@@ -5191,7 +5196,7 @@
@Override
public int getInitialDisplayDensity(int displayId) {
synchronized (mWindowMap) {
- final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
return displayContent.mInitialDisplayDensity;
}
@@ -5202,7 +5207,7 @@
@Override
public int getBaseDisplayDensity(int displayId) {
synchronized (mWindowMap) {
- final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
return displayContent.mBaseDisplayDensity;
}
@@ -5228,7 +5233,7 @@
final long ident = Binder.clearCallingIdentity();
try {
synchronized(mWindowMap) {
- final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null && mCurrentUserId == targetUserId) {
setForcedDisplayDensityLocked(displayContent, density);
}
@@ -5259,7 +5264,7 @@
final long ident = Binder.clearCallingIdentity();
try {
synchronized(mWindowMap) {
- final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null && mCurrentUserId == callingUserId) {
setForcedDisplayDensityLocked(displayContent,
displayContent.mInitialDisplayDensity);
@@ -5351,7 +5356,7 @@
final long ident = Binder.clearCallingIdentity();
try {
synchronized(mWindowMap) {
- DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
+ DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null) {
setOverscanLocked(displayContent, left, top, right, bottom);
}
@@ -6614,19 +6619,11 @@
synchronized (mWindowMap) { }
}
- // TODO: All the display method below should probably be moved into the RootWindowContainer...
- private void createDisplayContentLocked(final Display display) {
- if (display == null) {
- throw new IllegalArgumentException("getDisplayContent: display must not be null");
- }
- mRoot.getDisplayContentOrCreate(display.getDisplayId());
- }
-
// There is an inherent assumption that this will never return null.
// TODO(multi-display): Inspect all the call-points of this method to see if they make sense to
// support non-default display.
DisplayContent getDefaultDisplayContentLocked() {
- return mRoot.getDisplayContentOrCreate(DEFAULT_DISPLAY);
+ return mRoot.getDisplayContent(DEFAULT_DISPLAY);
}
public void onDisplayAdded(int displayId) {
@@ -6641,10 +6638,6 @@
public void onDisplayRemoved(int displayId) {
synchronized (mWindowMap) {
- final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
- if (displayContent != null) {
- displayContent.removeIfPossible();
- }
mAnimator.removeDisplayLocked(displayId);
mWindowPlacerLocked.requestTraversal();
}
@@ -6660,7 +6653,7 @@
public void onDisplayChanged(int displayId) {
synchronized (mWindowMap) {
- final DisplayContent displayContent = mRoot.getDisplayContentOrCreate(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null) {
displayContent.updateDisplayInfo();
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 5ea113b..75bb5e4 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -842,6 +842,14 @@
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
traceEnd();
+ traceBeginAndSlog("SetWindowManagerService");
+ mActivityManagerService.setWindowManager(wm);
+ traceEnd();
+
+ traceBeginAndSlog("WindowManagerServiceOnInitReady");
+ wm.onInitReady();
+ traceEnd();
+
// Start receiving calls from HIDL services. Start in in a separate thread
// because it need to connect to SensorManager. This have to start
// after START_SENSOR_SERVICE is done.
@@ -859,10 +867,6 @@
traceEnd();
}
- traceBeginAndSlog("SetWindowManagerService");
- mActivityManagerService.setWindowManager(wm);
- traceEnd();
-
traceBeginAndSlog("StartInputManager");
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
inputManager.start();
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 000cf38..7a55904 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
@@ -107,6 +108,13 @@
sWm = WindowManagerService.main(context, ims, true, false,
false, new TestWindowManagerPolicy());
+
+ sWm.onInitReady();
+
+ // Display creation is driven by the ActivityManagerService via ActivityStackSupervisor.
+ // We emulate those steps here.
+ sWm.mRoot.createDisplayContent(sWm.mDisplayManager.getDisplay(DEFAULT_DISPLAY),
+ mock(DisplayWindowController.class));
}
return sWm;
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
index 69b1378..6e6863d 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -284,7 +284,8 @@
final int displayId = sNextDisplayId++;
final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
mDisplayInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
- return new DisplayContent(display, sWm, new WallpaperController(sWm));
+ return new DisplayContent(display, sWm, new WallpaperController(sWm),
+ mock(DisplayWindowController.class));
}
/** Creates a {@link com.android.server.wm.WindowTestUtils.TestWindowState} */