Per-test WindowManagerService instance

This CL starts using a WindowManagerService instance for each test method,
instead of sharing a single instance within a test class. It also starts
resetting mocks after each test method. With a MockTrack hack, it reduces
memory leaks happening in extended inline Mockito (b/123984854).

Bug: 123652272
Test: Pass all non-flaky presubmit tests in WmTests.
  $ tradefed.sh run commandAndExit WmTests \
      --include-annotation android.platform.test.annotations.Presubmit \
      --exclude-annotation androidx.test.filters.FlakyTest
Change-Id: Icbfd5c5d726e4c29a623682deac852c5b14667dd
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index abc0bd6..164535c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -74,7 +74,6 @@
 import com.android.server.wm.utils.MockTracker;
 
 import org.junit.After;
-import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Rule;
@@ -89,8 +88,6 @@
 class ActivityTestsBase {
     private static int sNextDisplayId = DEFAULT_DISPLAY + 1;
 
-    private static MockTracker sMockTracker;
-
     @Rule
     public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
             new DexmakerShareClassLoaderRule();
@@ -102,6 +99,8 @@
     RootActivityContainer mRootActivityContainer;
     ActivityStackSupervisor mSupervisor;
 
+    private MockTracker mMockTracker;
+
     // Default package name
     static final String DEFAULT_COMPONENT_PACKAGE_NAME = "com.foo";
 
@@ -110,19 +109,13 @@
 
     @BeforeClass
     public static void setUpOnceBase() {
-        sMockTracker = new MockTracker();
-
         AttributeCache.init(getInstrumentation().getTargetContext());
     }
 
-    @AfterClass
-    public static void tearDownOnceBase() {
-        sMockTracker.close();
-        sMockTracker = null;
-    }
-
     @Before
     public void setUpBase() {
+        mMockTracker = new MockTracker();
+
         mTestInjector.setUp();
 
         mService = new TestActivityTaskManagerService(mContext);
@@ -137,6 +130,9 @@
             mService.setWindowManager(null);
             mService = null;
         }
+
+        mMockTracker.close();
+        mMockTracker = null;
     }
 
     /** Creates a {@link TestActivityDisplay}. */
@@ -651,7 +647,10 @@
 
         @Override
         protected DisplayContent createDisplayContent() {
-            return WindowTestUtils.createTestDisplayContent();
+            final DisplayContent displayContent = mock(DisplayContent.class);
+            DockedStackDividerController divider = mock(DockedStackDividerController.class);
+            doReturn(divider).when(displayContent).getDockedDividerController();
+            return displayContent;
         }
 
         void removeAllTasks() {
@@ -732,14 +731,13 @@
 
         @Override
         protected void createTaskStack(int displayId, boolean onTop, Rect outBounds) {
-            mTaskStack = WindowTestUtils.createMockTaskStack();
+            mTaskStack = mock(TaskStack.class);
 
             // Primary pinned stacks require a non-empty out bounds to be set or else all tasks
             // will be moved to the full screen stack.
             if (getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
                 outBounds.set(0, 0, 100, 100);
             }
-
         }
 
         @Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
index 123de2d..afadc79 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -24,14 +24,13 @@
 import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
 import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 
 import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
@@ -39,9 +38,7 @@
 
 import androidx.test.filters.SmallTest;
 
-import org.junit.AfterClass;
 import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
@@ -54,33 +51,12 @@
 @Presubmit
 public class AppTransitionTests extends WindowTestsBase {
 
-    private static RootWindowContainer sOriginalRootWindowContainer;
-
     private DisplayContent mDc;
 
-    @BeforeClass
-    public static void setUpRootWindowContainerMock() {
-        final WindowManagerService wm = TestSystemServices.getWindowManagerService();
-        // For unit test, we don't need to test performSurfacePlacement to prevent some abnormal
-        // interaction with surfaceflinger native side.
-        sOriginalRootWindowContainer = wm.mRoot;
-        // Creating spied mock of RootWindowContainer shouldn't be done in @Before, since it will
-        // create unnecessary nested spied objects chain, because WindowManagerService object under
-        // test is a single instance shared among all tests that extend WindowTestsBase class.
-        // Instead it should be done once before running all tests in this test class.
-        wm.mRoot = spy(wm.mRoot);
-        doNothing().when(wm.mRoot).performSurfacePlacement(anyBoolean());
-    }
-
-    @AfterClass
-    public static void tearDownRootWindowContainerMock() {
-        final WindowManagerService wm = TestSystemServices.getWindowManagerService();
-        wm.mRoot = sOriginalRootWindowContainer;
-        sOriginalRootWindowContainer = null;
-    }
-
     @Before
     public void setUp() throws Exception {
+        spyOn(mWm.mRoot);
+        doNothing().when(mWm.mRoot).performSurfacePlacement(anyBoolean());
         mDc = mWm.getDefaultDisplayContentLocked();
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
index 7be331c..85b2f7b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
@@ -26,11 +26,11 @@
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
 import static com.android.server.wm.utils.CoordinateTransforms.transformPhysicalToLogicalCoordinates;
 
 import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.content.ContextWrapper;
@@ -65,8 +65,7 @@
     DisplayPolicy mDisplayPolicy;
 
     @Before
-    public void setUpBase() {
-        super.setUpBase();
+    public void setUpDisplayPolicy() {
         mDisplayPolicy = spy(mDisplayContent.getDisplayPolicy());
 
         final TestContextWrapper context =
@@ -77,9 +76,9 @@
         resources.addOverride(R.dimen.navigation_bar_height, NAV_BAR_HEIGHT);
         resources.addOverride(R.dimen.navigation_bar_height_landscape, NAV_BAR_HEIGHT);
         resources.addOverride(R.dimen.navigation_bar_width, NAV_BAR_HEIGHT);
-        when(mDisplayPolicy.getSystemUiContext()).thenReturn(context);
-        when(mDisplayPolicy.hasNavigationBar()).thenReturn(true);
-        when(mDisplayPolicy.hasStatusBar()).thenReturn(true);
+        doReturn(context).when(mDisplayPolicy).getSystemUiContext();
+        doReturn(true).when(mDisplayPolicy).hasNavigationBar();
+        doReturn(true).when(mDisplayPolicy).hasStatusBar();
 
         final int shortSizeDp =
                 Math.min(DISPLAY_WIDTH, DISPLAY_HEIGHT) * DENSITY_DEFAULT / DISPLAY_DENSITY;
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
index b15e99a..8733674 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
@@ -807,7 +807,7 @@
         private void build() throws Exception {
             mMockContext = mock(Context.class);
 
-            mMockDisplayContent = mock(WindowTestUtils.TestDisplayContent.class);
+            mMockDisplayContent = mock(DisplayContent.class);
             mMockDisplayContent.isDefaultDisplay = mIsDefaultDisplay;
             when(mMockDisplayContent.calculateDisplayCutoutForRotation(anyInt()))
                     .thenReturn(WmDisplayCutout.NO_CUTOUT);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestSystemServices.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
similarity index 66%
rename from services/tests/wmtests/src/com/android/server/wm/TestSystemServices.java
rename to services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index e540b3a..712cd1e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestSystemServices.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -57,44 +57,61 @@
 import com.android.server.Watchdog;
 import com.android.server.input.InputManagerService;
 import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.wm.utils.MockTracker;
 
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.quality.Strictness;
 
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
- * A Test utility class to create a mock {@link WindowManagerService} instance for tests.
+ * JUnit test rule to create a mock {@link WindowManagerService} instance for tests.
  */
-class TestSystemServices {
-    private static StaticMockitoSession sMockitoSession;
-    private static WindowManagerService sService;
-    private static TestWindowManagerPolicy sPolicy;
+public class SystemServicesTestRule implements TestRule {
 
-    static AtomicBoolean sCurrentMessagesProcessed = new AtomicBoolean(false);
+    private static final String TAG = SystemServicesTestRule.class.getSimpleName();
 
-    static void setUpWindowManagerService() {
-        sMockitoSession = mockitoSession()
-                .spyStatic(LockGuard.class)
-                .spyStatic(Watchdog.class)
+    private final AtomicBoolean mCurrentMessagesProcessed = new AtomicBoolean(false);
+
+    private MockTracker mMockTracker;
+    private StaticMockitoSession mMockitoSession;
+    private WindowManagerService mWindowManagerService;
+    private TestWindowManagerPolicy mWindowManagerPolicy;
+
+    /** {@link MockTracker} to track mocks created by {@link SystemServicesTestRule}. */
+    private static class Tracker extends MockTracker {
+        // This empty extended class is necessary since Mockito distinguishes a listener by it
+        // class.
+    }
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                try {
+                    runWithDexmakerShareClassLoader(SystemServicesTestRule.this::setUp);
+                    base.evaluate();
+                } finally {
+                    tearDown();
+                }
+            }
+        };
+    }
+
+    private void setUp() {
+        mMockTracker = new Tracker();
+
+        mMockitoSession = mockitoSession()
+                .spyStatic(LocalServices.class)
+                .mockStatic(LockGuard.class)
+                .mockStatic(Watchdog.class)
                 .strictness(Strictness.LENIENT)
                 .startMocking();
 
-        runWithDexmakerShareClassLoader(TestSystemServices::setUpTestWindowService);
-    }
-
-    static void tearDownWindowManagerService() {
-        waitUntilWindowManagerHandlersIdle();
-        removeLocalServices();
-        sService = null;
-        sPolicy = null;
-
-        sMockitoSession.finishMocking();
-        sMockitoSession = null;
-    }
-
-    private static void setUpTestWindowService() {
-        doReturn(null).when(() -> LockGuard.installLock(any(), anyInt()));
         doReturn(mock(Watchdog.class)).when(Watchdog::getInstance);
 
         final Context context = getInstrumentation().getTargetContext();
@@ -116,21 +133,18 @@
         doReturn(appOpsManager).when(context)
                 .getSystemService(eq(Context.APP_OPS_SERVICE));
 
-        removeLocalServices();
-
         final DisplayManagerInternal dmi = mock(DisplayManagerInternal.class);
-        LocalServices.addService(DisplayManagerInternal.class, dmi);
+        doReturn(dmi).when(() -> LocalServices.getService(eq(DisplayManagerInternal.class)));
 
         final PowerManagerInternal pmi = mock(PowerManagerInternal.class);
-        LocalServices.addService(PowerManagerInternal.class, pmi);
         final PowerSaveState state = new PowerSaveState.Builder().build();
         doReturn(state).when(pmi).getLowPowerState(anyInt());
+        doReturn(pmi).when(() -> LocalServices.getService(eq(PowerManagerInternal.class)));
 
         final ActivityManagerInternal ami = mock(ActivityManagerInternal.class);
-        LocalServices.addService(ActivityManagerInternal.class, ami);
+        doReturn(ami).when(() -> LocalServices.getService(eq(ActivityManagerInternal.class)));
 
         final ActivityTaskManagerInternal atmi = mock(ActivityTaskManagerInternal.class);
-        LocalServices.addService(ActivityTaskManagerInternal.class, atmi);
         doAnswer((InvocationOnMock invocationOnMock) -> {
             final Runnable runnable = invocationOnMock.getArgument(0);
             if (runnable != null) {
@@ -138,6 +152,7 @@
             }
             return null;
         }).when(atmi).notifyKeyguardFlagsChanged(nullable(Runnable.class), anyInt());
+        doReturn(atmi).when(() -> LocalServices.getService(eq(ActivityTaskManagerInternal.class)));
 
         final InputManagerService ims = mock(InputManagerService.class);
         // InputChannel is final and can't be mocked.
@@ -150,31 +165,46 @@
         final WindowManagerGlobalLock wmLock = new WindowManagerGlobalLock();
         doReturn(wmLock).when(atms).getGlobalLock();
 
-        sPolicy = new TestWindowManagerPolicy(TestSystemServices::getWindowManagerService);
-        sService = WindowManagerService.main(context, ims, false, false, sPolicy, atms);
+        mWindowManagerPolicy = new TestWindowManagerPolicy(this::getWindowManagerService);
+        mWindowManagerService = WindowManagerService.main(
+                context, ims, false, false, mWindowManagerPolicy, atms);
 
-        sService.onInitReady();
+        mWindowManagerService.onInitReady();
 
-        final Display display = sService.mDisplayManager.getDisplay(DEFAULT_DISPLAY);
+        final Display display = mWindowManagerService.mDisplayManager.getDisplay(DEFAULT_DISPLAY);
         // Display creation is driven by the ActivityManagerService via
         // ActivityStackSupervisor. We emulate those steps here.
-        sService.mRoot.createDisplayContent(display, mock(ActivityDisplay.class));
+        mWindowManagerService.mRoot.createDisplayContent(display, mock(ActivityDisplay.class));
+
+        mMockTracker.stopTracking();
+    }
+
+    private void tearDown() {
+        waitUntilWindowManagerHandlersIdle();
+        removeLocalServices();
+        mWindowManagerService = null;
+        mWindowManagerPolicy = null;
+        if (mMockitoSession != null) {
+            mMockitoSession.finishMocking();
+            mMockitoSession = null;
+        }
+
+        if (mMockTracker != null) {
+            mMockTracker.close();
+            mMockTracker = null;
+        }
     }
 
     private static void removeLocalServices() {
-        LocalServices.removeServiceForTest(DisplayManagerInternal.class);
-        LocalServices.removeServiceForTest(PowerManagerInternal.class);
-        LocalServices.removeServiceForTest(ActivityManagerInternal.class);
-        LocalServices.removeServiceForTest(ActivityTaskManagerInternal.class);
         LocalServices.removeServiceForTest(WindowManagerInternal.class);
         LocalServices.removeServiceForTest(WindowManagerPolicy.class);
     }
 
-    static WindowManagerService getWindowManagerService() {
-        return sService;
+    WindowManagerService getWindowManagerService() {
+        return mWindowManagerService;
     }
 
-    static void cleanupWindowManagerHandlers() {
+    void cleanupWindowManagerHandlers() {
         final WindowManagerService wm = getWindowManagerService();
         if (wm == null) {
             return;
@@ -184,7 +214,7 @@
         SurfaceAnimationThread.getHandler().removeCallbacksAndMessages(null);
     }
 
-    static void waitUntilWindowManagerHandlersIdle() {
+    void waitUntilWindowManagerHandlersIdle() {
         final WindowManagerService wm = getWindowManagerService();
         if (wm == null) {
             return;
@@ -196,21 +226,21 @@
         waitHandlerIdle(SurfaceAnimationThread.getHandler());
     }
 
-    private static void waitHandlerIdle(Handler handler) {
-        synchronized (sCurrentMessagesProcessed) {
+    private void waitHandlerIdle(Handler handler) {
+        synchronized (mCurrentMessagesProcessed) {
             // Add a message to the handler queue and make sure it is fully processed before we move
             // on. This makes sure all previous messages in the handler are fully processed vs. just
             // popping them from the message queue.
-            sCurrentMessagesProcessed.set(false);
+            mCurrentMessagesProcessed.set(false);
             handler.post(() -> {
-                synchronized (sCurrentMessagesProcessed) {
-                    sCurrentMessagesProcessed.set(true);
-                    sCurrentMessagesProcessed.notifyAll();
+                synchronized (mCurrentMessagesProcessed) {
+                    mCurrentMessagesProcessed.set(true);
+                    mCurrentMessagesProcessed.notifyAll();
                 }
             });
-            while (!sCurrentMessagesProcessed.get()) {
+            while (!mCurrentMessagesProcessed.get()) {
                 try {
-                    sCurrentMessagesProcessed.wait();
+                    mCurrentMessagesProcessed.wait();
                 } catch (InterruptedException e) {
                 }
             }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
index 1e58e41..1b396f5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
@@ -18,6 +18,8 @@
 
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
@@ -26,7 +28,6 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyInt;
 
 import android.platform.test.annotations.Presubmit;
 import android.view.InputChannel;
@@ -63,8 +64,7 @@
         }
 
         spyOn(mDisplayContent);
-        InputMonitor inputMonitor = mock(InputMonitor.class);
-        when(mDisplayContent.getInputMonitor()).thenReturn(inputMonitor);
+        doReturn(mock(InputMonitor.class)).when(mDisplayContent).getInputMonitor();
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
index fb30f8b..61c1d39 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
@@ -118,7 +118,7 @@
     public void setUp() throws Exception {
         mWindowToken = createAppWindowToken(mWm.getDefaultDisplayContentLocked(),
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
-        mStubStack = WindowTestUtils.createMockTaskStack();
+        mStubStack = mock(TaskStack.class);
     }
 
     // Do not use this function directly in the tests below. Instead, use more explicit function
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
index 114eac9..99cbb81 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
@@ -20,97 +20,25 @@
 import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
 
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
 import android.app.ActivityManager;
 import android.content.ComponentName;
-import android.content.Context;
-import android.os.Binder;
 import android.os.Build;
 import android.os.IBinder;
-import android.view.Display;
 import android.view.IApplicationToken;
 import android.view.IWindow;
-import android.view.Surface;
 import android.view.SurfaceControl.Transaction;
 import android.view.WindowManager;
 
 /**
- * A collection of static functions that can be referenced by other test packages to provide access
- * to WindowManager related test functionality.
+ * A collection of static functions that provide access to WindowManager related test functionality.
  */
-public class WindowTestUtils {
+class WindowTestUtils {
     private static int sNextTaskId = 0;
 
-    /** An extension of {@link DisplayContent} to gain package scoped access. */
-    public static class TestDisplayContent extends DisplayContent {
-
-        private TestDisplayContent(Display display, WindowManagerService service,
-                ActivityDisplay activityDisplay) {
-            super(display, service, activityDisplay);
-        }
-
-        /**
-         * Stubbing method of non-public parent class isn't supported, so here explicitly overrides.
-         */
-        @Override
-        public DisplayRotation getDisplayRotation() {
-            return null;
-        }
-
-        /**
-         * Stubbing method of non-public parent class isn't supported, so here explicitly overrides.
-         */
-        @Override
-        DockedStackDividerController getDockedDividerController() {
-            return null;
-        }
-
-        /** Create a mocked default {@link DisplayContent}. */
-        public static TestDisplayContent create(Context context) {
-            final TestDisplayContent displayContent = mock(TestDisplayContent.class);
-            displayContent.isDefaultDisplay = true;
-
-            final DisplayPolicy displayPolicy = mock(DisplayPolicy.class);
-            when(displayPolicy.navigationBarCanMove()).thenReturn(true);
-            when(displayPolicy.hasNavigationBar()).thenReturn(true);
-
-            final DisplayRotation displayRotation = new DisplayRotation(
-                    mock(WindowManagerService.class), displayContent, displayPolicy,
-                    mock(DisplayWindowSettings.class), context, new Object());
-            displayRotation.mPortraitRotation = Surface.ROTATION_0;
-            displayRotation.mLandscapeRotation = Surface.ROTATION_90;
-            displayRotation.mUpsideDownRotation = Surface.ROTATION_180;
-            displayRotation.mSeascapeRotation = Surface.ROTATION_270;
-
-            when(displayContent.getDisplayRotation()).thenReturn(displayRotation);
-
-            return displayContent;
-        }
-    }
-
-    /** Create a mocked default {@link DisplayContent}. */
-    public static TestDisplayContent createTestDisplayContent() {
-        final TestDisplayContent displayContent = mock(TestDisplayContent.class);
-        DockedStackDividerController divider = mock(DockedStackDividerController.class);
-        when(displayContent.getDockedDividerController()).thenReturn(divider);
-
-        return displayContent;
-    }
-
-    /**
-     * Creates a mock instance of {@link TestTaskStack}.
-     */
-    public static TaskStack createMockTaskStack() {
-        return mock(TestTaskStack.class);
-    }
-
     /** Creates a {@link Task} and adds it to the specified {@link TaskStack}. */
-    public static Task createTaskInStack(WindowManagerService service, TaskStack stack,
+    static Task createTaskInStack(WindowManagerService service, TaskStack stack,
             int userId) {
         synchronized (service.mGlobalLock) {
             final Task newTask = new Task(sNextTaskId++, stack, userId, service, 0, false,
@@ -121,27 +49,12 @@
     }
 
     /** Creates an {@link AppWindowToken} and adds it to the specified {@link Task}. */
-    public static TestAppWindowToken createAppWindowTokenInTask(DisplayContent dc, Task task) {
+    static TestAppWindowToken createAppWindowTokenInTask(DisplayContent dc, Task task) {
         final TestAppWindowToken newToken = createTestAppWindowToken(dc);
         task.addChild(newToken, POSITION_TOP);
         return newToken;
     }
 
-    /**
-     * An extension of {@link TestTaskStack}, which overrides package scoped methods that would not
-     * normally be mocked out.
-     */
-    public static class TestTaskStack extends TaskStack {
-        TestTaskStack(WindowManagerService service, int stackId) {
-            super(service, stackId, null);
-        }
-
-        @Override
-        void addTask(Task task, int position, boolean showForAllUsers, boolean moveParents) {
-            // Do nothing.
-        }
-    }
-
     static TestAppWindowToken createTestAppWindowToken(DisplayContent dc) {
         synchronized (dc.mWmService.mGlobalLock) {
             return new TestAppWindowToken(dc);
@@ -149,7 +62,7 @@
     }
 
     /** Used so we can gain access to some protected members of the {@link AppWindowToken} class. */
-    public static class TestAppWindowToken extends AppWindowToken {
+    static class TestAppWindowToken extends AppWindowToken {
         boolean mOnTop = false;
         private boolean mSkipPrepareSurfaces;
         private Transaction mPendingTransactionOverride;
@@ -165,17 +78,6 @@
             mTargetSdk = Build.VERSION_CODES.CUR_DEVELOPMENT;
         }
 
-        TestAppWindowToken(WindowManagerService service, IApplicationToken token,
-                ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
-                long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers,
-                int targetSdk, int orientation, int rotationAnimationHint, int configChanges,
-                boolean launchTaskBehind, boolean alwaysFocusable, ActivityRecord activityRecord) {
-            super(service, token, activityComponent, voiceInteraction, dc,
-                    inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk,
-                    orientation, rotationAnimationHint, configChanges, launchTaskBehind,
-                    alwaysFocusable, activityRecord);
-        }
-
         int getWindowsCount() {
             return mChildren.size();
         }
@@ -192,14 +94,6 @@
             return mChildren.peekLast();
         }
 
-        int positionInParent() {
-            return getParent().mChildren.indexOf(this);
-        }
-
-        void setIsOnTop(boolean onTop) {
-            mOnTop = onTop;
-        }
-
         @Override
         void onParentChanged() {
             if (!mSkipOnParentChanged) {
@@ -264,7 +158,7 @@
     }
 
     /* Used so we can gain access to some protected members of the {@link WindowToken} class */
-    public static class TestWindowToken extends WindowToken {
+    static class TestWindowToken extends WindowToken {
 
         private TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) {
             super(dc.mWmService, mock(IBinder.class), type, persistOnEmpty, dc,
@@ -281,7 +175,7 @@
     }
 
     /* Used so we can gain access to some protected members of the {@link Task} class */
-    public static class TestTask extends Task {
+    static class TestTask extends Task {
         boolean mShouldDeferRemoval = false;
         boolean mOnDisplayChangedCalled = false;
         private boolean mIsAnimating = false;
@@ -318,26 +212,13 @@
         }
     }
 
-    public static TestTask createTestTask(TaskStack stack) {
+    static TestTask createTestTask(TaskStack stack) {
         return new TestTask(sNextTaskId++, stack, 0, stack.mWmService, RESIZE_MODE_UNRESIZEABLE,
                 false, mock(TaskRecord.class));
     }
 
-    public static class TestIApplicationToken implements IApplicationToken {
-
-        private final Binder mBinder = new Binder();
-        @Override
-        public IBinder asBinder() {
-            return mBinder;
-        }
-        @Override
-        public String getName() {
-            return null;
-        }
-    }
-
     /** Used to track resize reports. */
-    public static class TestWindowState extends WindowState {
+    static class TestWindowState extends WindowState {
         boolean mResizeReported;
 
         TestWindowState(WindowManagerService service, Session session, IWindow window,
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index a83bf2a..5ed39b2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -58,6 +58,7 @@
 import org.junit.BeforeClass;
 import org.junit.Rule;
 
+import java.io.IOException;
 import java.util.HashSet;
 import java.util.LinkedList;
 
@@ -78,8 +79,6 @@
     private static int sNextDisplayId = DEFAULT_DISPLAY + 1;
     static int sNextStackId = 1000;
 
-    private static MockTracker sMockTracker;
-
     /** Non-default display. */
     DisplayContent mDisplayContent;
     DisplayInfo mDisplayInfo = new DisplayInfo();
@@ -94,6 +93,8 @@
     WindowState mChildAppWindowBelow;
     HashSet<WindowState> mCommonWindows;
 
+    private MockTracker mMockTracker;
+
     /**
      * To restore the original SurfaceControl.Transaction factory if any tests changed
      * {@link WindowManagerService#mTransactionFactory}.
@@ -103,6 +104,8 @@
     @Rule
     public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
             new DexmakerShareClassLoaderRule();
+    @Rule
+    public final SystemServicesTestRule mSystemServicesTestRule = new SystemServicesTestRule();
 
     static WindowState.PowerManagerWrapper sPowerManagerWrapper;
 
@@ -110,25 +113,18 @@
     public static void setUpOnceBase() {
         AttributeCache.init(getInstrumentation().getTargetContext());
 
-        TestSystemServices.setUpWindowManagerService();
-
-        // MockTracker needs to be initialized after TestSystemServices because we don't want to
-        // track static mocks.
-        sMockTracker = new MockTracker();
-
         sPowerManagerWrapper = mock(WindowState.PowerManagerWrapper.class);
     }
 
     @AfterClass
-    public static void tearDownOnceBase() {
-        sMockTracker.close();
-        sMockTracker = null;
-
-        TestSystemServices.tearDownWindowManagerService();
+    public static void tearDownOnceBase() throws IOException {
+        sPowerManagerWrapper = null;
     }
 
     @Before
     public void setUpBase() {
+        mMockTracker = new MockTracker();
+
         // If @Before throws an exception, the error isn't logged. This will make sure any failures
         // in the set up are clear. This can be removed when b/37850063 is fixed.
         try {
@@ -136,7 +132,7 @@
 
             final Context context = getInstrumentation().getTargetContext();
 
-            mWm = TestSystemServices.getWindowManagerService();
+            mWm = mSystemServicesTestRule.getWindowManagerService();
             mOriginalTransactionFactory = mWm.mTransactionFactory;
             beforeCreateDisplay();
 
@@ -216,11 +212,14 @@
             }
 
             // Cleaned up everything in Handler.
-            TestSystemServices.cleanupWindowManagerHandlers();
+            mSystemServicesTestRule.cleanupWindowManagerHandlers();
         } catch (Exception e) {
             Log.e(TAG, "Failed to tear down test", e);
             throw e;
         }
+
+        mMockTracker.close();
+        mMockTracker = null;
     }
 
     private WindowState createCommonWindow(WindowState parent, int type, String name) {
@@ -237,7 +236,7 @@
      * Waits until the main handler for WM has processed all messages.
      */
     void waitUntilHandlersIdle() {
-        TestSystemServices.waitUntilWindowManagerHandlersIdle();
+        mSystemServicesTestRule.waitUntilWindowManagerHandlersIdle();
     }
 
     private WindowToken createWindowToken(
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/MockTracker.java b/services/tests/wmtests/src/com/android/server/wm/utils/MockTracker.java
index 1ce463b..a6e675a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/utils/MockTracker.java
+++ b/services/tests/wmtests/src/com/android/server/wm/utils/MockTracker.java
@@ -21,6 +21,7 @@
 import org.mockito.Mockito;
 import org.mockito.MockitoFramework;
 import org.mockito.internal.creation.settings.CreationSettings;
+import org.mockito.internal.util.MockUtil;
 import org.mockito.listeners.MockCreationListener;
 import org.mockito.mock.MockCreationSettings;
 
@@ -33,7 +34,7 @@
  * same type registered.
  */
 public class MockTracker implements MockCreationListener, AutoCloseable {
-    private static final String TAG = "MockTracker";
+    private static final String TAG = MockTracker.class.getSimpleName();
 
     private static final Field SPIED_INSTANCE_FIELD;
 
@@ -54,6 +55,10 @@
         mMockitoFramework.addListener(this);
     }
 
+    public void stopTracking() {
+        mMockitoFramework.removeListener(this);
+    }
+
     @Override
     public void onMockCreated(Object mock, MockCreationSettings settings) {
         mMocks.put(mock, null);
@@ -83,10 +88,8 @@
         mMockitoFramework.removeListener(this);
 
         for (final Object mock : mMocks.keySet()) {
-            try {
+            if (MockUtil.isMock(mock)) {
                 Mockito.reset(mock);
-            } catch (Exception e) {
-                Log.e(TAG, "Failed to reset " + mock, e);
             }
         }
         mMocks.clear();