diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java
new file mode 100644
index 0000000..f741c70
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import android.app.ActivityOptions;
+import android.content.pm.ActivityInfo;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.server.am.LaunchParamsController.LaunchParams;
+import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.Test;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.doAnswer;
+
+import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
+
+/**
+ * Tests for exercising resizing bounds due to activity options.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:ActivityLaunchParamsModifierTests
+ */
+@MediumTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class ActivityLaunchParamsModifierTests extends ActivityTestsBase {
+    private ActivityLaunchParamsModifier mModifier;
+    private ActivityManagerService mService;
+    private ActivityStack mStack;
+    private TaskRecord mTask;
+    private ActivityRecord mActivity;
+
+    private LaunchParams mCurrent;
+    private LaunchParams mResult;
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mService = createActivityManagerService();
+        mModifier = new ActivityLaunchParamsModifier(mService.mStackSupervisor);
+        mCurrent = new LaunchParams();
+        mResult = new LaunchParams();
+
+
+        mStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        mTask = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
+        mActivity = new ActivityBuilder(mService).setTask(mTask).build();
+    }
+
+
+    @Test
+    public void testSkippedInvocations() throws Exception {
+        // No specified activity should be ignored
+        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
+                null /*activity*/, null /*source*/, null /*options*/, mCurrent, mResult));
+
+        // No specified activity options should be ignored
+        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
+                mActivity, null /*source*/, null /*options*/, mCurrent, mResult));
+
+        // launch bounds specified should be ignored.
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
+                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
+
+        // Non-resizeable records should be ignored
+        mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+        assertFalse(mActivity.isResizeable());
+        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
+                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
+
+        // make record resizeable
+        mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
+        assertTrue(mActivity.isResizeable());
+
+        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
+                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
+
+        // Does not support freeform
+        mService.mSupportsFreeformWindowManagement = false;
+        assertFalse(mService.mStackSupervisor.canUseActivityOptionsLaunchBounds(options));
+        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
+                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
+
+        mService.mSupportsFreeformWindowManagement = true;
+        options.setLaunchBounds(new Rect());
+        assertTrue(mService.mStackSupervisor.canUseActivityOptionsLaunchBounds(options));
+
+        // Invalid bounds
+        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
+                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
+        options.setLaunchBounds(new Rect(0, 0, -1, -1));
+        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
+                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
+
+        // Valid bounds should cause the positioner to be applied.
+        options.setLaunchBounds(new Rect(0, 0, 100, 100));
+        assertEquals(RESULT_DONE, mModifier.onCalculate(null /*task*/, null /*layout*/,
+                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
+    }
+
+    @Test
+    public void testBoundsExtraction() throws Exception {
+        // Make activity resizeable and enable freeform mode.
+        mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
+        mService.mSupportsFreeformWindowManagement = true;
+
+        ActivityOptions options = ActivityOptions.makeBasic();
+        final Rect proposedBounds = new Rect(20, 30, 45, 40);
+        options.setLaunchBounds(proposedBounds);
+
+        assertEquals(RESULT_DONE, mModifier.onCalculate(null /*task*/, null /*layout*/,
+                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
+        assertEquals(mResult.mBounds, proposedBounds);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java
new file mode 100644
index 0000000..bce87dc
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.app.ActivityManagerInternal;
+import android.os.SystemClock;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Test class for {@link ActivityManagerInternal}.
+ *
+ * To run the tests, use
+ *
+ * runtest -c com.android.server.am.ActivityManagerInternalTest frameworks-services
+ *
+ * or the following steps:
+ *
+ * Build: m FrameworksServicesTests
+ * Install: adb install -r \
+ *     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
+ * Run: adb shell am instrument -e class com.android.server.am.ActivityManagerInternalTest -w \
+ *     com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
+ */
+@RunWith(AndroidJUnit4.class)
+public class ActivityManagerInternalTest {
+    private static final int TEST_UID1 = 111;
+    private static final int TEST_UID2 = 112;
+
+    private static final long TEST_PROC_STATE_SEQ1 = 1111;
+    private static final long TEST_PROC_STATE_SEQ2 = 1112;
+    private static final long TEST_PROC_STATE_SEQ3 = 1113;
+
+    @Mock private ActivityManagerService.Injector mMockInjector;
+
+    private ActivityManagerService mAms;
+    private ActivityManagerInternal mAmi;
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mAms = new ActivityManagerService(mMockInjector);
+        mAmi = mAms.new LocalService();
+    }
+
+    @MediumTest
+    @Test
+    public void testNotifyNetworkPolicyRulesUpdated() throws Exception {
+        // Check there is no crash when there are no active uid records.
+        mAmi.notifyNetworkPolicyRulesUpdated(TEST_UID1, TEST_PROC_STATE_SEQ1);
+
+        // Notify that network policy rules are updated for TEST_UID1 and verify that
+        // UidRecord.lastNetworkUpdateProcStateSeq is updated and any blocked threads are notified.
+        verifyNetworkUpdatedProcStateSeq(
+                TEST_PROC_STATE_SEQ2, // curProcStateSeq
+                TEST_PROC_STATE_SEQ1, // lastNetworkUpdateProcStateSeq
+                TEST_PROC_STATE_SEQ2, // procStateSeq to notify
+                true); // expectNotify
+
+        // Notify that network policy rules are updated for TEST_UID1 with already handled
+        // procStateSeq and verify that there is no notify call.
+        verifyNetworkUpdatedProcStateSeq(
+                TEST_PROC_STATE_SEQ1, // curProcStateSeq
+                TEST_PROC_STATE_SEQ1, // lastNetworkUpdateProcStateSeq
+                TEST_PROC_STATE_SEQ1, // procStateSeq to notify
+                false); // expectNotify
+
+        // Notify that network policy rules are updated for TEST_UID1 with procStateSeq older
+        // than it's UidRecord.curProcStateSeq and verify that there is no notify call.
+        verifyNetworkUpdatedProcStateSeq(
+                TEST_PROC_STATE_SEQ3, // curProcStateSeq
+                TEST_PROC_STATE_SEQ1, // lastNetworkUpdateProcStateSeq
+                TEST_PROC_STATE_SEQ2, // procStateSeq to notify
+                false); // expectNotify
+    }
+
+    private void verifyNetworkUpdatedProcStateSeq(long curProcStateSeq,
+            long lastNetworkUpdatedProcStateSeq, long expectedProcStateSeq, boolean expectNotify)
+            throws Exception {
+        final UidRecord record1 = addActiveUidRecord(TEST_UID1, curProcStateSeq,
+                lastNetworkUpdatedProcStateSeq);
+        final UidRecord record2 = addActiveUidRecord(TEST_UID2, curProcStateSeq,
+                lastNetworkUpdatedProcStateSeq);
+
+        final CustomThread thread1 = new CustomThread(record1.networkStateLock);
+        thread1.startAndWait("Unexpected state for " + record1);
+        final CustomThread thread2 = new CustomThread(record2.networkStateLock);
+        thread2.startAndWait("Unexpected state for " + record2);
+
+        mAmi.notifyNetworkPolicyRulesUpdated(TEST_UID1, expectedProcStateSeq);
+        assertEquals(record1 + " should be updated",
+                expectedProcStateSeq, record1.lastNetworkUpdatedProcStateSeq);
+        assertEquals(record2 + " should not be updated",
+                lastNetworkUpdatedProcStateSeq, record2.lastNetworkUpdatedProcStateSeq);
+
+        if (expectNotify) {
+            thread1.assertTerminated("Unexpected state for " + record1);
+            assertTrue("Threads waiting for network should be notified: " + record1,
+                    thread1.mNotified);
+        } else {
+            thread1.assertWaiting("Unexpected state for " + record1);
+            thread1.interrupt();
+        }
+        thread2.assertWaiting("Unexpected state for " + record2);
+        thread2.interrupt();
+
+        mAms.mActiveUids.clear();
+    }
+
+    private UidRecord addActiveUidRecord(int uid, long curProcStateSeq,
+            long lastNetworkUpdatedProcStateSeq) {
+        final UidRecord record = new UidRecord(uid);
+        record.lastNetworkUpdatedProcStateSeq = lastNetworkUpdatedProcStateSeq;
+        record.curProcStateSeq = curProcStateSeq;
+        record.waitingForNetwork = true;
+        mAms.mActiveUids.put(uid, record);
+        return record;
+    }
+
+    static class CustomThread extends Thread {
+        private static final long WAIT_TIMEOUT_MS = 1000;
+        private static final long WAIT_INTERVAL_MS = 100;
+
+        private final Object mLock;
+        private Runnable mRunnable;
+        boolean mNotified;
+
+        public CustomThread(Object lock) {
+            mLock = lock;
+        }
+
+        public CustomThread(Object lock, Runnable runnable) {
+            super(runnable);
+            mLock = lock;
+            mRunnable = runnable;
+        }
+
+        @Override
+        public void run() {
+            if (mRunnable != null) {
+                mRunnable.run();
+            } else {
+                synchronized (mLock) {
+                    try {
+                        mLock.wait();
+                    } catch (InterruptedException e) {
+                        Thread.currentThread().interrupted();
+                    }
+                }
+            }
+            mNotified = !Thread.interrupted();
+        }
+
+        public void startAndWait(String errMsg) throws Exception {
+            startAndWait(errMsg, false);
+        }
+
+        public void startAndWait(String errMsg, boolean timedWaiting) throws Exception {
+            start();
+            final long endTime = SystemClock.elapsedRealtime() + WAIT_TIMEOUT_MS;
+            final Thread.State stateToReach = timedWaiting
+                    ? Thread.State.TIMED_WAITING : Thread.State.WAITING;
+            while (getState() != stateToReach
+                    && SystemClock.elapsedRealtime() < endTime) {
+                Thread.sleep(WAIT_INTERVAL_MS);
+            }
+            if (timedWaiting) {
+                assertTimedWaiting(errMsg);
+            } else {
+                assertWaiting(errMsg);
+            }
+        }
+
+        public void assertWaiting(String errMsg) {
+            assertEquals(errMsg, Thread.State.WAITING, getState());
+        }
+
+        public void assertTimedWaiting(String errMsg) {
+            assertEquals(errMsg, Thread.State.TIMED_WAITING, getState());
+        }
+
+        public void assertTerminated(String errMsg) throws Exception {
+            final long endTime = SystemClock.elapsedRealtime() + WAIT_TIMEOUT_MS;
+            while (getState() != Thread.State.TERMINATED
+                    && SystemClock.elapsedRealtime() < endTime) {
+                Thread.sleep(WAIT_INTERVAL_MS);
+            }
+            assertEquals(errMsg, Thread.State.TERMINATED, getState());
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
new file mode 100644
index 0000000..c70d1e1
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -0,0 +1,833 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
+import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
+import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
+import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
+import static android.app.ActivityManager.PROCESS_STATE_RECEIVER;
+import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_TOP;
+import static android.util.DebugUtils.valueToString;
+import static com.android.server.am.ActivityManagerInternalTest.CustomThread;
+import static com.android.server.am.ActivityManagerService.DISPATCH_UIDS_CHANGED_UI_MSG;
+import static com.android.server.am.ActivityManagerService.Injector;
+import static com.android.server.am.ActivityManagerService.NETWORK_STATE_BLOCK;
+import static com.android.server.am.ActivityManagerService.NETWORK_STATE_NO_CHANGE;
+import static com.android.server.am.ActivityManagerService.NETWORK_STATE_UNBLOCK;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
+import android.app.AppOpsManager;
+import android.app.IApplicationThread;
+import android.app.IUidObserver;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.support.test.filters.MediumTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.internal.os.BatteryStatsImpl;
+import com.android.server.AppOpsService;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+
+/**
+ * Test class for {@link ActivityManagerService}.
+ *
+ * To run the tests, use
+ *
+ * runtest -c com.android.server.am.ActivityManagerServiceTest frameworks-services
+ *
+ * or the following steps:
+ *
+ * Build: m FrameworksServicesTests
+ * Install: adb install -r \
+ *     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
+ * Run: adb shell am instrument -e class com.android.server.am.ActivityManagerServiceTest -w \
+ *     com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ActivityManagerServiceTest {
+    private static final String TAG = ActivityManagerServiceTest.class.getSimpleName();
+
+    private static final int TEST_UID = 11111;
+
+    private static final long TEST_PROC_STATE_SEQ1 = 555;
+    private static final long TEST_PROC_STATE_SEQ2 = 556;
+
+    private static final int[] UID_RECORD_CHANGES = {
+        UidRecord.CHANGE_PROCSTATE,
+        UidRecord.CHANGE_GONE,
+        UidRecord.CHANGE_GONE | UidRecord.CHANGE_IDLE,
+        UidRecord.CHANGE_IDLE,
+        UidRecord.CHANGE_ACTIVE
+    };
+
+    @Mock private Context mContext;
+    @Mock private AppOpsService mAppOpsService;
+    @Mock private PackageManager mPackageManager;
+    @Mock private BatteryStatsImpl mBatteryStatsImpl;
+
+    private TestInjector mInjector;
+    private ActivityManagerService mAms;
+    private HandlerThread mHandlerThread;
+    private TestHandler mHandler;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mHandlerThread = new HandlerThread(TAG);
+        mHandlerThread.start();
+        mHandler = new TestHandler(mHandlerThread.getLooper());
+        mInjector = new TestInjector();
+        mAms = new ActivityManagerService(mInjector);
+        mAms.mWaitForNetworkTimeoutMs = 2000;
+
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
+    }
+
+    @After
+    public void tearDown() {
+        mHandlerThread.quit();
+    }
+
+    @MediumTest
+    @Test
+    public void incrementProcStateSeqAndNotifyAppsLocked() throws Exception {
+
+        final UidRecord uidRec = addUidRecord(TEST_UID);
+        addUidRecord(TEST_UID + 1);
+
+        // Uid state is not moving from background to foreground or vice versa.
+        verifySeqCounterAndInteractions(uidRec,
+                PROCESS_STATE_TOP, // prevState
+                PROCESS_STATE_TOP, // curState
+                0, // expectedGlobalCounter
+                0, // exptectedCurProcStateSeq
+                NETWORK_STATE_NO_CHANGE, // expectedBlockState
+                false); // expectNotify
+
+        // Uid state is moving from foreground to background.
+        verifySeqCounterAndInteractions(uidRec,
+                PROCESS_STATE_FOREGROUND_SERVICE, // prevState
+                PROCESS_STATE_SERVICE, // curState
+                1, // expectedGlobalCounter
+                1, // exptectedCurProcStateSeq
+                NETWORK_STATE_UNBLOCK, // expectedBlockState
+                true); // expectNotify
+
+        // Explicitly setting the seq counter for more verification.
+        mAms.mProcStateSeqCounter = 42;
+
+        // Uid state is not moving from background to foreground or vice versa.
+        verifySeqCounterAndInteractions(uidRec,
+                PROCESS_STATE_IMPORTANT_BACKGROUND, // prevState
+                PROCESS_STATE_IMPORTANT_FOREGROUND, // curState
+                42, // expectedGlobalCounter
+                1, // exptectedCurProcStateSeq
+                NETWORK_STATE_NO_CHANGE, // expectedBlockState
+                false); // expectNotify
+
+        // Uid state is moving from background to foreground.
+        verifySeqCounterAndInteractions(uidRec,
+                PROCESS_STATE_LAST_ACTIVITY, // prevState
+                PROCESS_STATE_TOP, // curState
+                43, // expectedGlobalCounter
+                43, // exptectedCurProcStateSeq
+                NETWORK_STATE_BLOCK, // expectedBlockState
+                false); // expectNotify
+
+        // verify waiting threads are not notified.
+        uidRec.waitingForNetwork = false;
+        // Uid state is moving from foreground to background.
+        verifySeqCounterAndInteractions(uidRec,
+                PROCESS_STATE_FOREGROUND_SERVICE, // prevState
+                PROCESS_STATE_SERVICE, // curState
+                44, // expectedGlobalCounter
+                44, // exptectedCurProcStateSeq
+                NETWORK_STATE_UNBLOCK, // expectedBlockState
+                false); // expectNotify
+
+        // Verify when uid is not restricted, procStateSeq is not incremented.
+        uidRec.waitingForNetwork = true;
+        mInjector.setNetworkRestrictedForUid(false);
+        verifySeqCounterAndInteractions(uidRec,
+                PROCESS_STATE_IMPORTANT_BACKGROUND, // prevState
+                PROCESS_STATE_TOP, // curState
+                44, // expectedGlobalCounter
+                44, // exptectedCurProcStateSeq
+                -1, // expectedBlockState, -1 to verify there are no interactions with main thread.
+                false); // expectNotify
+
+        // Verify when waitForNetworkTimeout is 0, then procStateSeq is not incremented.
+        mAms.mWaitForNetworkTimeoutMs = 0;
+        mInjector.setNetworkRestrictedForUid(true);
+        verifySeqCounterAndInteractions(uidRec,
+                PROCESS_STATE_TOP, // prevState
+                PROCESS_STATE_IMPORTANT_BACKGROUND, // curState
+                44, // expectedGlobalCounter
+                44, // exptectedCurProcStateSeq
+                -1, // expectedBlockState, -1 to verify there are no interactions with main thread.
+                false); // expectNotify
+
+        // Verify when the uid doesn't have internet permission, then procStateSeq is not
+        // incremented.
+        uidRec.hasInternetPermission = false;
+        mAms.mWaitForNetworkTimeoutMs = 111;
+        mInjector.setNetworkRestrictedForUid(true);
+        verifySeqCounterAndInteractions(uidRec,
+                PROCESS_STATE_CACHED_ACTIVITY, // prevState
+                PROCESS_STATE_FOREGROUND_SERVICE, // curState
+                44, // expectedGlobalCounter
+                44, // exptectedCurProcStateSeq
+                -1, // expectedBlockState, -1 to verify there are no interactions with main thread.
+                false); // expectNotify
+
+        // Verify procStateSeq is not incremented when the uid is not an application, regardless
+        // of the process state.
+        final int notAppUid = 111;
+        final UidRecord uidRec2 = addUidRecord(notAppUid);
+        verifySeqCounterAndInteractions(uidRec2,
+                PROCESS_STATE_CACHED_EMPTY, // prevState
+                PROCESS_STATE_TOP, // curState
+                44, // expectedGlobalCounter
+                0, // exptectedCurProcStateSeq
+                -1, // expectedBlockState, -1 to verify there are no interactions with main thread.
+                false); // expectNotify
+    }
+
+    private UidRecord addUidRecord(int uid) {
+        final UidRecord uidRec = new UidRecord(uid);
+        uidRec.waitingForNetwork = true;
+        uidRec.hasInternetPermission = true;
+        mAms.mActiveUids.put(uid, uidRec);
+
+        final ProcessRecord appRec = new ProcessRecord(null, mBatteryStatsImpl,
+                new ApplicationInfo(), TAG, uid);
+        appRec.thread = Mockito.mock(IApplicationThread.class);
+        mAms.mLruProcesses.add(appRec);
+
+        return uidRec;
+    }
+
+    private void verifySeqCounterAndInteractions(UidRecord uidRec, int prevState, int curState,
+            int expectedGlobalCounter, int expectedCurProcStateSeq, int expectedBlockState,
+            boolean expectNotify) throws Exception {
+        CustomThread thread = new CustomThread(uidRec.networkStateLock);
+        thread.startAndWait("Unexpected state for " + uidRec);
+
+        uidRec.setProcState = prevState;
+        uidRec.curProcState = curState;
+        mAms.incrementProcStateSeqAndNotifyAppsLocked();
+
+        assertEquals(expectedGlobalCounter, mAms.mProcStateSeqCounter);
+        assertEquals(expectedCurProcStateSeq, uidRec.curProcStateSeq);
+
+        for (int i = mAms.mLruProcesses.size() - 1; i >= 0; --i) {
+            final ProcessRecord app = mAms.mLruProcesses.get(i);
+            // AMS should notify apps only for block states other than NETWORK_STATE_NO_CHANGE.
+            if (app.uid == uidRec.uid && expectedBlockState == NETWORK_STATE_BLOCK) {
+                verify(app.thread).setNetworkBlockSeq(uidRec.curProcStateSeq);
+            } else {
+                verifyZeroInteractions(app.thread);
+            }
+            Mockito.reset(app.thread);
+        }
+
+        if (expectNotify) {
+            thread.assertTerminated("Unexpected state for " + uidRec);
+        } else {
+            thread.assertWaiting("Unexpected state for " + uidRec);
+            thread.interrupt();
+        }
+    }
+
+    @Test
+    public void testBlockStateForUid() {
+        final UidRecord uidRec = new UidRecord(TEST_UID);
+        int expectedBlockState;
+
+        final String errorTemplate = "Block state should be %s, prevState: %s, curState: %s";
+        Function<Integer, String> errorMsg = (blockState) -> {
+            return String.format(errorTemplate,
+                    valueToString(ActivityManagerService.class, "NETWORK_STATE_", blockState),
+                    valueToString(ActivityManager.class, "PROCESS_STATE_", uidRec.setProcState),
+                    valueToString(ActivityManager.class, "PROCESS_STATE_", uidRec.curProcState));
+        };
+
+        // No change in uid state
+        uidRec.setProcState = PROCESS_STATE_RECEIVER;
+        uidRec.curProcState = PROCESS_STATE_RECEIVER;
+        expectedBlockState = NETWORK_STATE_NO_CHANGE;
+        assertEquals(errorMsg.apply(expectedBlockState),
+                expectedBlockState, mAms.getBlockStateForUid(uidRec));
+
+        // Foreground to foreground
+        uidRec.setProcState = PROCESS_STATE_FOREGROUND_SERVICE;
+        uidRec.curProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
+        expectedBlockState = NETWORK_STATE_NO_CHANGE;
+        assertEquals(errorMsg.apply(expectedBlockState),
+                expectedBlockState, mAms.getBlockStateForUid(uidRec));
+
+        // Background to background
+        uidRec.setProcState = PROCESS_STATE_CACHED_ACTIVITY;
+        uidRec.curProcState = PROCESS_STATE_CACHED_EMPTY;
+        expectedBlockState = NETWORK_STATE_NO_CHANGE;
+        assertEquals(errorMsg.apply(expectedBlockState),
+                expectedBlockState, mAms.getBlockStateForUid(uidRec));
+
+        // Background to background
+        uidRec.setProcState = PROCESS_STATE_NONEXISTENT;
+        uidRec.curProcState = PROCESS_STATE_CACHED_ACTIVITY;
+        expectedBlockState = NETWORK_STATE_NO_CHANGE;
+        assertEquals(errorMsg.apply(expectedBlockState),
+                expectedBlockState, mAms.getBlockStateForUid(uidRec));
+
+        // Background to foreground
+        uidRec.setProcState = PROCESS_STATE_SERVICE;
+        uidRec.curProcState = PROCESS_STATE_FOREGROUND_SERVICE;
+        expectedBlockState = NETWORK_STATE_BLOCK;
+        assertEquals(errorMsg.apply(expectedBlockState),
+                expectedBlockState, mAms.getBlockStateForUid(uidRec));
+
+        // Foreground to background
+        uidRec.setProcState = PROCESS_STATE_TOP;
+        uidRec.curProcState = PROCESS_STATE_LAST_ACTIVITY;
+        expectedBlockState = NETWORK_STATE_UNBLOCK;
+        assertEquals(errorMsg.apply(expectedBlockState),
+                expectedBlockState, mAms.getBlockStateForUid(uidRec));
+    }
+
+    /**
+     * This test verifies that process state changes are dispatched to observers based on the
+     * changes they wanted to listen (this is specified when registering the observer).
+     */
+    @Test
+    public void testDispatchUids_dispatchNeededChanges() throws RemoteException {
+        when(mAppOpsService.noteOperation(AppOpsManager.OP_GET_USAGE_STATS, Process.myUid(), null))
+                .thenReturn(AppOpsManager.MODE_ALLOWED);
+
+        final int[] changesToObserve = {
+            ActivityManager.UID_OBSERVER_PROCSTATE,
+            ActivityManager.UID_OBSERVER_GONE,
+            ActivityManager.UID_OBSERVER_IDLE,
+            ActivityManager.UID_OBSERVER_ACTIVE,
+            ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE
+                    | ActivityManager.UID_OBSERVER_ACTIVE | ActivityManager.UID_OBSERVER_IDLE
+        };
+        final IUidObserver[] observers = new IUidObserver.Stub[changesToObserve.length];
+        for (int i = 0; i < observers.length; ++i) {
+            observers[i] = Mockito.mock(IUidObserver.Stub.class);
+            when(observers[i].asBinder()).thenReturn((IBinder) observers[i]);
+            mAms.registerUidObserver(observers[i], changesToObserve[i] /* which */,
+                    ActivityManager.PROCESS_STATE_UNKNOWN /* cutpoint */, null /* caller */);
+
+            // When we invoke AMS.registerUidObserver, there are some interactions with observers[i]
+            // mock in RemoteCallbackList class. We don't want to test those interactions and
+            // at the same time, we don't want those to interfere with verifyNoMoreInteractions.
+            // So, resetting the mock here.
+            Mockito.reset(observers[i]);
+        }
+
+        // Add pending uid records each corresponding to a different change type UidRecord.CHANGE_*
+        final int[] changesForPendingUidRecords = UID_RECORD_CHANGES;
+
+        final int[] procStatesForPendingUidRecords = {
+            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
+            ActivityManager.PROCESS_STATE_NONEXISTENT,
+            ActivityManager.PROCESS_STATE_CACHED_EMPTY,
+            ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
+            ActivityManager.PROCESS_STATE_TOP
+        };
+        final Map<Integer, UidRecord.ChangeItem> changeItems = new HashMap<>();
+        for (int i = 0; i < changesForPendingUidRecords.length; ++i) {
+            final UidRecord.ChangeItem pendingChange = new UidRecord.ChangeItem();
+            pendingChange.change = changesForPendingUidRecords[i];
+            pendingChange.uid = i;
+            pendingChange.processState = procStatesForPendingUidRecords[i];
+            pendingChange.procStateSeq = i;
+            changeItems.put(changesForPendingUidRecords[i], pendingChange);
+            mAms.mPendingUidChanges.add(pendingChange);
+        }
+
+        mAms.dispatchUidsChanged();
+        // Verify the required changes have been dispatched to observers.
+        for (int i = 0; i < observers.length; ++i) {
+            final int changeToObserve = changesToObserve[i];
+            final IUidObserver observerToTest = observers[i];
+            if ((changeToObserve & ActivityManager.UID_OBSERVER_IDLE) != 0) {
+                // Observer listens to uid idle changes, so change items corresponding to
+                // UidRecord.CHANGE_IDLE or UidRecord.CHANGE_IDLE_GONE needs to be
+                // delivered to this observer.
+                final int[] changesToVerify = {
+                    UidRecord.CHANGE_IDLE,
+                    UidRecord.CHANGE_GONE | UidRecord.CHANGE_IDLE
+                };
+                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
+                        (observer, changeItem) -> {
+                            verify(observer).onUidIdle(changeItem.uid, changeItem.ephemeral);
+                        });
+            }
+            if ((changeToObserve & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
+                // Observer listens to uid active changes, so change items corresponding to
+                // UidRecord.CHANGE_ACTIVE needs to be delivered to this observer.
+                final int[] changesToVerify = { UidRecord.CHANGE_ACTIVE };
+                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
+                        (observer, changeItem) -> {
+                            verify(observer).onUidActive(changeItem.uid);
+                        });
+            }
+            if ((changeToObserve & ActivityManager.UID_OBSERVER_GONE) != 0) {
+                // Observer listens to uid gone changes, so change items corresponding to
+                // UidRecord.CHANGE_GONE or UidRecord.CHANGE_IDLE_GONE needs to be
+                // delivered to this observer.
+                final int[] changesToVerify = {
+                        UidRecord.CHANGE_GONE,
+                        UidRecord.CHANGE_GONE | UidRecord.CHANGE_IDLE
+                };
+                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
+                        (observer, changeItem) -> {
+                            verify(observer).onUidGone(changeItem.uid, changeItem.ephemeral);
+                        });
+            }
+            if ((changeToObserve & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
+                // Observer listens to uid procState changes, so change items corresponding to
+                // UidRecord.CHANGE_PROCSTATE or UidRecord.CHANGE_IDLE or UidRecord.CHANGE_ACTIVE
+                // needs to be delivered to this observer.
+                final int[] changesToVerify = {
+                        UidRecord.CHANGE_PROCSTATE,
+                        UidRecord.CHANGE_ACTIVE,
+                        UidRecord.CHANGE_IDLE
+                };
+                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
+                        (observer, changeItem) -> {
+                            verify(observer).onUidStateChanged(changeItem.uid,
+                                    changeItem.processState, changeItem.procStateSeq);
+                        });
+            }
+            // Verify there are no other callbacks for this observer.
+            verifyNoMoreInteractions(observerToTest);
+        }
+    }
+
+    private interface ObserverChangesVerifier {
+        void verify(IUidObserver observer, UidRecord.ChangeItem changeItem) throws RemoteException;
+    }
+
+    private void verifyObserverReceivedChanges(IUidObserver observer, int[] changesToVerify,
+            Map<Integer, UidRecord.ChangeItem> changeItems, ObserverChangesVerifier verifier)
+            throws RemoteException {
+        for (int change : changesToVerify) {
+            final UidRecord.ChangeItem changeItem = changeItems.get(change);
+            verifier.verify(observer, changeItem);
+        }
+    }
+
+    /**
+     * This test verifies that process state changes are dispatched to observers only when they
+     * change across the cutpoint (this is specified when registering the observer).
+     */
+    @Test
+    public void testDispatchUidChanges_procStateCutpoint() throws RemoteException {
+        final IUidObserver observer = Mockito.mock(IUidObserver.Stub.class);
+
+        when(observer.asBinder()).thenReturn((IBinder) observer);
+        mAms.registerUidObserver(observer, ActivityManager.UID_OBSERVER_PROCSTATE /* which */,
+                ActivityManager.PROCESS_STATE_SERVICE /* cutpoint */, null /* callingPackage */);
+        // When we invoke AMS.registerUidObserver, there are some interactions with observer
+        // mock in RemoteCallbackList class. We don't want to test those interactions and
+        // at the same time, we don't want those to interfere with verifyNoMoreInteractions.
+        // So, resetting the mock here.
+        Mockito.reset(observer);
+
+        final UidRecord.ChangeItem changeItem = new UidRecord.ChangeItem();
+        changeItem.uid = TEST_UID;
+        changeItem.change = UidRecord.CHANGE_PROCSTATE;
+        changeItem.processState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
+        changeItem.procStateSeq = 111;
+        mAms.mPendingUidChanges.add(changeItem);
+        mAms.dispatchUidsChanged();
+        // First process state message is always delivered regardless of whether the process state
+        // change is above or below the cutpoint (PROCESS_STATE_SERVICE).
+        verify(observer).onUidStateChanged(TEST_UID,
+                changeItem.processState, changeItem.procStateSeq);
+        verifyNoMoreInteractions(observer);
+
+        changeItem.processState = ActivityManager.PROCESS_STATE_RECEIVER;
+        mAms.mPendingUidChanges.add(changeItem);
+        mAms.dispatchUidsChanged();
+        // Previous process state change is below cutpoint (PROCESS_STATE_SERVICE) and
+        // the current process state change is also below cutpoint, so no callback will be invoked.
+        verifyNoMoreInteractions(observer);
+
+        changeItem.processState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+        mAms.mPendingUidChanges.add(changeItem);
+        mAms.dispatchUidsChanged();
+        // Previous process state change is below cutpoint (PROCESS_STATE_SERVICE) and
+        // the current process state change is above cutpoint, so callback will be invoked with the
+        // current process state change.
+        verify(observer).onUidStateChanged(TEST_UID,
+                changeItem.processState, changeItem.procStateSeq);
+        verifyNoMoreInteractions(observer);
+
+        changeItem.processState = ActivityManager.PROCESS_STATE_TOP;
+        mAms.mPendingUidChanges.add(changeItem);
+        mAms.dispatchUidsChanged();
+        // Previous process state change is above cutpoint (PROCESS_STATE_SERVICE) and
+        // the current process state change is also above cutpoint, so no callback will be invoked.
+        verifyNoMoreInteractions(observer);
+
+        changeItem.processState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+        mAms.mPendingUidChanges.add(changeItem);
+        mAms.dispatchUidsChanged();
+        // Previous process state change is above cutpoint (PROCESS_STATE_SERVICE) and
+        // the current process state change is below cutpoint, so callback will be invoked with the
+        // current process state change.
+        verify(observer).onUidStateChanged(TEST_UID,
+                changeItem.processState, changeItem.procStateSeq);
+        verifyNoMoreInteractions(observer);
+    }
+
+    /**
+     * This test verifies that {@link ActivityManagerService#mValidateUids} which is a
+     * part of dumpsys is correctly updated.
+     */
+    @Test
+    public void testDispatchUidChanges_validateUidsUpdated() {
+        final int[] changesForPendingItems = UID_RECORD_CHANGES;
+
+        final int[] procStatesForPendingItems = {
+            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
+            ActivityManager.PROCESS_STATE_CACHED_EMPTY,
+            ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
+            ActivityManager.PROCESS_STATE_SERVICE,
+            ActivityManager.PROCESS_STATE_RECEIVER
+        };
+        final ArrayList<UidRecord.ChangeItem> pendingItemsForUids
+                = new ArrayList<>(changesForPendingItems.length);
+        for (int i = 0; i < changesForPendingItems.length; ++i) {
+            final UidRecord.ChangeItem item = new UidRecord.ChangeItem();
+            item.uid = i;
+            item.change = changesForPendingItems[i];
+            item.processState = procStatesForPendingItems[i];
+            pendingItemsForUids.add(i, item);
+        }
+
+        // Verify that when there no observers listening to uid state changes, then there will
+        // be no changes to validateUids.
+        mAms.mPendingUidChanges.addAll(pendingItemsForUids);
+        mAms.dispatchUidsChanged();
+        assertEquals("No observers registered, so validateUids should be empty",
+                0, mAms.mValidateUids.size());
+
+        final IUidObserver observer = Mockito.mock(IUidObserver.Stub.class);
+        when(observer.asBinder()).thenReturn((IBinder) observer);
+        mAms.registerUidObserver(observer, 0, 0, null);
+        // Verify that when observers are registered, then validateUids is correctly updated.
+        mAms.mPendingUidChanges.addAll(pendingItemsForUids);
+        mAms.dispatchUidsChanged();
+        for (int i = 0; i < pendingItemsForUids.size(); ++i) {
+            final UidRecord.ChangeItem item = pendingItemsForUids.get(i);
+            final UidRecord validateUidRecord = mAms.mValidateUids.get(item.uid);
+            if ((item.change & UidRecord.CHANGE_GONE) != 0) {
+                assertNull("validateUidRecord should be null since the change is either "
+                        + "CHANGE_GONE or CHANGE_GONE_IDLE", validateUidRecord);
+            } else {
+                assertNotNull("validateUidRecord should not be null since the change is neither "
+                        + "CHANGE_GONE nor CHANGE_GONE_IDLE", validateUidRecord);
+                assertEquals("processState: " + item.processState + " curProcState: "
+                        + validateUidRecord.curProcState + " should have been equal",
+                        item.processState, validateUidRecord.curProcState);
+                assertEquals("processState: " + item.processState + " setProcState: "
+                        + validateUidRecord.curProcState + " should have been equal",
+                        item.processState, validateUidRecord.setProcState);
+                if (item.change == UidRecord.CHANGE_IDLE) {
+                    assertTrue("UidRecord.idle should be updated to true for CHANGE_IDLE",
+                            validateUidRecord.idle);
+                } else if (item.change == UidRecord.CHANGE_ACTIVE) {
+                    assertFalse("UidRecord.idle should be updated to false for CHANGE_ACTIVE",
+                            validateUidRecord.idle);
+                }
+            }
+        }
+
+        // Verify that when uid state changes to CHANGE_GONE or CHANGE_GONE_IDLE, then it
+        // will be removed from validateUids.
+        assertNotEquals("validateUids should not be empty", 0, mAms.mValidateUids.size());
+        for (int i = 0; i < pendingItemsForUids.size(); ++i) {
+            final UidRecord.ChangeItem item = pendingItemsForUids.get(i);
+            // Assign CHANGE_GONE_IDLE to some items and CHANGE_GONE to the others, using even/odd
+            // distribution for this assignment.
+            item.change = (i % 2) == 0 ? (UidRecord.CHANGE_GONE | UidRecord.CHANGE_IDLE)
+                    : UidRecord.CHANGE_GONE;
+        }
+        mAms.mPendingUidChanges.addAll(pendingItemsForUids);
+        mAms.dispatchUidsChanged();
+        assertEquals("validateUids should be empty, validateUids: " + mAms.mValidateUids,
+                0, mAms.mValidateUids.size());
+    }
+
+    @Test
+    public void testEnqueueUidChangeLocked_procStateSeqUpdated() {
+        final UidRecord uidRecord = new UidRecord(TEST_UID);
+        uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ1;
+
+        // Verify with no pending changes for TEST_UID.
+        verifyLastProcStateSeqUpdated(uidRecord, -1, TEST_PROC_STATE_SEQ1);
+
+        // Add a pending change for TEST_UID and verify enqueueUidChangeLocked still works as
+        // expected.
+        final UidRecord.ChangeItem changeItem = new UidRecord.ChangeItem();
+        uidRecord.pendingChange = changeItem;
+        uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ2;
+        verifyLastProcStateSeqUpdated(uidRecord, -1, TEST_PROC_STATE_SEQ2);
+    }
+
+    @Test
+    public void testEnqueueUidChangeLocked_nullUidRecord() {
+        // Use "null" uidRecord to make sure there is no crash.
+        mAms.enqueueUidChangeLocked(null, TEST_UID, UidRecord.CHANGE_ACTIVE);
+    }
+
+    private void verifyLastProcStateSeqUpdated(UidRecord uidRecord, int uid, long curProcstateSeq) {
+        // Test enqueueUidChangeLocked with every UidRecord.CHANGE_*
+        for (int i = 0; i < UID_RECORD_CHANGES.length; ++i) {
+            final int changeToDispatch = UID_RECORD_CHANGES[i];
+            // Reset lastProcStateSeqDispatchToObservers after every test.
+            uidRecord.lastDispatchedProcStateSeq = 0;
+            mAms.enqueueUidChangeLocked(uidRecord, uid, changeToDispatch);
+            // Verify there is no effect on curProcStateSeq.
+            assertEquals(curProcstateSeq, uidRecord.curProcStateSeq);
+            if ((changeToDispatch & UidRecord.CHANGE_GONE) != 0) {
+                // Since the change is CHANGE_GONE or CHANGE_GONE_IDLE, verify that
+                // lastProcStateSeqDispatchedToObservers is not updated.
+                assertNotEquals(uidRecord.curProcStateSeq,
+                        uidRecord.lastDispatchedProcStateSeq);
+            } else {
+                // Since the change is neither CHANGE_GONE nor CHANGE_GONE_IDLE, verify that
+                // lastProcStateSeqDispatchedToObservers has been updated to curProcStateSeq.
+                assertEquals(uidRecord.curProcStateSeq,
+                        uidRecord.lastDispatchedProcStateSeq);
+            }
+        }
+    }
+
+    @MediumTest
+    @Test
+    public void testEnqueueUidChangeLocked_dispatchUidsChanged() {
+        final UidRecord uidRecord = new UidRecord(TEST_UID);
+        final int expectedProcState = PROCESS_STATE_SERVICE;
+        uidRecord.setProcState = expectedProcState;
+        uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ1;
+
+        // Test with no pending uid records.
+        for (int i = 0; i < UID_RECORD_CHANGES.length; ++i) {
+            final int changeToDispatch = UID_RECORD_CHANGES[i];
+
+            // Reset the current state
+            mHandler.reset();
+            uidRecord.pendingChange = null;
+            mAms.mPendingUidChanges.clear();
+
+            mAms.enqueueUidChangeLocked(uidRecord, -1, changeToDispatch);
+
+            // Verify that UidRecord.pendingChange is updated correctly.
+            assertNotNull(uidRecord.pendingChange);
+            assertEquals(TEST_UID, uidRecord.pendingChange.uid);
+            assertEquals(expectedProcState, uidRecord.pendingChange.processState);
+            assertEquals(TEST_PROC_STATE_SEQ1, uidRecord.pendingChange.procStateSeq);
+
+            // Verify that DISPATCH_UIDS_CHANGED_UI_MSG is posted to handler.
+            mHandler.waitForMessage(DISPATCH_UIDS_CHANGED_UI_MSG);
+        }
+    }
+
+    @MediumTest
+    @Test
+    public void testWaitForNetworkStateUpdate() throws Exception {
+        // Check there is no crash when there is no UidRecord for myUid
+        mAms.waitForNetworkStateUpdate(TEST_PROC_STATE_SEQ1);
+
+        // Verify there is no waiting when UidRecord.curProcStateSeq is greater than
+        // the procStateSeq in the request to wait.
+        verifyWaitingForNetworkStateUpdate(
+                TEST_PROC_STATE_SEQ1, // curProcStateSeq
+                TEST_PROC_STATE_SEQ1, // lastDsipatchedProcStateSeq
+                TEST_PROC_STATE_SEQ1 - 4, // lastNetworkUpdatedProcStateSeq
+                TEST_PROC_STATE_SEQ1 - 2, // procStateSeqToWait
+                false); // expectWait
+
+        // Verify there is no waiting when the procStateSeq in the request to wait is
+        // not dispatched to NPMS.
+        verifyWaitingForNetworkStateUpdate(
+                TEST_PROC_STATE_SEQ1, // curProcStateSeq
+                TEST_PROC_STATE_SEQ1 - 1, // lastDsipatchedProcStateSeq
+                TEST_PROC_STATE_SEQ1 - 1, // lastNetworkUpdatedProcStateSeq
+                TEST_PROC_STATE_SEQ1, // procStateSeqToWait
+                false); // expectWait
+
+        // Verify there is not waiting when the procStateSeq in the request already has
+        // an updated network state.
+        verifyWaitingForNetworkStateUpdate(
+                TEST_PROC_STATE_SEQ1, // curProcStateSeq
+                TEST_PROC_STATE_SEQ1, // lastDsipatchedProcStateSeq
+                TEST_PROC_STATE_SEQ1, // lastNetworkUpdatedProcStateSeq
+                TEST_PROC_STATE_SEQ1, // procStateSeqToWait
+                false); // expectWait
+
+        // Verify waiting for network works
+        verifyWaitingForNetworkStateUpdate(
+                TEST_PROC_STATE_SEQ1, // curProcStateSeq
+                TEST_PROC_STATE_SEQ1, // lastDsipatchedProcStateSeq
+                TEST_PROC_STATE_SEQ1 - 1, // lastNetworkUpdatedProcStateSeq
+                TEST_PROC_STATE_SEQ1, // procStateSeqToWait
+                true); // expectWait
+    }
+
+    private void verifyWaitingForNetworkStateUpdate(long curProcStateSeq,
+            long lastDispatchedProcStateSeq, long lastNetworkUpdatedProcStateSeq,
+            final long procStateSeqToWait, boolean expectWait) throws Exception {
+        final UidRecord record = new UidRecord(Process.myUid());
+        record.curProcStateSeq = curProcStateSeq;
+        record.lastDispatchedProcStateSeq = lastDispatchedProcStateSeq;
+        record.lastNetworkUpdatedProcStateSeq = lastNetworkUpdatedProcStateSeq;
+        mAms.mActiveUids.put(Process.myUid(), record);
+
+        CustomThread thread = new CustomThread(record.networkStateLock, new Runnable() {
+            @Override
+            public void run() {
+                mAms.waitForNetworkStateUpdate(procStateSeqToWait);
+            }
+        });
+        final String errMsg = "Unexpected state for " + record;
+        if (expectWait) {
+            thread.startAndWait(errMsg, true);
+            thread.assertTimedWaiting(errMsg);
+            synchronized (record.networkStateLock) {
+                record.networkStateLock.notifyAll();
+            }
+            thread.assertTerminated(errMsg);
+            assertTrue(thread.mNotified);
+            assertFalse(record.waitingForNetwork);
+        } else {
+            thread.start();
+            thread.assertTerminated(errMsg);
+        }
+
+        mAms.mActiveUids.clear();
+    }
+
+    private class TestHandler extends Handler {
+        private static final long WAIT_FOR_MSG_TIMEOUT_MS = 4000; // 4 sec
+        private static final long WAIT_FOR_MSG_INTERVAL_MS = 400; // 0.4 sec
+
+        private Set<Integer> mMsgsHandled = new HashSet<>();
+
+        TestHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            mMsgsHandled.add(msg.what);
+        }
+
+        public void waitForMessage(int msg) {
+            final long endTime = System.currentTimeMillis() + WAIT_FOR_MSG_TIMEOUT_MS;
+            while (!mMsgsHandled.contains(msg) && System.currentTimeMillis() < endTime) {
+                SystemClock.sleep(WAIT_FOR_MSG_INTERVAL_MS);
+            }
+            if (!mMsgsHandled.contains(msg)) {
+                fail("Timed out waiting for the message to be handled, msg: " + msg);
+            }
+        }
+
+        public void reset() {
+            mMsgsHandled.clear();
+        }
+    }
+
+    private class TestInjector extends Injector {
+        private boolean mRestricted = true;
+
+        @Override
+        public Context getContext() {
+            return mContext;
+        }
+
+        @Override
+        public AppOpsService getAppOpsService(File file, Handler handler) {
+            return mAppOpsService;
+        }
+
+        @Override
+        public Handler getUiHandler(ActivityManagerService service) {
+            return mHandler;
+        }
+
+        @Override
+        public boolean isNetworkRestrictedForUid(int uid) {
+            return mRestricted;
+        }
+
+        public void setNetworkRestrictedForUid(boolean restricted) {
+            mRestricted = restricted;
+        }
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
new file mode 100644
index 0000000..ba25b16
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.app.ActivityManager;
+import android.app.IActivityManager;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.os.RemoteException;
+import android.test.AndroidTestCase;
+
+import java.util.List;
+
+public class ActivityManagerTest extends AndroidTestCase {
+
+    IActivityManager service;
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        service = ActivityManager.getService();
+    }
+
+    public void testTaskIdsForRunningUsers() throws RemoteException {
+        for(int userId : service.getRunningUserIds()) {
+            testTaskIdsForUser(userId);
+        }
+    }
+
+    private void testTaskIdsForUser(int userId) throws RemoteException {
+        List<ActivityManager.RecentTaskInfo> recentTasks = service.getRecentTasks(
+                100, 0, userId).getList();
+        if(recentTasks != null) {
+            for(ActivityManager.RecentTaskInfo recentTask : recentTasks) {
+                int taskId = recentTask.persistentId;
+                assertEquals("The task id " + taskId + " should not belong to user " + userId,
+                        taskId / UserHandle.PER_USER_RANGE, userId);
+            }
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
new file mode 100644
index 0000000..5ee1c40
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
+import static com.android.server.am.ActivityStack.ActivityState.FINISHING;
+import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
+import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
+import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
+import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
+import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
+import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM;
+import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_LEFT;
+import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_RIGHT;
+
+import static junit.framework.TestCase.assertNotNull;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityOptions;
+import android.app.servertransaction.ClientTransaction;
+import android.app.servertransaction.PauseActivityItem;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.MutableBoolean;
+
+import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.mockito.invocation.InvocationOnMock;
+
+/**
+ * Tests for the {@link ActivityRecord} class.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:com.android.server.am.ActivityRecordTests
+ */
+@MediumTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class ActivityRecordTests extends ActivityTestsBase {
+    private ActivityManagerService mService;
+    private TestActivityStack mStack;
+    private TaskRecord mTask;
+    private ActivityRecord mActivity;
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mService = createActivityManagerService();
+        mStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        mTask = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
+        mActivity = new ActivityBuilder(mService).setTask(mTask).build();
+    }
+
+    @Test
+    public void testStackCleanupOnClearingTask() throws Exception {
+        mActivity.setTask(null);
+        assertEquals(mStack.onActivityRemovedFromStackInvocationCount(), 1);
+    }
+
+    @Test
+    public void testStackCleanupOnActivityRemoval() throws Exception {
+        mTask.removeActivity(mActivity);
+        assertEquals(mStack.onActivityRemovedFromStackInvocationCount(),  1);
+    }
+
+    @Test
+    public void testStackCleanupOnTaskRemoval() throws Exception {
+        mStack.removeTask(mTask, null /*reason*/, REMOVE_TASK_MODE_MOVING);
+        // Stack should be gone on task removal.
+        assertNull(mService.mStackSupervisor.getStack(mStack.mStackId));
+    }
+
+    @Test
+    public void testNoCleanupMovingActivityInSameStack() throws Exception {
+        final TaskRecord newTask = new TaskBuilder(mService.mStackSupervisor).setStack(mStack)
+                .build();
+        mActivity.reparent(newTask, 0, null /*reason*/);
+        assertEquals(mStack.onActivityRemovedFromStackInvocationCount(), 0);
+    }
+
+    @Test
+    public void testPausingWhenVisibleFromStopped() throws Exception {
+        final MutableBoolean pauseFound = new MutableBoolean(false);
+        doAnswer((InvocationOnMock invocationOnMock) -> {
+            final ClientTransaction transaction = invocationOnMock.getArgument(0);
+            if (transaction.getLifecycleStateRequest() instanceof PauseActivityItem) {
+                pauseFound.value = true;
+            }
+            return null;
+        }).when(mActivity.app.thread).scheduleTransaction(any());
+
+        mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped");
+
+        // The activity is in the focused stack so it should not move to paused.
+        mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);
+        assertTrue(mActivity.isState(STOPPED));
+        assertFalse(pauseFound.value);
+
+        // Clear focused stack
+        mActivity.mStackSupervisor.mFocusedStack = null;
+
+        // In the unfocused stack, the activity should move to paused.
+        mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);
+        assertTrue(mActivity.isState(PAUSING));
+        assertTrue(pauseFound.value);
+
+        // Make sure that the state does not change for current non-stopping states.
+        mActivity.setState(INITIALIZING, "testPausingWhenVisibleFromStopped");
+
+        mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);
+
+        assertTrue(mActivity.isState(INITIALIZING));
+
+        // Make sure the state does not change if we are not the current top activity.
+        mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped behind");
+
+        // Make sure that the state does not change when we have an activity becoming translucent
+        final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+        mStack.mTranslucentActivityWaiting = topActivity;
+        mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);
+
+        assertTrue(mActivity.isState(STOPPED));
+    }
+
+    @Test
+    public void testPositionLimitedAspectRatioNavBarBottom() throws Exception {
+        verifyPositionWithLimitedAspectRatio(NAV_BAR_BOTTOM, new Rect(0, 0, 1000, 2000), 1.5f,
+                new Rect(0, 0, 1000, 1500));
+    }
+
+    @Test
+    public void testPositionLimitedAspectRatioNavBarLeft() throws Exception {
+        verifyPositionWithLimitedAspectRatio(NAV_BAR_LEFT, new Rect(0, 0, 2000, 1000), 1.5f,
+                new Rect(500, 0, 2000, 1000));
+    }
+
+    @Test
+    public void testPositionLimitedAspectRatioNavBarRight() throws Exception {
+        verifyPositionWithLimitedAspectRatio(NAV_BAR_RIGHT, new Rect(0, 0, 2000, 1000), 1.5f,
+                new Rect(0, 0, 1500, 1000));
+    }
+
+    private void verifyPositionWithLimitedAspectRatio(int navBarPosition, Rect taskBounds,
+            float aspectRatio, Rect expectedActivityBounds) {
+        // Verify with nav bar on the right.
+        when(mService.mWindowManager.getNavBarPosition()).thenReturn(navBarPosition);
+        mTask.getConfiguration().windowConfiguration.setAppBounds(taskBounds);
+        mActivity.info.maxAspectRatio = aspectRatio;
+        mActivity.ensureActivityConfiguration(
+                0 /* globalChanges */, false /* preserveWindow */);
+        assertEquals(expectedActivityBounds, mActivity.getBounds());
+    }
+
+    @Test
+    public void testCanBeLaunchedOnDisplay() throws Exception {
+        testSupportsLaunchingResizeable(false /*taskPresent*/, true /*taskResizeable*/,
+                true /*activityResizeable*/, true /*expected*/);
+
+        testSupportsLaunchingResizeable(false /*taskPresent*/, true /*taskResizeable*/,
+                false /*activityResizeable*/, false /*expected*/);
+
+        testSupportsLaunchingResizeable(true /*taskPresent*/, false /*taskResizeable*/,
+                true /*activityResizeable*/, false /*expected*/);
+
+        testSupportsLaunchingResizeable(true /*taskPresent*/, true /*taskResizeable*/,
+                false /*activityResizeable*/, true /*expected*/);
+    }
+
+    @Test
+    public void testsApplyOptionsLocked() {
+        ActivityOptions activityOptions = ActivityOptions.makeBasic();
+
+        // Set and apply options for ActivityRecord. Pending options should be cleared
+        mActivity.updateOptionsLocked(activityOptions);
+        mActivity.applyOptionsLocked();
+        assertNull(mActivity.pendingOptions);
+
+        // Set options for two ActivityRecords in same Task. Apply one ActivityRecord options.
+        // Pending options should be cleared for both ActivityRecords
+        ActivityRecord activity2 = new ActivityBuilder(mService).setTask(mTask).build();
+        activity2.updateOptionsLocked(activityOptions);
+        mActivity.updateOptionsLocked(activityOptions);
+        mActivity.applyOptionsLocked();
+        assertNull(mActivity.pendingOptions);
+        assertNull(activity2.pendingOptions);
+
+        // Set options for two ActivityRecords in separate Tasks. Apply one ActivityRecord options.
+        // Pending options should be cleared for only ActivityRecord that was applied
+        TaskRecord task2 = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
+        activity2 = new ActivityBuilder(mService).setTask(task2).build();
+        activity2.updateOptionsLocked(activityOptions);
+        mActivity.updateOptionsLocked(activityOptions);
+        mActivity.applyOptionsLocked();
+        assertNull(mActivity.pendingOptions);
+        assertNotNull(activity2.pendingOptions);
+    }
+
+    private void testSupportsLaunchingResizeable(boolean taskPresent, boolean taskResizeable,
+            boolean activityResizeable, boolean expected) {
+        mService.mSupportsMultiWindow = true;
+
+        final TaskRecord task = taskPresent
+                ? new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build() : null;
+
+        if (task != null) {
+            task.setResizeMode(taskResizeable ? RESIZE_MODE_RESIZEABLE : RESIZE_MODE_UNRESIZEABLE);
+        }
+
+        final ActivityRecord record = new ActivityBuilder(mService).setTask(task).build();
+        record.info.resizeMode = activityResizeable
+                ? RESIZE_MODE_RESIZEABLE : RESIZE_MODE_UNRESIZEABLE;
+
+        record.canBeLaunchedOnDisplay(DEFAULT_DISPLAY);
+
+
+        verify(mService.mStackSupervisor, times(1)).canPlaceEntityOnDisplay(anyInt(), eq(expected),
+                anyInt(), anyInt(), eq(record.info));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
new file mode 100644
index 0000000..1ce41a6
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
@@ -0,0 +1,410 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
+import static android.app.ActivityManager.START_TASK_TO_FRONT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
+import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
+
+import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
+import static com.android.server.am.ActivityStackSupervisor
+        .MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.app.ActivityOptions;
+import android.app.WaitResult;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.SparseIntArray;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.invocation.InvocationOnMock;
+
+import java.util.ArrayList;
+
+/**
+ * Tests for the {@link ActivityStackSupervisor} class.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:com.android.server.am.ActivityStackSupervisorTests
+ */
+@MediumTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class ActivityStackSupervisorTests extends ActivityTestsBase {
+    private ActivityManagerService mService;
+    private ActivityStackSupervisor mSupervisor;
+    private ActivityStack mFullscreenStack;
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mService = createActivityManagerService();
+        mSupervisor = mService.mStackSupervisor;
+        mFullscreenStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+    }
+
+    /**
+     * This test ensures that we do not try to restore a task based off an invalid task id. The
+     * stack supervisor is a test version so there will be no tasks present. We should expect
+     * {@code null} to be returned in this case.
+     */
+    @Test
+    public void testRestoringInvalidTask() throws Exception {
+        TaskRecord task = mSupervisor.anyTaskForIdLocked(0 /*taskId*/,
+                MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, null, false /* onTop */);
+        assertNull(task);
+    }
+
+    /**
+     * This test ensures that an existing task in the pinned stack is moved to the fullscreen
+     * activity stack when a new task is added.
+     */
+    @Test
+    public void testReplacingTaskInPinnedStack() throws Exception {
+        final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
+                .setStack(mFullscreenStack).build();
+        final TaskRecord firstTask = firstActivity.getTask();
+
+        final ActivityRecord secondActivity = new ActivityBuilder(mService).setCreateTask(true)
+                .setStack(mFullscreenStack).build();
+        final TaskRecord secondTask = secondActivity.getTask();
+
+        mSupervisor.setFocusStackUnchecked("testReplacingTaskInPinnedStack", mFullscreenStack);
+
+        // Ensure full screen stack has both tasks.
+        ensureStackPlacement(mFullscreenStack, firstTask, secondTask);
+
+        // Move first activity to pinned stack.
+        final Rect sourceBounds = new Rect();
+        mSupervisor.moveActivityToPinnedStackLocked(firstActivity, sourceBounds,
+                0f /*aspectRatio*/, "initialMove");
+
+        final ActivityDisplay display = mFullscreenStack.getDisplay();
+        ActivityStack pinnedStack = display.getPinnedStack();
+        // Ensure a task has moved over.
+        ensureStackPlacement(pinnedStack, firstTask);
+        ensureStackPlacement(mFullscreenStack, secondTask);
+
+        // Move second activity to pinned stack.
+        mSupervisor.moveActivityToPinnedStackLocked(secondActivity, sourceBounds,
+                0f /*aspectRatio*/, "secondMove");
+
+        // Need to get stacks again as a new instance might have been created.
+        pinnedStack = display.getPinnedStack();
+        mFullscreenStack = display.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        // Ensure stacks have swapped tasks.
+        ensureStackPlacement(pinnedStack, secondTask);
+        ensureStackPlacement(mFullscreenStack, firstTask);
+    }
+
+    private static void ensureStackPlacement(ActivityStack stack, TaskRecord... tasks) {
+        final ArrayList<TaskRecord> stackTasks = stack.getAllTasks();
+        assertEquals(stackTasks.size(), tasks != null ? tasks.length : 0);
+
+        if (tasks == null) {
+            return;
+        }
+
+        for (TaskRecord task : tasks) {
+            assertTrue(stackTasks.contains(task));
+        }
+    }
+
+    /**
+     * Ensures that an activity is removed from the stopping activities list once it is resumed.
+     */
+    @Test
+    public void testStoppingActivityRemovedWhenResumed() throws Exception {
+        final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
+                .setStack(mFullscreenStack).build();
+        mSupervisor.mStoppingActivities.add(firstActivity);
+
+        firstActivity.completeResumeLocked();
+
+        assertFalse(mSupervisor.mStoppingActivities.contains(firstActivity));
+    }
+
+    /**
+     * Ensures that waiting results are notified of launches.
+     */
+    @Test
+    public void testReportWaitingActivityLaunchedIfNeeded() throws Exception {
+        final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
+                .setStack(mFullscreenStack).build();
+
+        // #notifyAll will be called on the ActivityManagerService. we must hold the object lock
+        // when this happens.
+        synchronized (mSupervisor.mService) {
+            final WaitResult taskToFrontWait = new WaitResult();
+            mSupervisor.mWaitingActivityLaunched.add(taskToFrontWait);
+            mSupervisor.reportWaitingActivityLaunchedIfNeeded(firstActivity, START_TASK_TO_FRONT);
+
+            assertTrue(mSupervisor.mWaitingActivityLaunched.isEmpty());
+            assertEquals(taskToFrontWait.result, START_TASK_TO_FRONT);
+            assertEquals(taskToFrontWait.who, null);
+
+            final WaitResult deliverToTopWait = new WaitResult();
+            mSupervisor.mWaitingActivityLaunched.add(deliverToTopWait);
+            mSupervisor.reportWaitingActivityLaunchedIfNeeded(firstActivity,
+                    START_DELIVERED_TO_TOP);
+
+            assertTrue(mSupervisor.mWaitingActivityLaunched.isEmpty());
+            assertEquals(deliverToTopWait.result, START_DELIVERED_TO_TOP);
+            assertEquals(deliverToTopWait.who, firstActivity.realActivity);
+        }
+    }
+
+    @Test
+    public void testApplySleepTokensLocked() throws Exception {
+        final ActivityDisplay display = mSupervisor.getDefaultDisplay();
+        final KeyguardController keyguard = mSupervisor.getKeyguardController();
+        final ActivityStack stack = mock(ActivityStack.class);
+        display.addChild(stack, 0 /* position */);
+
+        // Make sure we wake and resume in the case the display is turning on and the keyguard is
+        // not showing.
+        verifySleepTokenBehavior(display, keyguard, stack, true /*displaySleeping*/,
+                false /* displayShouldSleep */, true /* isFocusedStack */,
+                false /* keyguardShowing */, true /* expectWakeFromSleep */,
+                true /* expectResumeTopActivity */);
+
+        // Make sure we wake and don't resume when the display is turning on and the keyguard is
+        // showing.
+        verifySleepTokenBehavior(display, keyguard, stack, true /*displaySleeping*/,
+                false /* displayShouldSleep */, true /* isFocusedStack */,
+                true /* keyguardShowing */, true /* expectWakeFromSleep */,
+                false /* expectResumeTopActivity */);
+
+        // Make sure we wake and don't resume when the display is turning on and the keyguard is
+        // not showing as unfocused.
+        verifySleepTokenBehavior(display, keyguard, stack, true /*displaySleeping*/,
+                false /* displayShouldSleep */, false /* isFocusedStack */,
+                false /* keyguardShowing */, true /* expectWakeFromSleep */,
+                false /* expectResumeTopActivity */);
+
+        // Should not do anything if the display state hasn't changed.
+        verifySleepTokenBehavior(display, keyguard, stack, false /*displaySleeping*/,
+                false /* displayShouldSleep */, true /* isFocusedStack */,
+                false /* keyguardShowing */, false /* expectWakeFromSleep */,
+                false /* expectResumeTopActivity */);
+    }
+
+    private void verifySleepTokenBehavior(ActivityDisplay display, KeyguardController keyguard,
+            ActivityStack stack, boolean displaySleeping, boolean displayShouldSleep,
+            boolean isFocusedStack, boolean keyguardShowing, boolean expectWakeFromSleep,
+            boolean expectResumeTopActivity) {
+        reset(stack);
+
+        doReturn(displayShouldSleep).when(display).shouldSleep();
+        doReturn(displaySleeping).when(display).isSleeping();
+        doReturn(keyguardShowing).when(keyguard).isKeyguardOrAodShowing(anyInt());
+
+        mSupervisor.mFocusedStack = isFocusedStack ? stack : null;
+        mSupervisor.applySleepTokensLocked(true);
+        verify(stack, times(expectWakeFromSleep ? 1 : 0)).awakeFromSleepingLocked();
+        verify(stack, times(expectResumeTopActivity ? 1 : 0)).resumeTopActivityUncheckedLocked(
+                null /* target */, null /* targetOptions */);
+    }
+
+    @Test
+    public void testTopRunningActivityLockedWithNonExistentDisplay() throws Exception {
+        // Create display that ActivityManagerService does not know about
+        final int unknownDisplayId = 100;
+
+        doAnswer((InvocationOnMock invocationOnMock) -> {
+            final SparseIntArray displayIds = invocationOnMock.<SparseIntArray>getArgument(0);
+            displayIds.put(0, unknownDisplayId);
+            return null;
+        }).when(mSupervisor.mWindowManager).getDisplaysInFocusOrder(any());
+
+        mSupervisor.mFocusedStack = mock(ActivityStack.class);
+
+        // Supervisor should skip over the non-existent display.
+        assertEquals(null, mSupervisor.topRunningActivityLocked());
+    }
+
+    /**
+     * Verifies that removal of activity with task and stack is done correctly.
+     */
+    @Test
+    public void testRemovingStackOnAppCrash() throws Exception {
+        final ActivityDisplay defaultDisplay = mService.mStackSupervisor.getDefaultDisplay();
+        final int originalStackCount = defaultDisplay.getChildCount();
+        final ActivityStack stack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+        final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
+                .setStack(stack).build();
+
+        assertEquals(originalStackCount + 1, defaultDisplay.getChildCount());
+
+        // Let's pretend that the app has crashed.
+        firstActivity.app.thread = null;
+        mService.mStackSupervisor.finishTopCrashedActivitiesLocked(firstActivity.app, "test");
+
+        // Verify that the stack was removed.
+        assertEquals(originalStackCount, defaultDisplay.getChildCount());
+    }
+
+    @Test
+    public void testFocusability() throws Exception {
+        final ActivityStack stack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true)
+                .setStack(stack).build();
+
+        // Under split screen primary we should be focusable when not minimized
+        mService.mStackSupervisor.setDockedStackMinimized(false);
+        assertTrue(stack.isFocusable());
+        assertTrue(activity.isFocusable());
+
+        // Under split screen primary we should not be focusable when minimized
+        mService.mStackSupervisor.setDockedStackMinimized(true);
+        assertFalse(stack.isFocusable());
+        assertFalse(activity.isFocusable());
+
+        final ActivityStack pinnedStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final ActivityRecord pinnedActivity = new ActivityBuilder(mService).setCreateTask(true)
+                .setStack(pinnedStack).build();
+
+        // We should not be focusable when in pinned mode
+        assertFalse(pinnedStack.isFocusable());
+        assertFalse(pinnedActivity.isFocusable());
+
+        // Add flag forcing focusability.
+        pinnedActivity.info.flags |= FLAG_ALWAYS_FOCUSABLE;
+
+        // We should not be focusable when in pinned mode
+        assertTrue(pinnedStack.isFocusable());
+        assertTrue(pinnedActivity.isFocusable());
+
+        // Without the overridding activity, stack should not be focusable.
+        pinnedStack.removeTask(pinnedActivity.getTask(), "testFocusability",
+                REMOVE_TASK_MODE_DESTROYING);
+        assertFalse(pinnedStack.isFocusable());
+    }
+
+    /**
+     * Verifies the correct activity is returned when querying the top running activity.
+     */
+    @Test
+    public void testTopRunningActivity() throws Exception {
+        // Create stack to hold focus
+        final ActivityStack emptyStack = mService.mStackSupervisor.getDefaultDisplay()
+                .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+
+        final KeyguardController keyguard = mSupervisor.getKeyguardController();
+        final ActivityStack stack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true)
+                .setStack(stack).build();
+
+        mSupervisor.mFocusedStack = emptyStack;
+
+        doAnswer((InvocationOnMock invocationOnMock) -> {
+            final SparseIntArray displayIds = invocationOnMock.<SparseIntArray>getArgument(0);
+            displayIds.put(0, mSupervisor.getDefaultDisplay().mDisplayId);
+            return null;
+        }).when(mSupervisor.mWindowManager).getDisplaysInFocusOrder(any());
+
+        // Make sure the top running activity is not affected when keyguard is not locked
+        assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked());
+        assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked(
+                true /* considerKeyguardState */));
+
+        // Check to make sure activity not reported when it cannot show on lock and lock is on.
+        doReturn(true).when(keyguard).isKeyguardLocked();
+        assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked());
+        assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked(
+                true /* considerKeyguardState */));
+
+        // Change focus to stack with activity.
+        mSupervisor.mFocusedStack = stack;
+        assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked());
+        assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked(
+                true /* considerKeyguardState */));
+
+        // Add activity that should be shown on the keyguard.
+        final ActivityRecord showWhenLockedActivity = new ActivityBuilder(mService)
+                .setCreateTask(true)
+                .setStack(stack)
+                .setActivityFlags(FLAG_SHOW_WHEN_LOCKED)
+                .build();
+
+        // Ensure the show when locked activity is returned.
+        assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked());
+        assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked(
+                true /* considerKeyguardState */));
+
+        // Change focus back to empty stack
+        mSupervisor.mFocusedStack = emptyStack;
+        // Ensure the show when locked activity is returned when not the focused stack
+        assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked());
+        assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked(
+                true /* considerKeyguardState */));
+    }
+
+    /**
+     * Verify that split-screen primary stack will be chosen if activity is launched that targets
+     * split-screen secondary, but a matching existing instance is found on top of split-screen
+     * primary stack.
+     */
+    @Test
+    public void testSplitScreenPrimaryChosenWhenTopActivityLaunchedToSecondary() throws Exception {
+        // Create primary split-screen stack with a task and an activity.
+        final ActivityStack primaryStack = mService.mStackSupervisor.getDefaultDisplay()
+                .createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
+                        true /* onTop */);
+        final TaskRecord task = new TaskBuilder(mSupervisor).setStack(primaryStack).build();
+        final ActivityRecord r = new ActivityBuilder(mService).setTask(task).build();
+
+        // Find a launch stack for the top activity in split-screen primary, while requesting
+        // split-screen secondary.
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
+        final ActivityStack result = mSupervisor.getLaunchStack(r, options, task, true /* onTop */);
+
+        // Assert that the primary stack is returned.
+        assertEquals(primaryStack, result);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
new file mode 100644
index 0000000..01425ed
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
@@ -0,0 +1,631 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
+
+import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
+import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
+import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.pm.ActivityInfo;
+import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for the {@link ActivityStack} class.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:com.android.server.am.ActivityStackTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class ActivityStackTests extends ActivityTestsBase {
+    private ActivityManagerService mService;
+    private ActivityStackSupervisor mSupervisor;
+    private ActivityDisplay mDefaultDisplay;
+    private ActivityStack mStack;
+    private TaskRecord mTask;
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mService = createActivityManagerService();
+        mSupervisor = mService.mStackSupervisor;
+        mDefaultDisplay = mService.mStackSupervisor.getDefaultDisplay();
+        mStack = mDefaultDisplay.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
+    }
+
+    @Test
+    public void testEmptyTaskCleanupOnRemove() throws Exception {
+        assertNotNull(mTask.getWindowContainerController());
+        mStack.removeTask(mTask, "testEmptyTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
+        assertNull(mTask.getWindowContainerController());
+    }
+
+    @Test
+    public void testOccupiedTaskCleanupOnRemove() throws Exception {
+        final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
+        assertNotNull(mTask.getWindowContainerController());
+        mStack.removeTask(mTask, "testOccupiedTaskCleanupOnRemove", REMOVE_TASK_MODE_DESTROYING);
+        assertNotNull(mTask.getWindowContainerController());
+    }
+
+    @Test
+    public void testResumedActivity() throws Exception {
+        final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
+        assertEquals(mStack.getResumedActivity(), null);
+        r.setState(RESUMED, "testResumedActivity");
+        assertEquals(mStack.getResumedActivity(), r);
+        r.setState(PAUSING, "testResumedActivity");
+        assertEquals(mStack.getResumedActivity(), null);
+    }
+
+    @Test
+    public void testResumedActivityFromTaskReparenting() {
+        final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
+        // Ensure moving task between two stacks updates resumed activity
+        r.setState(RESUMED, "testResumedActivityFromTaskReparenting");
+        assertEquals(mStack.getResumedActivity(), r);
+
+        final ActivityStack destStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+
+        mTask.reparent(destStack, true /* toTop */, TaskRecord.REPARENT_KEEP_STACK_AT_FRONT,
+                false /* animate */, true /* deferResume*/,
+                "testResumedActivityFromTaskReparenting");
+
+        assertEquals(mStack.getResumedActivity(), null);
+        assertEquals(destStack.getResumedActivity(), r);
+    }
+
+    @Test
+    public void testResumedActivityFromActivityReparenting() {
+        final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
+        // Ensure moving task between two stacks updates resumed activity
+        r.setState(RESUMED, "testResumedActivityFromActivityReparenting");
+        assertEquals(mStack.getResumedActivity(), r);
+
+        final ActivityStack destStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final TaskRecord destTask = new TaskBuilder(mSupervisor).setStack(destStack).build();
+
+        mTask.removeActivity(r);
+        destTask.addActivityToTop(r);
+
+        assertEquals(mStack.getResumedActivity(), null);
+        assertEquals(destStack.getResumedActivity(), r);
+    }
+
+    @Test
+    public void testPrimarySplitScreenToFullscreenWhenMovedToBack() throws Exception {
+        // Create primary splitscreen stack. This will create secondary stacks and places the
+        // existing fullscreen stack on the bottom.
+        final ActivityStack primarySplitScreen = mDefaultDisplay.createStack(
+                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+
+        // Assert windowing mode.
+        assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+
+        // Move primary to back.
+        primarySplitScreen.moveToBack("testPrimarySplitScreenToFullscreenWhenMovedToBack",
+                null /* task */);
+
+        // Assert that stack is at the bottom.
+        assertEquals(mDefaultDisplay.getIndexOf(primarySplitScreen), 0);
+
+        // Ensure no longer in splitscreen.
+        assertEquals(primarySplitScreen.getWindowingMode(), WINDOWING_MODE_FULLSCREEN);
+    }
+
+    @Test
+    public void testStopActivityWhenActivityDestroyed() throws Exception {
+        final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build();
+        r.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
+        mSupervisor.setFocusStackUnchecked("testStopActivityWithDestroy", mStack);
+        mStack.stopActivityLocked(r);
+        // Mostly testing to make sure there is a crash in the call part, so if we get here we are
+        // good-to-go!
+    }
+
+    @Test
+    public void testFindTaskWithOverlay() throws Exception {
+        final ActivityRecord r = new ActivityBuilder(mService)
+                .setCreateTask(true)
+                .setStack(mStack)
+                .setUid(0)
+                .build();
+        final TaskRecord task = r.getTask();
+        // Overlay must be for a different user to prevent recognizing a matching top activity
+        final ActivityRecord taskOverlay = new ActivityBuilder(mService).setTask(task)
+                .setUid(UserHandle.PER_USER_RANGE * 2).build();
+        taskOverlay.mTaskOverlay = true;
+
+        final ActivityStackSupervisor.FindTaskResult result =
+                new ActivityStackSupervisor.FindTaskResult();
+        mStack.findTaskLocked(r, result);
+
+        assertEquals(task.getTopActivity(false /* includeOverlays */), r);
+        assertEquals(task.getTopActivity(true /* includeOverlays */), taskOverlay);
+        assertNotNull(result.r);
+    }
+
+    @Test
+    public void testShouldBeVisible_Fullscreen() throws Exception {
+        final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
+        final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+
+        assertTrue(homeStack.shouldBeVisible(null /* starting */));
+        assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
+
+        final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        // Home stack shouldn't be visible behind an opaque fullscreen stack, but pinned stack
+        // should be visible since it is always on-top.
+        fullscreenStack.setIsTranslucent(false);
+        assertFalse(homeStack.shouldBeVisible(null /* starting */));
+        assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
+        assertTrue(fullscreenStack.shouldBeVisible(null /* starting */));
+
+        // Home stack should be visible behind a translucent fullscreen stack.
+        fullscreenStack.setIsTranslucent(true);
+        assertTrue(homeStack.shouldBeVisible(null /* starting */));
+        assertTrue(pinnedStack.shouldBeVisible(null /* starting */));
+    }
+
+    @Test
+    public void testShouldBeVisible_SplitScreen() throws Exception {
+        final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
+        // Home stack should always be fullscreen for this test.
+        homeStack.setSupportsSplitScreen(false);
+        final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+
+        // Home stack shouldn't be visible if both halves of split-screen are opaque.
+        splitScreenPrimary.setIsTranslucent(false);
+        splitScreenSecondary.setIsTranslucent(false);
+        assertFalse(homeStack.shouldBeVisible(null /* starting */));
+        assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
+        assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
+
+        // Home stack should be visible if one of the halves of split-screen is translucent.
+        splitScreenPrimary.setIsTranslucent(true);
+        assertTrue(homeStack.shouldBeVisible(null /* starting */));
+        assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
+        assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
+
+        final TestActivityStack splitScreenSecondary2 = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        // First split-screen secondary shouldn't be visible behind another opaque split-split
+        // secondary.
+        splitScreenSecondary2.setIsTranslucent(false);
+        assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
+        assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
+
+        // First split-screen secondary should be visible behind another translucent split-screen
+        // secondary.
+        splitScreenSecondary2.setIsTranslucent(true);
+        assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
+        assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
+
+        final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
+
+        // Split-screen stacks shouldn't be visible behind an opaque fullscreen stack.
+        assistantStack.setIsTranslucent(false);
+        assertTrue(assistantStack.shouldBeVisible(null /* starting */));
+        assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
+        assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
+        assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
+
+        // Split-screen stacks should be visible behind a translucent fullscreen stack.
+        assistantStack.setIsTranslucent(true);
+        assertTrue(assistantStack.shouldBeVisible(null /* starting */));
+        assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
+        assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
+        assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
+
+        // Assistant stack shouldn't be visible behind translucent split-screen stack
+        assistantStack.setIsTranslucent(false);
+        splitScreenPrimary.setIsTranslucent(true);
+        splitScreenSecondary2.setIsTranslucent(true);
+        splitScreenSecondary2.moveToFront("testShouldBeVisible_SplitScreen");
+        splitScreenPrimary.moveToFront("testShouldBeVisible_SplitScreen");
+        assertFalse(assistantStack.shouldBeVisible(null /* starting */));
+        assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
+        assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
+    }
+
+    @Test
+    public void testShouldBeVisible_Finishing() throws Exception {
+        final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
+        final TestActivityStack translucentStack = createStackForShouldBeVisibleTest(
+                mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        translucentStack.setIsTranslucent(true);
+
+        assertTrue(homeStack.shouldBeVisible(null /* starting */));
+        assertTrue(translucentStack.shouldBeVisible(null /* starting */));
+
+        final ActivityRecord topRunningHomeActivity = homeStack.topRunningActivityLocked();
+        topRunningHomeActivity.finishing = true;
+        final ActivityRecord topRunningTranslucentActivity =
+                translucentStack.topRunningActivityLocked();
+        topRunningTranslucentActivity.finishing = true;
+
+        // Home shouldn't be visible since its activity is marked as finishing and it isn't the top
+        // of the stack list.
+        assertFalse(homeStack.shouldBeVisible(null /* starting */));
+        // Home should be visible if we are starting an activity within it.
+        assertTrue(homeStack.shouldBeVisible(topRunningHomeActivity /* starting */));
+        // The translucent stack should be visible since it is the top of the stack list even though
+        // it has its activity marked as finishing.
+        assertTrue(translucentStack.shouldBeVisible(null /* starting */));
+    }
+
+    @Test
+    public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindFullscreen() {
+        mDefaultDisplay.removeChild(mStack);
+
+        final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
+        final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+
+        homeStack.setIsTranslucent(false);
+        fullscreenStack.setIsTranslucent(false);
+
+        // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
+        int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
+        assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack);
+        mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
+        assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
+    }
+
+    @Test
+    public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeBehindTranslucent() {
+        mDefaultDisplay.removeChild(mStack);
+
+        final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
+        final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+
+        homeStack.setIsTranslucent(false);
+        fullscreenStack.setIsTranslucent(true);
+
+        // Ensure that we don't move the home stack if it is already behind the top fullscreen stack
+        int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
+        assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack);
+        mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
+        assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
+    }
+
+    @Test
+    public void testMoveHomeStackBehindBottomMostVisibleStack_NoMoveHomeOnTop() {
+        mDefaultDisplay.removeChild(mStack);
+
+        final TestActivityStack fullscreenStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
+
+        homeStack.setIsTranslucent(false);
+        fullscreenStack.setIsTranslucent(false);
+
+        // Ensure we don't move the home stack if it is already on top
+        int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
+        assertTrue(mDefaultDisplay.getStackAbove(homeStack) == null);
+        mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
+        assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
+    }
+
+    @Test
+    public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreen() {
+        mDefaultDisplay.removeChild(mStack);
+
+        final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
+        final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
+                mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
+                mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        final TestActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+
+        homeStack.setIsTranslucent(false);
+        fullscreenStack1.setIsTranslucent(false);
+        fullscreenStack2.setIsTranslucent(false);
+
+        // Ensure that we move the home stack behind the bottom most fullscreen stack, ignoring the
+        // pinned stack
+        assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
+        mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
+        assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
+    }
+
+    @Test
+    public void testMoveHomeStackBehindBottomMostVisibleStack_MoveHomeBehindFullscreenAndTranslucent() {
+        mDefaultDisplay.removeChild(mStack);
+
+        final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
+        final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
+                mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
+                mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+
+        homeStack.setIsTranslucent(false);
+        fullscreenStack1.setIsTranslucent(false);
+        fullscreenStack2.setIsTranslucent(true);
+
+        // Ensure that we move the home stack behind the bottom most non-translucent fullscreen
+        // stack
+        assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
+        mDefaultDisplay.moveStackBehindBottomMostVisibleStack(homeStack);
+        assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
+    }
+
+    @Test
+    public void testMoveHomeStackBehindStack_BehindHomeStack() {
+        mDefaultDisplay.removeChild(mStack);
+
+        final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
+                mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
+                mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
+
+        homeStack.setIsTranslucent(false);
+        fullscreenStack1.setIsTranslucent(false);
+        fullscreenStack2.setIsTranslucent(false);
+
+        // Ensure we don't move the home stack behind itself
+        int homeStackIndex = mDefaultDisplay.getIndexOf(homeStack);
+        mDefaultDisplay.moveStackBehindStack(homeStack, homeStack);
+        assertTrue(mDefaultDisplay.getIndexOf(homeStack) == homeStackIndex);
+    }
+
+    @Test
+    public void testMoveHomeStackBehindStack() {
+        mDefaultDisplay.removeChild(mStack);
+
+        final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
+                mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
+                mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        final TestActivityStack fullscreenStack3 = createStackForShouldBeVisibleTest(
+                mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        final TestActivityStack fullscreenStack4 = createStackForShouldBeVisibleTest(
+                mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        final TestActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
+
+        mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack1);
+        assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack1);
+        mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2);
+        assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
+        mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack4);
+        assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack4);
+        mDefaultDisplay.moveStackBehindStack(homeStack, fullscreenStack2);
+        assertTrue(mDefaultDisplay.getStackAbove(homeStack) == fullscreenStack2);
+    }
+
+    @Test
+    public void testSplitScreenMoveToFront() throws Exception {
+        final TestActivityStack splitScreenPrimary = createStackForShouldBeVisibleTest(
+                mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        final TestActivityStack splitScreenSecondary = createStackForShouldBeVisibleTest(
+                mDefaultDisplay, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */);
+        final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
+
+        splitScreenPrimary.setIsTranslucent(false);
+        splitScreenSecondary.setIsTranslucent(false);
+        assistantStack.setIsTranslucent(false);
+
+        assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
+        assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
+        assertTrue(assistantStack.shouldBeVisible(null /* starting */));
+
+        splitScreenSecondary.moveToFront("testSplitScreenMoveToFront");
+
+        assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
+        assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
+        assertFalse(assistantStack.shouldBeVisible(null /* starting */));
+    }
+
+    private <T extends ActivityStack> T createStackForShouldBeVisibleTest(
+            ActivityDisplay display, int windowingMode, int activityType, boolean onTop) {
+        final T stack = display.createStack(windowingMode, activityType, onTop);
+        final ActivityRecord r = new ActivityBuilder(mService).setUid(0).setStack(stack)
+                .setCreateTask(true).build();
+        return stack;
+    }
+
+    @Test
+    public void testFinishDisabledPackageActivities() throws Exception {
+        final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
+        final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
+
+        // Making the second activity a task overlay without an app means it will be removed from
+        // the task's activities as well once first activity is removed.
+        secondActivity.mTaskOverlay = true;
+        secondActivity.app = null;
+
+        assertEquals(mTask.mActivities.size(), 2);
+
+        mStack.finishDisabledPackageActivitiesLocked(firstActivity.packageName, null,
+                true /* doit */, true /* evenPersistent */, UserHandle.USER_ALL);
+
+        assertTrue(mTask.mActivities.isEmpty());
+        assertTrue(mStack.getAllTasks().isEmpty());
+    }
+
+    @Test
+    public void testHandleAppDied() throws Exception {
+        final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
+        final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build();
+
+        // Making the first activity a task overlay means it will be removed from the task's
+        // activities as well once second activity is removed as handleAppDied processes the
+        // activity list in reverse.
+        firstActivity.mTaskOverlay = true;
+        firstActivity.app = null;
+
+        // second activity will be immediately removed as it has no state.
+        secondActivity.haveState = false;
+
+        assertEquals(mTask.mActivities.size(), 2);
+
+        mStack.handleAppDiedLocked(secondActivity.app);
+
+        assertTrue(mTask.mActivities.isEmpty());
+        assertTrue(mStack.getAllTasks().isEmpty());
+    }
+
+    @Test
+    public void testShouldSleepActivities() throws Exception {
+        // When focused activity and keyguard is going away, we should not sleep regardless
+        // of the display state
+        verifyShouldSleepActivities(true /* focusedStack */, true /*keyguardGoingAway*/,
+                true /* displaySleeping */, false /* expected*/);
+
+        // When not the focused stack, defer to display sleeping state.
+        verifyShouldSleepActivities(false /* focusedStack */, true /*keyguardGoingAway*/,
+                true /* displaySleeping */, true /* expected*/);
+
+        // If keyguard is going away, defer to the display sleeping state.
+        verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
+                true /* displaySleeping */, true /* expected*/);
+        verifyShouldSleepActivities(true /* focusedStack */, false /*keyguardGoingAway*/,
+                false /* displaySleeping */, false /* expected*/);
+    }
+
+    @Test
+    public void testStackOrderChangedOnRemoveStack() throws Exception {
+        StackOrderChangedListener listener = new StackOrderChangedListener();
+        mDefaultDisplay.registerStackOrderChangedListener(listener);
+        try {
+            mDefaultDisplay.removeChild(mStack);
+        } finally {
+            mDefaultDisplay.unregisterStackOrderChangedListener(listener);
+        }
+        assertTrue(listener.changed);
+    }
+
+    @Test
+    public void testStackOrderChangedOnAddPositionStack() throws Exception {
+        mDefaultDisplay.removeChild(mStack);
+
+        StackOrderChangedListener listener = new StackOrderChangedListener();
+        mDefaultDisplay.registerStackOrderChangedListener(listener);
+        try {
+            mDefaultDisplay.addChild(mStack, 0);
+        } finally {
+            mDefaultDisplay.unregisterStackOrderChangedListener(listener);
+        }
+        assertTrue(listener.changed);
+    }
+
+    @Test
+    public void testStackOrderChangedOnPositionStack() throws Exception {
+        StackOrderChangedListener listener = new StackOrderChangedListener();
+        try {
+            final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
+                    mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+                    true /* onTop */);
+            mDefaultDisplay.registerStackOrderChangedListener(listener);
+            mDefaultDisplay.positionChildAtBottom(fullscreenStack1);
+        } finally {
+            mDefaultDisplay.unregisterStackOrderChangedListener(listener);
+        }
+        assertTrue(listener.changed);
+    }
+
+    private void verifyShouldSleepActivities(boolean focusedStack,
+            boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
+        mSupervisor.mFocusedStack = focusedStack ? mStack : null;
+
+        final ActivityDisplay display = mock(ActivityDisplay.class);
+        final KeyguardController keyguardController = mSupervisor.getKeyguardController();
+
+        doReturn(display).when(mSupervisor).getActivityDisplay(anyInt());
+        doReturn(keyguardGoingAway).when(keyguardController).isKeyguardGoingAway();
+        doReturn(displaySleeping).when(display).isSleeping();
+
+        assertEquals(expected, mStack.shouldSleepActivities());
+    }
+
+    private class StackOrderChangedListener implements ActivityDisplay.OnStackOrderChangedListener {
+        boolean changed = false;
+
+        @Override
+        public void onStackOrderChanged() {
+            changed = true;
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
new file mode 100644
index 0000000..7948e4c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+
+import android.content.Intent;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch;
+import com.android.server.am.ActivityStarter.Factory;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.times;
+
+import java.util.Random;
+
+/**
+ * Tests for the {@link ActivityStartController} class.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:ActivityStartControllerTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class ActivityStartControllerTests extends ActivityTestsBase {
+    private ActivityManagerService mService;
+    private ActivityStartController mController;
+    private Factory mFactory;
+    private ActivityStarter mStarter;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mService = createActivityManagerService();
+        mFactory = mock(Factory.class);
+        mController = new ActivityStartController(mService, mService.mStackSupervisor, mFactory);
+        mStarter = spy(new ActivityStarter(mController, mService, mService.mStackSupervisor,
+                mock(ActivityStartInterceptor.class)));
+        doReturn(mStarter).when(mFactory).obtain();
+    }
+
+    /**
+     * Ensures that pending launches are processed.
+     */
+    @Test
+    public void testPendingActivityLaunches() {
+        final Random random = new Random();
+
+        final ActivityRecord activity = new ActivityBuilder(mService).build();
+        final ActivityRecord source = new ActivityBuilder(mService).build();
+        final int startFlags = random.nextInt();
+        final ActivityStack stack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final ProcessRecord process= new ProcessRecord(null, null,
+                mService.mContext.getApplicationInfo(), "name", 12345);
+
+        mController.addPendingActivityLaunch(
+                new PendingActivityLaunch(activity, source, startFlags, stack, process));
+        final boolean resume = random.nextBoolean();
+        mController.doPendingActivityLaunches(resume);
+
+        verify(mStarter, times(1)).startResolvedActivity(eq(activity), eq(source), eq(null),
+                eq(null), eq(startFlags), eq(resume), eq(null), eq(null), eq(null));
+    }
+
+
+    /**
+     * Ensures instances are recycled after execution.
+     */
+    @Test
+    public void testRecycling() throws Exception {
+        final Intent intent = new Intent();
+        final ActivityStarter optionStarter = new ActivityStarter(mController, mService,
+                mService.mStackSupervisor, mock(ActivityStartInterceptor.class));
+        optionStarter
+                .setIntent(intent)
+                .setReason("Test")
+                .execute();
+        verify(mFactory, times(1)).recycle(eq(optionStarter));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
new file mode 100644
index 0000000..b4b34c5
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;
+
+import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.when;
+
+import android.app.KeyguardManager;
+import android.app.admin.DevicePolicyManagerInternal;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManagerInternal;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.test.filters.SmallTest;
+import android.testing.DexmakerShareClassLoaderRule;
+
+import com.android.internal.app.SuspendedAppActivity;
+import com.android.internal.app.UnlaunchableAppActivity;
+import com.android.server.LocalServices;
+import com.android.server.pm.PackageManagerService;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit tests for {@link ActivityStartInterceptorTest}.
+ *
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.am.ActivityStartInterceptorTest
+ */
+@SmallTest
+public class ActivityStartInterceptorTest {
+    private static final int TEST_USER_ID = 1;
+    private static final int TEST_REAL_CALLING_UID = 2;
+    private static final int TEST_REAL_CALLING_PID = 3;
+    private static final String TEST_CALLING_PACKAGE = "com.test.caller";
+    private static final int TEST_START_FLAGS = 4;
+    private static final Intent ADMIN_SUPPORT_INTENT =
+            new Intent("com.test.ADMIN_SUPPORT");
+    private static final Intent CONFIRM_CREDENTIALS_INTENT =
+            new Intent("com.test.CONFIRM_CREDENTIALS");
+    private static final UserInfo PARENT_USER_INFO = new UserInfo(0 /* userId */, "parent",
+            0 /* flags */);
+    private static final String TEST_PACKAGE_NAME = "com.test.package";
+
+    @Rule
+    public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
+            new DexmakerShareClassLoaderRule();
+
+    @Mock
+    private Context mContext;
+    @Mock
+    private ActivityManagerService mService;
+    @Mock
+    private ActivityStackSupervisor mSupervisor;
+    @Mock
+    private DevicePolicyManagerInternal mDevicePolicyManager;
+    @Mock
+    private PackageManagerInternal mPackageManagerInternal;
+    @Mock
+    private UserManager mUserManager;
+    @Mock
+    private UserController mUserController;
+    @Mock
+    private KeyguardManager mKeyguardManager;
+    @Mock
+    private PackageManagerService mPackageManager;
+
+    private ActivityStartInterceptor mInterceptor;
+    private ActivityInfo mAInfo = new ActivityInfo();
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mInterceptor = new ActivityStartInterceptor(mService, mSupervisor, mContext,
+                mUserController);
+        mInterceptor.setStates(TEST_USER_ID, TEST_REAL_CALLING_PID, TEST_REAL_CALLING_UID,
+                TEST_START_FLAGS, TEST_CALLING_PACKAGE);
+
+        // Mock DevicePolicyManagerInternal
+        LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
+        LocalServices.addService(DevicePolicyManagerInternal.class,
+                mDevicePolicyManager);
+        when(mDevicePolicyManager
+                        .createShowAdminSupportIntent(TEST_USER_ID, true))
+                .thenReturn(ADMIN_SUPPORT_INTENT);
+        when(mService.getPackageManagerInternalLocked()).thenReturn(mPackageManagerInternal);
+
+        // Mock UserManager
+        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+        when(mUserManager.getProfileParent(TEST_USER_ID)).thenReturn(PARENT_USER_INFO);
+
+        // Mock KeyguardManager
+        when(mContext.getSystemService(Context.KEYGUARD_SERVICE)).thenReturn(mKeyguardManager);
+        when(mKeyguardManager.createConfirmDeviceCredentialIntent(
+                nullable(CharSequence.class), nullable(CharSequence.class), eq(TEST_USER_ID))).
+                thenReturn(CONFIRM_CREDENTIALS_INTENT);
+
+        // Mock PackageManager
+        when(mService.getPackageManager()).thenReturn(mPackageManager);
+        when(mPackageManager.getHarmfulAppWarning(TEST_PACKAGE_NAME, TEST_USER_ID))
+                .thenReturn(null);
+
+        // Initialise activity info
+        mAInfo.applicationInfo = new ApplicationInfo();
+        mAInfo.packageName = mAInfo.applicationInfo.packageName = TEST_PACKAGE_NAME;
+    }
+
+    @Test
+    public void testSuspendedByAdminPackage() {
+        // GIVEN the package we're about to launch is currently suspended
+        mAInfo.applicationInfo.flags = FLAG_SUSPENDED;
+
+        when(mPackageManagerInternal.getSuspendingPackage(TEST_PACKAGE_NAME, TEST_USER_ID))
+                .thenReturn(PLATFORM_PACKAGE_NAME);
+
+        // THEN calling intercept returns true
+        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
+
+        // THEN the returned intent is the admin support intent
+        assertEquals(ADMIN_SUPPORT_INTENT, mInterceptor.mIntent);
+    }
+
+    @Test
+    public void testSuspendedPackage() {
+        mAInfo.applicationInfo.flags = FLAG_SUSPENDED;
+        final String suspendingPackage = "com.test.suspending.package";
+        final String dialogMessage = "Test Message";
+        when(mPackageManagerInternal.getSuspendingPackage(TEST_PACKAGE_NAME, TEST_USER_ID))
+                .thenReturn(suspendingPackage);
+        when(mPackageManagerInternal.getSuspendedDialogMessage(TEST_PACKAGE_NAME, TEST_USER_ID))
+                .thenReturn(dialogMessage);
+        // THEN calling intercept returns true
+        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
+
+        // Check intent parameters
+        assertEquals(dialogMessage,
+                mInterceptor.mIntent.getStringExtra(SuspendedAppActivity.EXTRA_DIALOG_MESSAGE));
+        assertEquals(suspendingPackage,
+                mInterceptor.mIntent.getStringExtra(SuspendedAppActivity.EXTRA_SUSPENDING_PACKAGE));
+        assertEquals(TEST_PACKAGE_NAME,
+                mInterceptor.mIntent.getStringExtra(SuspendedAppActivity.EXTRA_SUSPENDED_PACKAGE));
+        assertEquals(TEST_USER_ID, mInterceptor.mIntent.getIntExtra(Intent.EXTRA_USER_ID, -1000));
+    }
+
+    @Test
+    public void testInterceptQuietProfile() {
+        // GIVEN that the user the activity is starting as is currently in quiet mode
+        when(mUserManager.isQuietModeEnabled(eq(UserHandle.of(TEST_USER_ID)))).thenReturn(true);
+
+        // THEN calling intercept returns true
+        assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
+
+        // THEN the returned intent is the quiet mode intent
+        assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID)
+                .filterEquals(mInterceptor.mIntent));
+    }
+
+    @Test
+    public void testWorkChallenge() {
+        // GIVEN that the user the activity is starting as is currently locked
+        when(mUserController.shouldConfirmCredentials(TEST_USER_ID)).thenReturn(true);
+
+        // THEN calling intercept returns true
+        mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null);
+
+        // THEN the returned intent is the quiet mode intent
+        assertTrue(CONFIRM_CREDENTIALS_INTENT.filterEquals(mInterceptor.mIntent));
+    }
+
+    @Test
+    public void testNoInterception() {
+        // GIVEN that none of the interception conditions are met
+
+        // THEN calling intercept returns false
+        assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
new file mode 100644
index 0000000..1520859
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
@@ -0,0 +1,474 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import static android.app.ActivityManager.START_ABORTED;
+import static android.app.ActivityManager.START_CLASS_NOT_FOUND;
+import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
+import static android.app.ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
+import static android.app.ActivityManager.START_INTENT_NOT_RESOLVED;
+import static android.app.ActivityManager.START_NOT_VOICE_COMPATIBLE;
+import static android.app.ActivityManager.START_PERMISSION_DENIED;
+import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
+import static android.app.ActivityManager.START_SUCCESS;
+import static android.app.ActivityManager.START_SWITCHES_CANCELED;
+import static android.app.ActivityManager.START_TASK_TO_FRONT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
+
+import android.app.ActivityOptions;
+import android.app.IApplicationThread;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ActivityInfo.WindowLayout;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.graphics.Rect;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.service.voice.IVoiceInteractionSession;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.Gravity;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
+import static com.android.server.am.ActivityManagerService.ANIMATE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyObject;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.times;
+
+import com.android.internal.os.BatteryStatsImpl;
+import com.android.server.am.ActivityStarter.Factory;
+import com.android.server.am.LaunchParamsController.LaunchParamsModifier;
+import com.android.server.am.TaskRecord.TaskRecordFactory;
+
+import java.util.ArrayList;
+
+/**
+ * Tests for the {@link ActivityStarter} class.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:ActivityStarterTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class ActivityStarterTests extends ActivityTestsBase {
+    private ActivityManagerService mService;
+    private ActivityStarter mStarter;
+    private ActivityStartController mController;
+
+    private static final int PRECONDITION_NO_CALLER_APP = 1;
+    private static final int PRECONDITION_NO_INTENT_COMPONENT = 1 << 1;
+    private static final int PRECONDITION_NO_ACTIVITY_INFO = 1 << 2;
+    private static final int PRECONDITION_SOURCE_PRESENT = 1 << 3;
+    private static final int PRECONDITION_REQUEST_CODE = 1 << 4;
+    private static final int PRECONDITION_SOURCE_VOICE_SESSION = 1 << 5;
+    private static final int PRECONDITION_NO_VOICE_SESSION_SUPPORT = 1 << 6;
+    private static final int PRECONDITION_DIFFERENT_UID = 1 << 7;
+    private static final int PRECONDITION_ACTIVITY_SUPPORTS_INTENT_EXCEPTION = 1 << 8;
+    private static final int PRECONDITION_CANNOT_START_ANY_ACTIVITY = 1 << 9;
+    private static final int PRECONDITION_DISALLOW_APP_SWITCHING = 1 << 10;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mService = createActivityManagerService();
+        mController = mock(ActivityStartController.class);
+        mStarter = new ActivityStarter(mController, mService, mService.mStackSupervisor,
+                mock(ActivityStartInterceptor.class));
+    }
+
+    @Test
+    public void testUpdateLaunchBounds() throws Exception {
+        // When in a non-resizeable stack, the task bounds should be updated.
+        final TaskRecord task = new TaskBuilder(mService.mStackSupervisor)
+                .setStack(mService.mStackSupervisor.getDefaultDisplay().createStack(
+                        WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */))
+                .build();
+        final Rect bounds = new Rect(10, 10, 100, 100);
+
+        mStarter.updateBounds(task, bounds);
+        assertEquals(task.getOverrideBounds(), bounds);
+        assertEquals(new Rect(), task.getStack().getOverrideBounds());
+
+        // When in a resizeable stack, the stack bounds should be updated as well.
+        final TaskRecord task2 = new TaskBuilder(mService.mStackSupervisor)
+                .setStack(mService.mStackSupervisor.getDefaultDisplay().createStack(
+                        WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */))
+                .build();
+        assertTrue(task2.getStack() instanceof PinnedActivityStack);
+        mStarter.updateBounds(task2, bounds);
+
+        verify(mService, times(1)).resizeStack(eq(task2.getStack().mStackId),
+                eq(bounds), anyBoolean(), anyBoolean(), anyBoolean(), anyInt());
+
+        // In the case of no animation, the stack and task bounds should be set immediately.
+        if (!ANIMATE) {
+            assertEquals(task2.getStack().getOverrideBounds(), bounds);
+            assertEquals(task2.getOverrideBounds(), bounds);
+        } else {
+            assertEquals(task2.getOverrideBounds(), new Rect());
+        }
+    }
+
+    @Test
+    public void testStartActivityPreconditions() throws Exception {
+        verifyStartActivityPreconditions(PRECONDITION_NO_CALLER_APP, START_PERMISSION_DENIED);
+        verifyStartActivityPreconditions(PRECONDITION_NO_INTENT_COMPONENT,
+                START_INTENT_NOT_RESOLVED);
+        verifyStartActivityPreconditions(PRECONDITION_NO_ACTIVITY_INFO, START_CLASS_NOT_FOUND);
+        verifyStartActivityPreconditions(PRECONDITION_SOURCE_PRESENT | PRECONDITION_REQUEST_CODE,
+                Intent.FLAG_ACTIVITY_FORWARD_RESULT, START_FORWARD_AND_REQUEST_CONFLICT);
+        verifyStartActivityPreconditions(
+                PRECONDITION_SOURCE_PRESENT | PRECONDITION_NO_VOICE_SESSION_SUPPORT
+                        | PRECONDITION_SOURCE_VOICE_SESSION | PRECONDITION_DIFFERENT_UID,
+                START_NOT_VOICE_COMPATIBLE);
+        verifyStartActivityPreconditions(
+                PRECONDITION_SOURCE_PRESENT | PRECONDITION_NO_VOICE_SESSION_SUPPORT
+                        | PRECONDITION_SOURCE_VOICE_SESSION | PRECONDITION_DIFFERENT_UID
+                        | PRECONDITION_ACTIVITY_SUPPORTS_INTENT_EXCEPTION,
+                START_NOT_VOICE_COMPATIBLE);
+        verifyStartActivityPreconditions(PRECONDITION_CANNOT_START_ANY_ACTIVITY, START_ABORTED);
+        verifyStartActivityPreconditions(PRECONDITION_DISALLOW_APP_SWITCHING,
+                START_SWITCHES_CANCELED);
+    }
+
+    private static boolean containsConditions(int preconditions, int mask) {
+        return (preconditions & mask) == mask;
+    }
+
+    private void verifyStartActivityPreconditions(int preconditions, int expectedResult) {
+        verifyStartActivityPreconditions(preconditions, 0 /*launchFlags*/, expectedResult);
+    }
+
+    /**
+     * Excercises how the {@link ActivityStarter} reacts to various preconditions. The caller
+     * provides a bitmask of all the set conditions (such as {@link #PRECONDITION_NO_CALLER_APP})
+     * and the launch flags specified in the intent. The method constructs a call to
+     * {@link ActivityStarter#execute} based on these preconditions and ensures the result matches
+     * the expected. It is important to note that the method also checks side effects of the start,
+     * such as ensuring {@link ActivityOptions#abort()} is called in the relevant scenarios.
+     * @param preconditions A bitmask representing the preconditions for the launch
+     * @param launchFlags The launch flags to be provided by the launch {@link Intent}.
+     * @param expectedResult The expected result from the launch.
+     */
+    private void verifyStartActivityPreconditions(int preconditions, int launchFlags,
+            int expectedResult) {
+        final ActivityManagerService service = createActivityManagerService();
+        final IPackageManager packageManager = mock(IPackageManager.class);
+        final ActivityStartController controller = mock(ActivityStartController.class);
+
+        final ActivityStarter starter = new ActivityStarter(controller, service,
+                service.mStackSupervisor, mock(ActivityStartInterceptor.class));
+        final IApplicationThread caller = mock(IApplicationThread.class);
+
+        // If no caller app, return {@code null} {@link ProcessRecord}.
+        final ProcessRecord record = containsConditions(preconditions, PRECONDITION_NO_CALLER_APP)
+                ? null : new ProcessRecord(null, mock(BatteryStatsImpl.class),
+                mock(ApplicationInfo.class), null, 0);
+
+        doReturn(record).when(service).getRecordForAppLocked(anyObject());
+
+        final Intent intent = new Intent();
+        intent.setFlags(launchFlags);
+
+        final ActivityInfo aInfo = containsConditions(preconditions, PRECONDITION_NO_ACTIVITY_INFO)
+                ?  null : new ActivityInfo();
+
+        IVoiceInteractionSession voiceSession =
+                containsConditions(preconditions, PRECONDITION_SOURCE_VOICE_SESSION)
+                ? mock(IVoiceInteractionSession.class) : null;
+
+        // Create source token
+        final ActivityBuilder builder = new ActivityBuilder(service).setTask(
+                new TaskBuilder(service.mStackSupervisor).setVoiceSession(voiceSession).build());
+
+        if (aInfo != null) {
+            aInfo.applicationInfo = new ApplicationInfo();
+            aInfo.applicationInfo.packageName =
+                    ActivityBuilder.getDefaultComponent().getPackageName();
+        }
+
+        // Offset uid by one from {@link ActivityInfo} to simulate different uids.
+        if (containsConditions(preconditions, PRECONDITION_DIFFERENT_UID)) {
+            builder.setUid(aInfo.applicationInfo.uid + 1);
+        }
+
+        final ActivityRecord source = builder.build();
+
+        if (!containsConditions(preconditions, PRECONDITION_NO_INTENT_COMPONENT)) {
+            intent.setComponent(source.realActivity);
+        }
+
+        if (containsConditions(preconditions, PRECONDITION_DISALLOW_APP_SWITCHING)) {
+            doReturn(false).when(service).checkAppSwitchAllowedLocked(anyInt(), anyInt(), anyInt(),
+                    anyInt(), any());
+        }
+
+        if (containsConditions(preconditions,PRECONDITION_CANNOT_START_ANY_ACTIVITY)) {
+            doReturn(false).when(service.mStackSupervisor).checkStartAnyActivityPermission(
+                    any(), any(), any(), anyInt(), anyInt(), anyInt(), any(),
+                    anyBoolean(), anyBoolean(), any(), any(), any());
+        }
+
+        try {
+            if (containsConditions(preconditions,
+                    PRECONDITION_ACTIVITY_SUPPORTS_INTENT_EXCEPTION)) {
+                doAnswer((inv) -> {
+                    throw new RemoteException();
+                }).when(packageManager).activitySupportsIntent(eq(source.realActivity), eq(intent),
+                        any());
+            } else {
+                doReturn(!containsConditions(preconditions, PRECONDITION_NO_VOICE_SESSION_SUPPORT))
+                        .when(packageManager).activitySupportsIntent(eq(source.realActivity),
+                        eq(intent), any());
+            }
+        } catch (RemoteException e) {
+        }
+
+        final IBinder resultTo = containsConditions(preconditions, PRECONDITION_SOURCE_PRESENT)
+                || containsConditions(preconditions, PRECONDITION_SOURCE_VOICE_SESSION)
+                ? source.appToken : null;
+
+        final int requestCode = containsConditions(preconditions, PRECONDITION_REQUEST_CODE)
+                ? 1 : 0;
+
+        final int result = starter.setCaller(caller)
+                .setIntent(intent)
+                .setActivityInfo(aInfo)
+                .setResultTo(resultTo)
+                .setRequestCode(requestCode)
+                .setReason("testLaunchActivityPermissionDenied")
+                .execute();
+
+        // In some cases the expected result internally is different than the published result. We
+        // must use ActivityStarter#getExternalResult to translate.
+        assertEquals(ActivityStarter.getExternalResult(expectedResult), result);
+
+        // Ensure that {@link ActivityOptions} are aborted with unsuccessful result.
+        if (expectedResult != START_SUCCESS) {
+            final ActivityStarter optionStarter = new ActivityStarter(mController, mService,
+                    mService.mStackSupervisor, mock(ActivityStartInterceptor.class));
+            final ActivityOptions options = spy(ActivityOptions.makeBasic());
+
+            final int optionResult = optionStarter.setCaller(caller)
+                    .setIntent(intent)
+                    .setActivityInfo(aInfo)
+                    .setResultTo(resultTo)
+                    .setRequestCode(requestCode)
+                    .setReason("testLaunchActivityPermissionDenied")
+                    .setActivityOptions(new SafeActivityOptions(options))
+                    .execute();
+            verify(options, times(1)).abort();
+        }
+    }
+
+    private ActivityStarter prepareStarter(int launchFlags) {
+        // always allow test to start activity.
+        doReturn(true).when(mService.mStackSupervisor).checkStartAnyActivityPermission(
+                any(), any(), any(), anyInt(), anyInt(), anyInt(), any(),
+                anyBoolean(), anyBoolean(), any(), any(), any());
+
+        // instrument the stack and task used.
+        final ActivityStack stack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final TaskRecord task = new TaskBuilder(mService.mStackSupervisor)
+                .setCreateStack(false)
+                .build();
+
+        // supervisor needs a focused stack.
+        mService.mStackSupervisor.mFocusedStack = stack;
+
+        // use factory that only returns spy task.
+        final TaskRecordFactory factory = mock(TaskRecordFactory.class);
+        TaskRecord.setTaskRecordFactory(factory);
+
+        // return task when created.
+        doReturn(task).when(factory).create(any(), anyInt(), any(), any(), any(), any());
+
+        // direct starter to use spy stack.
+        doReturn(stack).when(mService.mStackSupervisor)
+                .getLaunchStack(any(), any(), any(), anyBoolean());
+        doReturn(stack).when(mService.mStackSupervisor)
+                .getLaunchStack(any(), any(), any(), anyBoolean(), anyInt());
+
+        final Intent intent = new Intent();
+        intent.addFlags(launchFlags);
+        intent.setComponent(ActivityBuilder.getDefaultComponent());
+
+        final ActivityInfo info = new ActivityInfo();
+
+        info.applicationInfo = new ApplicationInfo();
+        info.applicationInfo.packageName = ActivityBuilder.getDefaultComponent().getPackageName();
+
+        return new ActivityStarter(mController, mService,
+                mService.mStackSupervisor, mock(ActivityStartInterceptor.class))
+                .setIntent(intent)
+                .setActivityInfo(info);
+    }
+
+    /**
+     * Ensures that values specified at launch time are passed to {@link LaunchParamsModifier}
+     * when we are laying out a new task.
+     */
+    @Test
+    public void testCreateTaskLayout() {
+        // modifier for validating passed values.
+        final LaunchParamsModifier modifier = mock(LaunchParamsModifier.class);
+        mService.mStackSupervisor.getLaunchParamsController().registerModifier(modifier);
+
+        // add custom values to activity info to make unique.
+        final ActivityInfo info = new ActivityInfo();
+        final Rect launchBounds = new Rect(0, 0, 20, 30);
+
+        final WindowLayout windowLayout =
+                new WindowLayout(10, .5f, 20, 1.0f, Gravity.NO_GRAVITY, 1, 1);
+
+        info.windowLayout = windowLayout;
+        info.applicationInfo = new ApplicationInfo();
+        info.applicationInfo.packageName = ActivityBuilder.getDefaultComponent().getPackageName();
+
+        // create starter.
+        final ActivityStarter optionStarter = prepareStarter(0 /* launchFlags */);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchBounds(launchBounds);
+
+        // run starter.
+        optionStarter
+                .setReason("testCreateTaskLayout")
+                .setActivityInfo(info)
+                .setActivityOptions(new SafeActivityOptions(options))
+                .execute();
+
+        // verify that values are passed to the modifier.
+        verify(modifier, times(1)).onCalculate(any(), eq(windowLayout), any(), any(), eq(options),
+                any(), any());
+    }
+
+    /**
+     * This test ensures that if the intent is being delivered to a
+     */
+    @Test
+    public void testSplitScreenDeliverToTop() {
+        final ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+
+        final ActivityRecord focusActivity = new ActivityBuilder(mService)
+                .setCreateTask(true)
+                .build();
+
+        focusActivity.getStack().setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+
+        final ActivityRecord reusableActivity = new ActivityBuilder(mService)
+                .setCreateTask(true)
+                .build();
+
+        // Create reusable activity after entering split-screen so that it is the top secondary
+        // stack.
+        reusableActivity.getStack().setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+
+        // Set focus back to primary.
+        mService.mStackSupervisor.setFocusStackUnchecked("testSplitScreenDeliverToTop",
+                focusActivity.getStack());
+
+        doReturn(reusableActivity).when(mService.mStackSupervisor).findTaskLocked(any(), anyInt());
+
+        final int result = starter.setReason("testSplitScreenDeliverToTop").execute();
+
+        // Ensure result is delivering intent to top.
+        assertEquals(result, START_DELIVERED_TO_TOP);
+    }
+
+    /**
+     * This test ensures that if the intent is being delivered to a split-screen unfocused task
+     * reports it is brought to front instead of delivering to top.
+     */
+    @Test
+    public void testSplitScreenTaskToFront() {
+        final ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+
+        // Create reusable activity here first. Setting the windowing mode of the primary stack
+        // will move the existing standard full screen stack to secondary, putting this one on the
+        // bottom.
+        final ActivityRecord reusableActivity = new ActivityBuilder(mService)
+                .setCreateTask(true)
+                .build();
+
+        reusableActivity.getStack().setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+
+        final ActivityRecord focusActivity = new ActivityBuilder(mService)
+                .setCreateTask(true)
+                .build();
+
+        // Enter split-screen. Primary stack should have focus.
+        focusActivity.getStack().setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+
+        doReturn(reusableActivity).when(mService.mStackSupervisor).findTaskLocked(any(), anyInt());
+
+        final int result = starter.setReason("testSplitScreenMoveToFront").execute();
+
+        // Ensure result is moving task to front.
+        assertEquals(result, START_TASK_TO_FRONT);
+    }
+
+    /**
+     * Tests activity is cleaned up properly in a task mode violation.
+     */
+    @Test
+    public void testTaskModeViolation() {
+        final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
+        assertNoTasks(display);
+
+        final ActivityStarter starter = prepareStarter(0);
+
+        final LockTaskController lockTaskController = mService.getLockTaskController();
+        doReturn(true).when(lockTaskController).isLockTaskModeViolation(any());
+
+        final int result = starter.setReason("testTaskModeViolation").execute();
+
+        assertEquals(START_RETURN_LOCK_TASK_MODE_VIOLATION, result);
+        assertNoTasks(display);
+    }
+
+    private void assertNoTasks(ActivityDisplay display) {
+        for (int i = display.getChildCount() - 1; i >= 0; --i) {
+            final ActivityStack stack = display.getChildAt(i);
+            assertTrue(stack.getAllTasks().isEmpty());
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
new file mode 100644
index 0000000..1cd111f
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -0,0 +1,593 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.spy;
+
+import android.app.ActivityOptions;
+import com.android.server.wm.DisplayWindowController;
+
+import org.junit.Rule;
+import org.mockito.invocation.InvocationOnMock;
+
+import android.app.IApplicationThread;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.service.voice.IVoiceInteractionSession;
+import android.support.test.InstrumentationRegistry;
+import android.testing.DexmakerShareClassLoaderRule;
+
+
+import com.android.internal.app.IVoiceInteractor;
+
+import com.android.server.AttributeCache;
+import com.android.server.wm.AppWindowContainerController;
+import com.android.server.wm.PinnedStackWindowController;
+import com.android.server.wm.StackWindowController;
+import com.android.server.wm.TaskWindowContainerController;
+import com.android.server.wm.WindowManagerService;
+import com.android.server.wm.WindowTestUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.mockito.MockitoAnnotations;
+
+
+/**
+ * A base class to handle common operations in activity related unit tests.
+ */
+public class ActivityTestsBase {
+    private static boolean sOneTimeSetupDone = false;
+
+    @Rule
+    public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
+            new DexmakerShareClassLoaderRule();
+
+    private final Context mContext = InstrumentationRegistry.getContext();
+    private HandlerThread mHandlerThread;
+
+    // Default package name
+    static final String DEFAULT_COMPONENT_PACKAGE_NAME = "com.foo";
+
+    // Default base activity name
+    private static final String DEFAULT_COMPONENT_CLASS_NAME = ".BarActivity";
+
+    @Before
+    public void setUp() throws Exception {
+        if (!sOneTimeSetupDone) {
+            sOneTimeSetupDone = true;
+            MockitoAnnotations.initMocks(this);
+        }
+        mHandlerThread = new HandlerThread("ActivityTestsBaseThread");
+        mHandlerThread.start();
+    }
+
+    @After
+    public void tearDown() {
+        mHandlerThread.quitSafely();
+    }
+
+    protected ActivityManagerService createActivityManagerService() {
+        final ActivityManagerService service =
+                setupActivityManagerService(new TestActivityManagerService(mContext));
+        AttributeCache.init(mContext);
+        return service;
+    }
+
+    protected ActivityManagerService setupActivityManagerService(ActivityManagerService service) {
+        service = spy(service);
+        doReturn(mock(IPackageManager.class)).when(service).getPackageManager();
+        doNothing().when(service).grantEphemeralAccessLocked(anyInt(), any(), anyInt(), anyInt());
+        service.mWindowManager = prepareMockWindowManager();
+        return service;
+    }
+
+    /**
+     * Builder for creating new activities.
+     */
+    protected static class ActivityBuilder {
+        // An id appended to the end of the component name to make it unique
+        private static int sCurrentActivityId = 0;
+
+
+
+        private final ActivityManagerService mService;
+
+        private ComponentName mComponent;
+        private TaskRecord mTaskRecord;
+        private int mUid;
+        private boolean mCreateTask;
+        private ActivityStack mStack;
+        private int mActivityFlags;
+
+        ActivityBuilder(ActivityManagerService service) {
+            mService = service;
+        }
+
+        ActivityBuilder setComponent(ComponentName component) {
+            mComponent = component;
+            return this;
+        }
+
+        static ComponentName getDefaultComponent() {
+            return ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
+                    DEFAULT_COMPONENT_PACKAGE_NAME);
+        }
+
+        ActivityBuilder setTask(TaskRecord task) {
+            mTaskRecord = task;
+            return this;
+        }
+
+        ActivityBuilder setActivityFlags(int flags) {
+            mActivityFlags = flags;
+            return this;
+        }
+
+        ActivityBuilder setStack(ActivityStack stack) {
+            mStack = stack;
+            return this;
+        }
+
+        ActivityBuilder setCreateTask(boolean createTask) {
+            mCreateTask = createTask;
+            return this;
+        }
+
+        ActivityBuilder setUid(int uid) {
+            mUid = uid;
+            return this;
+        }
+
+        ActivityRecord build() {
+            if (mComponent == null) {
+                final int id = sCurrentActivityId++;
+                mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
+                        DEFAULT_COMPONENT_CLASS_NAME + id);
+            }
+
+            if (mCreateTask) {
+                mTaskRecord = new TaskBuilder(mService.mStackSupervisor)
+                        .setComponent(mComponent)
+                        .setStack(mStack).build();
+            }
+
+            Intent intent = new Intent();
+            intent.setComponent(mComponent);
+            final ActivityInfo aInfo = new ActivityInfo();
+            aInfo.applicationInfo = new ApplicationInfo();
+            aInfo.applicationInfo.packageName = mComponent.getPackageName();
+            aInfo.applicationInfo.uid = mUid;
+            aInfo.flags |= mActivityFlags;
+
+            final ActivityRecord activity = new ActivityRecord(mService, null /* caller */,
+                    0 /* launchedFromPid */, 0, null, intent, null,
+                    aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */,
+                    0 /* reqCode */, false /*componentSpecified*/, false /* rootVoiceInteraction */,
+                    mService.mStackSupervisor, null /* options */, null /* sourceRecord */);
+            activity.mWindowContainerController = mock(AppWindowContainerController.class);
+
+            if (mTaskRecord != null) {
+                mTaskRecord.addActivityToTop(activity);
+            }
+
+            activity.setProcess(new ProcessRecord(null, null,
+                    mService.mContext.getApplicationInfo(), "name", 12345));
+            activity.app.thread = mock(IApplicationThread.class);
+
+            return activity;
+        }
+    }
+
+    /**
+     * Builder for creating new tasks.
+     */
+    protected static class TaskBuilder {
+        // Default package name
+        static final String DEFAULT_PACKAGE = "com.bar";
+
+        private final ActivityStackSupervisor mSupervisor;
+
+        private ComponentName mComponent;
+        private String mPackage;
+        private int mFlags = 0;
+        private int mTaskId = 0;
+        private int mUserId = 0;
+        private IVoiceInteractionSession mVoiceSession;
+        private boolean mCreateStack = true;
+
+        private ActivityStack mStack;
+
+        TaskBuilder(ActivityStackSupervisor supervisor) {
+            mSupervisor = supervisor;
+        }
+
+        TaskBuilder setComponent(ComponentName component) {
+            mComponent = component;
+            return this;
+        }
+
+        TaskBuilder setPackage(String packageName) {
+            mPackage = packageName;
+            return this;
+        }
+
+        /**
+         * Set to {@code true} by default, set to {@code false} to prevent the task from
+         * automatically creating a parent stack.
+         */
+        TaskBuilder setCreateStack(boolean createStack) {
+            mCreateStack = createStack;
+            return this;
+        }
+
+        TaskBuilder setVoiceSession(IVoiceInteractionSession session) {
+            mVoiceSession = session;
+            return this;
+        }
+
+        TaskBuilder setFlags(int flags) {
+            mFlags = flags;
+            return this;
+        }
+
+        TaskBuilder setTaskId(int taskId) {
+            mTaskId = taskId;
+            return this;
+        }
+
+        TaskBuilder setUserId(int userId) {
+            mUserId = userId;
+            return this;
+        }
+
+        TaskBuilder setStack(ActivityStack stack) {
+            mStack = stack;
+            return this;
+        }
+
+        TaskRecord build() {
+            if (mStack == null && mCreateStack) {
+                mStack = mSupervisor.getDefaultDisplay().createStack(
+                        WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+            }
+
+            final ActivityInfo aInfo = new ActivityInfo();
+            aInfo.applicationInfo = new ApplicationInfo();
+            aInfo.applicationInfo.packageName = mPackage;
+
+            Intent intent = new Intent();
+            if (mComponent == null) {
+                mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
+                        DEFAULT_COMPONENT_CLASS_NAME);
+            }
+
+            intent.setComponent(mComponent);
+            intent.setFlags(mFlags);
+
+            final TestTaskRecord task = new TestTaskRecord(mSupervisor.mService, mTaskId, aInfo,
+                    intent /*intent*/, mVoiceSession, null /*_voiceInteractor*/);
+            task.userId = mUserId;
+
+            if (mStack != null) {
+                mSupervisor.setFocusStackUnchecked("test", mStack);
+                mStack.addTask(task, true, "creating test task");
+                task.setStack(mStack);
+                task.setWindowContainerController();
+            }
+
+            task.touchActiveTime();
+
+            return task;
+        }
+
+        private static class TestTaskRecord extends TaskRecord {
+            TestTaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info,
+                       Intent _intent, IVoiceInteractionSession _voiceSession,
+                       IVoiceInteractor _voiceInteractor) {
+                super(service, _taskId, info, _intent, _voiceSession, _voiceInteractor);
+            }
+
+            @Override
+            void createWindowContainer(boolean onTop, boolean showForAllUsers) {
+                setWindowContainerController();
+            }
+
+            private void setWindowContainerController() {
+                setWindowContainerController(mock(TaskWindowContainerController.class));
+            }
+        }
+    }
+
+    /**
+     * An {@link ActivityManagerService} subclass which provides a test
+     * {@link ActivityStackSupervisor}.
+     */
+    protected static class TestActivityManagerService extends ActivityManagerService {
+        private ClientLifecycleManager mLifecycleManager;
+        private LockTaskController mLockTaskController;
+
+        TestActivityManagerService(Context context) {
+            super(context);
+            mSupportsMultiWindow = true;
+            mSupportsMultiDisplay = true;
+            mSupportsSplitScreenMultiWindow = true;
+            mSupportsFreeformWindowManagement = true;
+            mSupportsPictureInPicture = true;
+            mWindowManager = WindowTestUtils.getMockWindowManagerService();
+        }
+
+        @Override
+        public ClientLifecycleManager getLifecycleManager() {
+            if (mLifecycleManager == null) {
+                return super.getLifecycleManager();
+            }
+            return mLifecycleManager;
+        }
+
+        public LockTaskController getLockTaskController() {
+            if (mLockTaskController == null) {
+                mLockTaskController = spy(super.getLockTaskController());
+            }
+
+            return mLockTaskController;
+        }
+
+        void setLifecycleManager(ClientLifecycleManager manager) {
+            mLifecycleManager = manager;
+        }
+
+        @Override
+        final protected ActivityStackSupervisor createStackSupervisor() {
+            final ActivityStackSupervisor supervisor = spy(createTestSupervisor());
+            final KeyguardController keyguardController = mock(KeyguardController.class);
+
+            // No home stack is set.
+            doNothing().when(supervisor).moveHomeStackToFront(any());
+            doReturn(true).when(supervisor).moveHomeStackTaskToTop(any());
+            // Invoked during {@link ActivityStack} creation.
+            doNothing().when(supervisor).updateUIDsPresentOnDisplay();
+            // Always keep things awake.
+            doReturn(true).when(supervisor).hasAwakeDisplay();
+            // Called when moving activity to pinned stack.
+            doNothing().when(supervisor).ensureActivitiesVisibleLocked(any(), anyInt(), anyBoolean());
+            // Do not schedule idle timeouts
+            doNothing().when(supervisor).scheduleIdleTimeoutLocked(any());
+            // unit test version does not handle launch wake lock
+            doNothing().when(supervisor).acquireLaunchWakelock();
+            doReturn(keyguardController).when(supervisor).getKeyguardController();
+
+            supervisor.initialize();
+
+            return supervisor;
+        }
+
+        protected ActivityStackSupervisor createTestSupervisor() {
+            return new TestActivityStackSupervisor(this, mHandlerThread.getLooper());
+        }
+
+        @Override
+        void updateUsageStats(ActivityRecord component, boolean resumed) {
+        }
+    }
+
+    /**
+     * An {@link ActivityStackSupervisor} which stubs out certain methods that depend on
+     * setup not available in the test environment. Also specifies an injector for
+     */
+    protected static class TestActivityStackSupervisor extends ActivityStackSupervisor {
+        private ActivityDisplay mDisplay;
+        private KeyguardController mKeyguardController;
+
+        public TestActivityStackSupervisor(ActivityManagerService service, Looper looper) {
+            super(service, looper);
+            mDisplayManager =
+                    (DisplayManager) mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
+            mWindowManager = prepareMockWindowManager();
+            mKeyguardController = mock(KeyguardController.class);
+        }
+
+        @Override
+        public void initialize() {
+            super.initialize();
+            mDisplay = spy(new TestActivityDisplay(this, DEFAULT_DISPLAY));
+            attachDisplay(mDisplay);
+        }
+
+        @Override
+        public KeyguardController getKeyguardController() {
+            return mKeyguardController;
+        }
+
+        @Override
+        ActivityDisplay getDefaultDisplay() {
+            return mDisplay;
+        }
+
+        // Just return the current front task. This is called internally so we cannot use spy to mock this out.
+        @Override
+        ActivityStack getNextFocusableStackLocked(ActivityStack currentFocus,
+                boolean ignoreCurrent) {
+            return mFocusedStack;
+        }
+    }
+
+    protected static class TestActivityDisplay extends ActivityDisplay {
+
+        private final ActivityStackSupervisor mSupervisor;
+        TestActivityDisplay(ActivityStackSupervisor supervisor, int displayId) {
+            super(supervisor, displayId);
+            mSupervisor = supervisor;
+        }
+
+        @Override
+        <T extends ActivityStack> T createStackUnchecked(int windowingMode, int activityType,
+                int stackId, boolean onTop) {
+            if (windowingMode == WINDOWING_MODE_PINNED) {
+                return (T) new PinnedActivityStack(this, stackId, mSupervisor, onTop) {
+                    @Override
+                    Rect getDefaultPictureInPictureBounds(float aspectRatio) {
+                        return new Rect(50, 50, 100, 100);
+                    }
+
+                    @Override
+                    PinnedStackWindowController createStackWindowController(int displayId,
+                            boolean onTop, Rect outBounds) {
+                        return mock(PinnedStackWindowController.class);
+                    }
+                };
+            } else {
+                return (T) new TestActivityStack(
+                        this, stackId, mSupervisor, windowingMode, activityType, onTop);
+            }
+        }
+
+        @Override
+        protected DisplayWindowController createWindowContainerController() {
+            return mock(DisplayWindowController.class);
+        }
+    }
+
+    private static WindowManagerService prepareMockWindowManager() {
+        final WindowManagerService service = WindowTestUtils.getMockWindowManagerService();
+
+        doAnswer((InvocationOnMock invocationOnMock) -> {
+            final Runnable runnable = invocationOnMock.<Runnable>getArgument(0);
+            if (runnable != null) {
+                runnable.run();
+            }
+            return null;
+        }).when(service).inSurfaceTransaction(any());
+
+        return service;
+    }
+
+    /**
+     * Overridden {@link ActivityStack} that tracks test metrics, such as the number of times a
+     * method is called. Note that its functionality depends on the implementations of the
+     * construction arguments.
+     */
+    protected static class TestActivityStack<T extends StackWindowController>
+            extends ActivityStack<T> {
+        private int mOnActivityRemovedFromStackCount = 0;
+        private T mContainerController;
+
+        static final int IS_TRANSLUCENT_UNSET = 0;
+        static final int IS_TRANSLUCENT_FALSE = 1;
+        static final int IS_TRANSLUCENT_TRUE = 2;
+        private int mIsTranslucent = IS_TRANSLUCENT_UNSET;
+
+        static final int SUPPORTS_SPLIT_SCREEN_UNSET = 0;
+        static final int SUPPORTS_SPLIT_SCREEN_FALSE = 1;
+        static final int SUPPORTS_SPLIT_SCREEN_TRUE = 2;
+        private int mSupportsSplitScreen = SUPPORTS_SPLIT_SCREEN_UNSET;
+
+        TestActivityStack(ActivityDisplay display, int stackId, ActivityStackSupervisor supervisor,
+                int windowingMode, int activityType, boolean onTop) {
+            super(display, stackId, supervisor, windowingMode, activityType, onTop);
+        }
+
+        @Override
+        void onActivityRemovedFromStack(ActivityRecord r) {
+            mOnActivityRemovedFromStackCount++;
+            super.onActivityRemovedFromStack(r);
+        }
+
+        // Returns the number of times {@link #onActivityRemovedFromStack} has been called
+        int onActivityRemovedFromStackInvocationCount() {
+            return mOnActivityRemovedFromStackCount;
+        }
+
+        @Override
+        protected T createStackWindowController(int displayId, boolean onTop, Rect outBounds) {
+            mContainerController = (T) WindowTestUtils.createMockStackWindowContainerController();
+
+            // 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);
+            }
+            return mContainerController;
+        }
+
+        @Override
+        T getWindowContainerController() {
+            return mContainerController;
+        }
+
+        void setIsTranslucent(boolean isTranslucent) {
+            mIsTranslucent = isTranslucent ? IS_TRANSLUCENT_TRUE : IS_TRANSLUCENT_FALSE;
+        }
+
+        @Override
+        boolean isStackTranslucent(ActivityRecord starting) {
+            switch (mIsTranslucent) {
+                case IS_TRANSLUCENT_TRUE:
+                    return true;
+                case IS_TRANSLUCENT_FALSE:
+                    return false;
+                case IS_TRANSLUCENT_UNSET:
+                default:
+                    return super.isStackTranslucent(starting);
+            }
+        }
+
+        void setSupportsSplitScreen(boolean supportsSplitScreen) {
+            mSupportsSplitScreen = supportsSplitScreen
+                    ? SUPPORTS_SPLIT_SCREEN_TRUE : SUPPORTS_SPLIT_SCREEN_FALSE;
+        }
+
+        @Override
+        public boolean supportsSplitScreenWindowingMode() {
+            switch (mSupportsSplitScreen) {
+                case SUPPORTS_SPLIT_SCREEN_TRUE:
+                    return true;
+                case SUPPORTS_SPLIT_SCREEN_FALSE:
+                    return false;
+                case SUPPORTS_SPLIT_SCREEN_UNSET:
+                default:
+                    return super.supportsSplitScreenWindowingMode();
+            }
+        }
+
+        @Override
+        void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
+                                 boolean newTask, boolean keepCurTransition,
+                                 ActivityOptions options) {
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java b/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
new file mode 100644
index 0000000..3d11c4c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.content.Context;
+import android.os.Handler;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.server.AppOpsService;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+
+/**
+ * runtest -c com.android.server.am.AppErrorDialogTest frameworks-services
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class AppErrorDialogTest {
+
+    private Context mContext;
+    private ActivityManagerService mService;
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mService = new ActivityManagerService(new ActivityManagerService.Injector() {
+            @Override
+            public AppOpsService getAppOpsService(File file, Handler handler) {
+                return null;
+            }
+
+            @Override
+            public Handler getUiHandler(ActivityManagerService service) {
+                return null;
+            }
+
+            @Override
+            public boolean isNetworkRestrictedForUid(int uid) {
+                return false;
+            }
+        });
+    }
+
+    @Test
+    @UiThreadTest
+    public void testCreateWorks() throws Exception {
+        AppErrorDialog.Data data = new AppErrorDialog.Data();
+        data.proc = new ProcessRecord(null, null, mContext.getApplicationInfo(), "name", 12345);
+        data.result = new AppErrorResult();
+
+        AppErrorDialog dialog = new AppErrorDialog(mContext, mService, data);
+
+        dialog.create();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java b/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
new file mode 100644
index 0000000..ce88d84
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_ERRORED;
+import static android.app.AppOpsManager.OP_ASSIST_SCREENSHOT;
+import static android.app.AppOpsManager.OP_ASSIST_STRUCTURE;
+import static android.graphics.Bitmap.Config.ARGB_8888;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import android.app.AppOpsManager;
+import android.app.IActivityManager;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+import android.view.IWindowManager;
+
+import com.android.server.am.AssistDataRequester.AssistDataRequesterCallbacks;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Note: Currently, we only support fetching the screenshot for the current application, so the
+ * screenshot checks are hardcoded accordingly.
+ *
+ * runtest --path frameworks/base/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
+ */
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class AssistDataRequesterTest extends ActivityTestsBase {
+
+    private static final String TAG = AssistDataRequesterTest.class.getSimpleName();
+
+    private static final boolean CURRENT_ACTIVITY_ASSIST_ALLOWED = true;
+    private static final boolean CALLER_ASSIST_STRUCTURE_ALLOWED = true;
+    private static final boolean CALLER_ASSIST_SCREENSHOT_ALLOWED = true;
+    private static final boolean FETCH_DATA = true;
+    private static final boolean FETCH_SCREENSHOTS = true;
+    private static final boolean ALLOW_FETCH_DATA = true;
+    private static final boolean ALLOW_FETCH_SCREENSHOTS = true;
+
+    private static final int TEST_UID = 0;
+    private static final String TEST_PACKAGE = "";
+
+    private Context mContext;
+    private AssistDataRequester mDataRequester;
+    private Callbacks mCallbacks;
+    private Object mCallbacksLock;
+    private Handler mHandler;
+    private IActivityManager mAm;
+    private IWindowManager mWm;
+    private AppOpsManager mAppOpsManager;
+
+    /**
+     * The requests to fetch assist data are done incrementally from the text thread, and we
+     * immediately post onto the main thread handler below, which would immediately make the
+     * callback and decrement the pending counts. In order to assert the pending counts, we defer
+     * the callbacks on the test-side until after we flip the gate, after which we can drain the
+     * main thread handler and make assertions on the actual callbacks
+     */
+    private CountDownLatch mGate;
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mAm = mock(IActivityManager.class);
+        mWm = mock(IWindowManager.class);
+        mAppOpsManager = mock(AppOpsManager.class);
+        mContext =  InstrumentationRegistry.getContext();
+        mHandler = new Handler(Looper.getMainLooper());
+        mCallbacksLock = new Object();
+        mCallbacks = new Callbacks();
+        mDataRequester = new AssistDataRequester(mContext, mAm, mWm, mAppOpsManager, mCallbacks,
+                mCallbacksLock, OP_ASSIST_STRUCTURE, OP_ASSIST_SCREENSHOT);
+
+        // Gate the continuation of the assist data callbacks until we are ready within the tests
+        mGate = new CountDownLatch(1);
+        doAnswer(invocation -> {
+            mHandler.post(() -> {
+                try {
+                    mGate.await(10, TimeUnit.SECONDS);
+                    mDataRequester.onHandleAssistData(new Bundle());
+                } catch (InterruptedException e) {
+                    Log.e(TAG, "Failed to wait", e);
+                }
+            });
+            return true;
+        }).when(mAm).requestAssistContextExtras(anyInt(), any(), any(), any(), anyBoolean(),
+                anyBoolean());
+        doAnswer(invocation -> {
+            mHandler.post(() -> {
+                try {
+                    mGate.await(10, TimeUnit.SECONDS);
+                    mDataRequester.onHandleAssistScreenshot(Bitmap.createBitmap(1, 1, ARGB_8888));
+                } catch (InterruptedException e) {
+                    Log.e(TAG, "Failed to wait", e);
+                }
+            });
+            return true;
+        }).when(mWm).requestAssistScreenshot(any());
+    }
+
+    private void setupMocks(boolean currentActivityAssistAllowed, boolean assistStructureAllowed,
+            boolean assistScreenshotAllowed) throws Exception {
+        doReturn(currentActivityAssistAllowed).when(mAm).isAssistDataAllowedOnCurrentActivity();
+        doReturn(assistStructureAllowed ? MODE_ALLOWED : MODE_ERRORED).when(mAppOpsManager)
+                .checkOpNoThrow(eq(OP_ASSIST_STRUCTURE), anyInt(), anyString());
+        doReturn(assistScreenshotAllowed ? MODE_ALLOWED : MODE_ERRORED).when(mAppOpsManager)
+                .checkOpNoThrow(eq(OP_ASSIST_SCREENSHOT), anyInt(), anyString());
+    }
+
+    @Test
+    public void testRequestData() throws Exception {
+        setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
+                CALLER_ASSIST_SCREENSHOT_ALLOWED);
+
+        mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, FETCH_SCREENSHOTS,
+                ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE);
+        assertReceivedDataCount(5, 5, 1, 1);
+    }
+
+    @Test
+    public void testEmptyActivities_expectNoCallbacks() throws Exception {
+        setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
+                CALLER_ASSIST_SCREENSHOT_ALLOWED);
+
+        mDataRequester.requestAssistData(createActivityList(0), FETCH_DATA, FETCH_SCREENSHOTS,
+                ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE);
+        assertReceivedDataCount(0, 0, 0, 0);
+    }
+
+    @Test
+    public void testCurrentAppDisallow_expectNullCallbacks() throws Exception {
+        setupMocks(!CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
+                CALLER_ASSIST_SCREENSHOT_ALLOWED);
+
+        mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, FETCH_SCREENSHOTS,
+                ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE);
+        assertReceivedDataCount(0, 1, 0, 1);
+    }
+
+    @Test
+    public void testProcessPendingData() throws Exception {
+        setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
+                CALLER_ASSIST_SCREENSHOT_ALLOWED);
+
+        mCallbacks.canHandleReceivedData = false;
+        mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, FETCH_SCREENSHOTS,
+                ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE);
+        assertTrue(mDataRequester.getPendingDataCount() == 5);
+        assertTrue(mDataRequester.getPendingScreenshotCount() == 1);
+        mGate.countDown();
+        waitForIdle(mHandler);
+
+        // Callbacks still not ready to receive, but all pending data is received
+        assertTrue(mDataRequester.getPendingDataCount() == 0);
+        assertTrue(mDataRequester.getPendingScreenshotCount() == 0);
+        assertTrue(mCallbacks.receivedData.isEmpty());
+        assertTrue(mCallbacks.receivedScreenshots.isEmpty());
+        assertFalse(mCallbacks.requestCompleted);
+
+        mCallbacks.canHandleReceivedData = true;
+        mDataRequester.processPendingAssistData();
+        // Since we are posting the callback for the request-complete, flush the handler as well
+        mGate.countDown();
+        waitForIdle(mHandler);
+        assertTrue(mCallbacks.receivedData.size() == 5);
+        assertTrue(mCallbacks.receivedScreenshots.size() == 1);
+        assertTrue(mCallbacks.requestCompleted);
+
+        // Clear the state and ensure that we only process pending data once
+        mCallbacks.reset();
+        mDataRequester.processPendingAssistData();
+        assertTrue(mCallbacks.receivedData.isEmpty());
+        assertTrue(mCallbacks.receivedScreenshots.isEmpty());
+    }
+
+    @Test
+    public void testNoFetchData_expectNoDataCallbacks() throws Exception {
+        setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
+                CALLER_ASSIST_SCREENSHOT_ALLOWED);
+
+        mDataRequester.requestAssistData(createActivityList(5), !FETCH_DATA, FETCH_SCREENSHOTS,
+                ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE);
+        assertReceivedDataCount(0, 0, 0, 1);
+    }
+
+    @Test
+    public void testDisallowAssistStructure_expectNullDataCallbacks() throws Exception {
+        setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, !CALLER_ASSIST_STRUCTURE_ALLOWED,
+                CALLER_ASSIST_SCREENSHOT_ALLOWED);
+
+        mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, FETCH_SCREENSHOTS,
+                ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE);
+        // Expect a single null data when the appops is denied
+        assertReceivedDataCount(0, 1, 0, 1);
+    }
+
+    @Test
+    public void testDisallowAssistContextExtras_expectNullDataCallbacks() throws Exception {
+        setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
+                CALLER_ASSIST_SCREENSHOT_ALLOWED);
+        doReturn(false).when(mAm).requestAssistContextExtras(anyInt(), any(), any(), any(),
+                anyBoolean(), anyBoolean());
+
+        mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, FETCH_SCREENSHOTS,
+                ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE);
+        // Expect a single null data when requestAssistContextExtras() fails
+        assertReceivedDataCount(0, 1, 0, 1);
+    }
+
+    @Test
+    public void testNoFetchScreenshots_expectNoScreenshotCallbacks() throws Exception {
+        setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
+                CALLER_ASSIST_SCREENSHOT_ALLOWED);
+
+        mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, !FETCH_SCREENSHOTS,
+                ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE);
+        assertReceivedDataCount(5, 5, 0, 0);
+    }
+
+    @Test
+    public void testDisallowAssistScreenshot_expectNullScreenshotCallback() throws Exception {
+        setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
+                !CALLER_ASSIST_SCREENSHOT_ALLOWED);
+
+        mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, FETCH_SCREENSHOTS,
+                ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE);
+        // Expect a single null screenshot when the appops is denied
+        assertReceivedDataCount(5, 5, 0, 1);
+    }
+
+    @Test
+    public void testCanNotHandleReceivedData_expectNoCallbacks() throws Exception {
+        setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, !CALLER_ASSIST_STRUCTURE_ALLOWED,
+                !CALLER_ASSIST_SCREENSHOT_ALLOWED);
+
+        mCallbacks.canHandleReceivedData = false;
+        mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, FETCH_SCREENSHOTS,
+                ALLOW_FETCH_DATA, ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE);
+        mGate.countDown();
+        waitForIdle(mHandler);
+        assertTrue(mCallbacks.receivedData.isEmpty());
+        assertTrue(mCallbacks.receivedScreenshots.isEmpty());
+    }
+
+    @Test
+    public void testRequestDataNoneAllowed_expectNullCallbacks() throws Exception {
+        setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
+                CALLER_ASSIST_SCREENSHOT_ALLOWED);
+
+        mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, FETCH_SCREENSHOTS,
+                !ALLOW_FETCH_DATA, !ALLOW_FETCH_SCREENSHOTS, TEST_UID, TEST_PACKAGE);
+        assertReceivedDataCount(0, 1, 0, 1);
+    }
+
+    private void assertReceivedDataCount(int numPendingData, int numReceivedData,
+            int numPendingScreenshots, int numReceivedScreenshots) throws Exception {
+        assertTrue("Expected " + numPendingData + " pending data, got "
+                        + mDataRequester.getPendingDataCount(),
+                mDataRequester.getPendingDataCount() == numPendingData);
+        assertTrue("Expected " + numPendingScreenshots + " pending screenshots, got "
+                        + mDataRequester.getPendingScreenshotCount(),
+                mDataRequester.getPendingScreenshotCount() == numPendingScreenshots);
+        assertFalse("Expected request NOT completed", mCallbacks.requestCompleted);
+        mGate.countDown();
+        waitForIdle(mHandler);
+        assertTrue("Expected " + numReceivedData + " data, received "
+                        + mCallbacks.receivedData.size(),
+                mCallbacks.receivedData.size() == numReceivedData);
+        assertTrue("Expected " + numReceivedScreenshots + " screenshots, received "
+                        + mCallbacks.receivedScreenshots.size(),
+                mCallbacks.receivedScreenshots.size() == numReceivedScreenshots);
+        assertTrue("Expected request completed", mCallbacks.requestCompleted);
+    }
+
+    private List<IBinder> createActivityList(int size) {
+        ArrayList<IBinder> activities = new ArrayList<>();
+        for (int i = 0; i < size; i++) {
+            activities.add(mock(IBinder.class));
+        }
+        return activities;
+    }
+
+    public void waitForIdle(Handler h) throws Exception {
+        if (Looper.myLooper() == h.getLooper()) {
+            throw new RuntimeException("This method can not be called from the waiting looper");
+        }
+        CountDownLatch latch = new CountDownLatch(1);
+        h.post(() -> latch.countDown());
+        latch.await(2, TimeUnit.SECONDS);
+    }
+
+    private class Callbacks implements AssistDataRequesterCallbacks {
+
+        boolean canHandleReceivedData = true;
+        boolean requestCompleted = false;
+        ArrayList<Bundle> receivedData = new ArrayList<>();
+        ArrayList<Bitmap> receivedScreenshots = new ArrayList<>();
+
+        void reset() {
+            canHandleReceivedData = true;
+            receivedData.clear();
+            receivedScreenshots.clear();
+        }
+
+        @Override
+        public boolean canHandleReceivedAssistDataLocked() {
+            return canHandleReceivedData;
+        }
+
+        @Override
+        public void onAssistDataReceivedLocked(Bundle data, int activityIndex, int activityCount) {
+            receivedData.add(data);
+        }
+
+        @Override
+        public void onAssistScreenshotReceivedLocked(Bitmap screenshot) {
+            receivedScreenshots.add(screenshot);
+        }
+
+        @Override
+        public void onAssistRequestCompleted() {
+            mHandler.post(() -> {
+                try {
+                    mGate.await(10, TimeUnit.SECONDS);
+                    requestCompleted = true;
+                } catch (InterruptedException e) {
+                    Log.e(TAG, "Failed to wait", e);
+                }
+            });
+        }
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/am/ClientLifecycleManagerTests.java b/services/tests/servicestests/src/com/android/server/am/ClientLifecycleManagerTests.java
new file mode 100644
index 0000000..ef6d5e8
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/ClientLifecycleManagerTests.java
@@ -0,0 +1,44 @@
+package com.android.server.am;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.app.IApplicationThread;
+import android.app.servertransaction.ClientTransaction;
+import android.os.Binder;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class ClientLifecycleManagerTests {
+
+    @Test
+    public void testScheduleAndRecycleBinderClientTransaction() throws Exception {
+        ClientTransaction item = spy(ClientTransaction.obtain(mock(IApplicationThread.class),
+                new Binder()));
+
+        ClientLifecycleManager clientLifecycleManager = new ClientLifecycleManager();
+        clientLifecycleManager.scheduleTransaction(item);
+
+        verify(item, times(1)).recycle();
+    }
+
+    @Test
+    public void testScheduleNoRecycleNonBinderClientTransaction() throws Exception {
+        ClientTransaction item = spy(ClientTransaction.obtain(mock(IApplicationThread.Stub.class),
+                new Binder()));
+
+        ClientLifecycleManager clientLifecycleManager = new ClientLifecycleManager();
+        clientLifecycleManager.scheduleTransaction(item);
+
+        verify(item, times(0)).recycle();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java b/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
new file mode 100644
index 0000000..da30c11
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import static com.android.server.am.ActivityManagerService.Injector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.mock.MockContentResolver;
+
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.server.AppOpsService;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.File;
+
+/**
+ * Test class for {@link CoreSettingsObserver}.
+ *
+ * To run the tests, use
+ *
+ * runtest -c com.android.server.am.CoreSettingsObserverTest frameworks-services
+ *
+ * or the following steps:
+ *
+ * Build: m FrameworksServicesTests
+ * Install: adb install -r \
+ *     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
+ * Run: adb shell am instrument -e class com.android.server.am.CoreSettingsObserverTest -w \
+ *     com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class CoreSettingsObserverTest {
+    private static final String TEST_SETTING_SECURE_INT = "secureInt";
+    private static final String TEST_SETTING_GLOBAL_FLOAT = "globalFloat";
+    private static final String TEST_SETTING_SYSTEM_STRING = "systemString";
+
+    private static final int TEST_INT = 111;
+    private static final float TEST_FLOAT = 3.14f;
+    private static final String TEST_STRING = "testString";
+
+    private ActivityManagerService mAms;
+    @Mock private Context mContext;
+
+    private MockContentResolver mContentResolver;
+    private CoreSettingsObserver mCoreSettingsObserver;
+
+    @BeforeClass
+    public static void setupOnce() {
+        FakeSettingsProvider.clearSettingsProvider();
+        CoreSettingsObserver.sSecureSettingToTypeMap.put(TEST_SETTING_SECURE_INT, int.class);
+        CoreSettingsObserver.sGlobalSettingToTypeMap.put(TEST_SETTING_GLOBAL_FLOAT, float.class);
+        CoreSettingsObserver.sSystemSettingToTypeMap.put(TEST_SETTING_SYSTEM_STRING, String.class);
+    }
+
+    @AfterClass
+    public static void tearDownOnce() {
+        FakeSettingsProvider.clearSettingsProvider();
+    }
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        final Context originalContext = InstrumentationRegistry.getContext();
+        when(mContext.getApplicationInfo()).thenReturn(originalContext.getApplicationInfo());
+        mContentResolver = new MockContentResolver(mContext);
+        mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        when(mContext.getContentResolver()).thenReturn(mContentResolver);
+
+        mAms = new ActivityManagerService(new TestInjector());
+        mCoreSettingsObserver = new CoreSettingsObserver(mAms);
+    }
+
+    @Test
+    public void testPopulateSettings() {
+        Settings.Secure.putInt(mContentResolver, TEST_SETTING_SECURE_INT, TEST_INT);
+        Settings.Global.putFloat(mContentResolver, TEST_SETTING_GLOBAL_FLOAT, TEST_FLOAT);
+        Settings.System.putString(mContentResolver, TEST_SETTING_SYSTEM_STRING, TEST_STRING);
+
+        final Bundle settingsBundle = getPopulatedBundle();
+
+        assertEquals("Unexpected value of " + TEST_SETTING_SECURE_INT,
+                TEST_INT, settingsBundle.getInt(TEST_SETTING_SECURE_INT));
+        assertEquals("Unexpected value of " + TEST_SETTING_GLOBAL_FLOAT,
+                TEST_FLOAT, settingsBundle.getFloat(TEST_SETTING_GLOBAL_FLOAT), 0);
+        assertEquals("Unexpected value of " + TEST_SETTING_SYSTEM_STRING,
+                TEST_STRING, settingsBundle.getString(TEST_SETTING_SYSTEM_STRING));
+    }
+
+    @Test
+    public void testPopulateSettings_settingNotSet() {
+        final Bundle settingsBundle = getPopulatedBundle();
+
+        assertFalse("Bundle should not contain " + TEST_SETTING_SECURE_INT,
+                settingsBundle.containsKey(TEST_SETTING_SECURE_INT));
+        assertFalse("Bundle should not contain " + TEST_SETTING_GLOBAL_FLOAT,
+                settingsBundle.containsKey(TEST_SETTING_GLOBAL_FLOAT));
+        assertFalse("Bundle should not contain " + TEST_SETTING_SYSTEM_STRING,
+                settingsBundle.containsKey(TEST_SETTING_SYSTEM_STRING));
+    }
+
+    private Bundle getPopulatedBundle() {
+        final Bundle settingsBundle = new Bundle();
+        mCoreSettingsObserver.populateSettings(settingsBundle,
+                CoreSettingsObserver.sGlobalSettingToTypeMap);
+        mCoreSettingsObserver.populateSettings(settingsBundle,
+                CoreSettingsObserver.sSecureSettingToTypeMap);
+        mCoreSettingsObserver.populateSettings(settingsBundle,
+                CoreSettingsObserver.sSystemSettingToTypeMap);
+        return settingsBundle;
+    }
+
+    private class TestInjector extends Injector {
+        @Override
+        public Context getContext() {
+            return mContext;
+        }
+
+        public AppOpsService getAppOpsService(File file, Handler handler) {
+            return null;
+        }
+
+        @Override
+        public Handler getUiHandler(ActivityManagerService service) {
+            return null;
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/GlobalSettingsToPropertiesMapperTest.java b/services/tests/servicestests/src/com/android/server/am/GlobalSettingsToPropertiesMapperTest.java
new file mode 100644
index 0000000..d9b3e1c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/GlobalSettingsToPropertiesMapperTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import android.content.ContentResolver;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.mock.MockContentResolver;
+
+import com.android.internal.util.Preconditions;
+import com.android.internal.util.test.FakeSettingsProvider;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Tests for {@link GlobalSettingsToPropertiesMapper}
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class GlobalSettingsToPropertiesMapperTest {
+    private static final String[][] TEST_MAPPING = new String[][] {
+        {Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS, "TestProperty"}
+    };
+
+    private TestMapper mTestMapper;
+    private MockContentResolver mMockContentResolver;
+
+    @Before
+    public void setup() {
+        // Use FakeSettingsProvider to not affect global state
+        mMockContentResolver = new MockContentResolver(InstrumentationRegistry.getContext());
+        mMockContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        mTestMapper = new TestMapper(mMockContentResolver);
+    }
+
+    @Test
+    public void testUpdatePropertiesFromGlobalSettings() {
+        Settings.Global.putString(mMockContentResolver,
+                Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS, "testValue");
+
+        mTestMapper.updatePropertiesFromGlobalSettings();
+        String propValue = mTestMapper.systemPropertiesGet("TestProperty");
+        Assert.assertEquals("testValue", propValue);
+
+        Settings.Global.putString(mMockContentResolver,
+                Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS, "testValue2");
+        mTestMapper.updatePropertyFromSetting(Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS,
+                "TestProperty");
+        propValue = mTestMapper.systemPropertiesGet("TestProperty");
+        Assert.assertEquals("testValue2", propValue);
+
+        Settings.Global.putString(mMockContentResolver,
+                Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS, null);
+        mTestMapper.updatePropertyFromSetting(Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS,
+                "TestProperty");
+        propValue = mTestMapper.systemPropertiesGet("TestProperty");
+        Assert.assertEquals("", propValue);
+    }
+
+    @Test
+    public void testUpdatePropertiesFromGlobalSettings_PropertyAndSettingNotPresent() {
+        // Test that empty property will not not be set if setting is not set
+        mTestMapper.updatePropertiesFromGlobalSettings();
+        String propValue = mTestMapper.systemPropertiesGet("TestProperty");
+        Assert.assertNull("Property should not be set if setting is null", propValue);
+    }
+
+    private static class TestMapper extends GlobalSettingsToPropertiesMapper {
+        private final Map<String, String> mProps = new HashMap<>();
+
+        TestMapper(ContentResolver contentResolver) {
+            super(contentResolver, TEST_MAPPING);
+        }
+
+        @Override
+        protected String systemPropertiesGet(String key) {
+            Preconditions.checkNotNull(key);
+            return mProps.get(key);
+        }
+
+        @Override
+        protected void systemPropertiesSet(String key, String value) {
+            Preconditions.checkNotNull(value);
+            Preconditions.checkNotNull(key);
+            mProps.put(key, value);
+        }
+    }
+
+}
+
diff --git a/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java b/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java
new file mode 100644
index 0000000..161c287
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import android.app.ActivityOptions;
+import android.content.pm.ActivityInfo.WindowLayout;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.server.am.LaunchParamsController.LaunchParams;
+import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.android.server.am.LaunchParamsController.LaunchParamsModifier;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
+import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
+import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+/**
+ * Tests for exercising {@link LaunchParamsController}.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:LaunchParamsControllerTests
+ */
+@MediumTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class LaunchParamsControllerTests extends ActivityTestsBase {
+    private ActivityManagerService mService;
+    private LaunchParamsController mController;
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mService = createActivityManagerService();
+        mController = new LaunchParamsController(mService);
+    }
+
+    /**
+     * Makes sure positioners get values passed to controller.
+     */
+    @Test
+    public void testArgumentPropagation() {
+        final LaunchParamsModifier
+                positioner = mock(LaunchParamsModifier.class);
+        mController.registerModifier(positioner);
+
+        final ActivityRecord record = new ActivityBuilder(mService).build();
+        final ActivityRecord source = new ActivityBuilder(mService).build();
+        final WindowLayout layout = new WindowLayout(0, 0, 0, 0, 0, 0, 0);
+        final ActivityOptions options = mock(ActivityOptions.class);
+
+        mController.calculate(record.getTask(), layout, record, source, options,
+                new LaunchParams());
+        verify(positioner, times(1)).onCalculate(eq(record.getTask()), eq(layout), eq(record),
+                eq(source), eq(options), any(), any());
+    }
+
+    /**
+     * Ensures positioners further down the chain are not called when RESULT_DONE is returned.
+     */
+    @Test
+    public void testEarlyExit() {
+        final LaunchParamsModifier
+                ignoredPositioner = mock(LaunchParamsModifier.class);
+        final LaunchParamsModifier earlyExitPositioner =
+                (task, layout, activity, source, options, currentParams, outParams) -> RESULT_DONE;
+
+        mController.registerModifier(ignoredPositioner);
+        mController.registerModifier(earlyExitPositioner);
+
+        mController.calculate(null /*task*/, null /*layout*/, null /*activity*/,
+                null /*source*/, null /*options*/, new LaunchParams());
+        verify(ignoredPositioner, never()).onCalculate(any(), any(), any(), any(), any(),
+                any(), any());
+    }
+
+    /**
+     * Ensures that positioners are called in the correct order.
+     */
+    @Test
+    public void testRegistration() {
+        LaunchParamsModifier earlyExitPositioner =
+                new InstrumentedPositioner(RESULT_DONE, new LaunchParams());
+
+        final LaunchParamsModifier firstPositioner = spy(earlyExitPositioner);
+
+        mController.registerModifier(firstPositioner);
+
+        mController.calculate(null /*task*/, null /*layout*/, null /*activity*/,
+                null /*source*/, null /*options*/, new LaunchParams());
+        verify(firstPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), any(),
+                any());
+
+        final LaunchParamsModifier secondPositioner = spy(earlyExitPositioner);
+
+        mController.registerModifier(secondPositioner);
+
+        mController.calculate(null /*task*/, null /*layout*/, null /*activity*/,
+                null /*source*/, null /*options*/, new LaunchParams());
+        verify(firstPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), any(),
+                any());
+        verify(secondPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), any(),
+                any());
+    }
+
+    /**
+     * Makes sure positioners further down the registration chain are called.
+     */
+    @Test
+    public void testPassThrough() {
+        final LaunchParamsModifier
+                positioner1 = mock(LaunchParamsModifier.class);
+        final LaunchParams params = new LaunchParams();
+        params.mWindowingMode = WINDOWING_MODE_FREEFORM;
+        params.mBounds.set(0, 0, 30, 20);
+        params.mPreferredDisplayId = 3;
+
+        final InstrumentedPositioner positioner2 = new InstrumentedPositioner(RESULT_CONTINUE,
+                params);
+
+        mController.registerModifier(positioner1);
+        mController.registerModifier(positioner2);
+
+        mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/,
+                null /*options*/, new LaunchParams());
+
+        verify(positioner1, times(1)).onCalculate(any(), any(), any(), any(), any(),
+                eq(positioner2.getLaunchParams()), any());
+    }
+
+    /**
+     * Ensures skipped results are not propagated.
+     */
+    @Test
+    public void testSkip() {
+        final LaunchParams params1 = new LaunchParams();
+        params1.mBounds.set(0, 0, 10, 10);
+        final InstrumentedPositioner positioner1 = new InstrumentedPositioner(RESULT_SKIP, params1);
+
+        final LaunchParams params2 = new LaunchParams();
+        params2.mBounds.set(0, 0, 20, 30);
+        final InstrumentedPositioner positioner2 =
+                new InstrumentedPositioner(RESULT_CONTINUE, params2);
+
+        mController.registerModifier(positioner1);
+        mController.registerModifier(positioner2);
+
+        final LaunchParams
+                result = new LaunchParams();
+
+        mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/,
+                null /*options*/, result);
+
+        assertEquals(result, positioner2.getLaunchParams());
+    }
+
+    /**
+     * Ensures that {@link LaunchParamsModifier} requests specifying display id during
+     * layout are honored.
+     */
+    @Test
+    public void testLayoutTaskPreferredDisplayChange() {
+        final LaunchParams params = new LaunchParams();
+        params.mPreferredDisplayId = 2;
+        final InstrumentedPositioner positioner = new InstrumentedPositioner(RESULT_DONE, params);
+        final TaskRecord task = new TaskBuilder(mService.mStackSupervisor).build();
+
+        mController.registerModifier(positioner);
+
+        doNothing().when(mService).moveStackToDisplay(anyInt(), anyInt());
+        mController.layoutTask(task, null /* windowLayout */);
+        verify(mService, times(1)).moveStackToDisplay(eq(task.getStackId()),
+                eq(params.mPreferredDisplayId));
+    }
+
+    /**
+     * Ensures that {@link LaunchParamsModifier} requests specifying windowingMode during
+     * layout are honored.
+     */
+    @Test
+    public void testLayoutTaskWindowingModeChange() {
+        final LaunchParams params = new LaunchParams();
+        final int windowingMode = WINDOWING_MODE_FREEFORM;
+        params.mWindowingMode = windowingMode;
+        final InstrumentedPositioner positioner = new InstrumentedPositioner(RESULT_DONE, params);
+        final TaskRecord task = new TaskBuilder(mService.mStackSupervisor).build();
+
+        mController.registerModifier(positioner);
+
+        final int beforeWindowMode = task.getStack().getWindowingMode();
+        assertNotEquals(beforeWindowMode, windowingMode);
+
+        mController.layoutTask(task, null /* windowLayout */);
+
+        final int afterWindowMode = task.getStack().getWindowingMode();
+        assertEquals(afterWindowMode, windowingMode);
+    }
+
+    public static class InstrumentedPositioner implements
+            LaunchParamsModifier {
+
+        final private int mReturnVal;
+        final private LaunchParams mParams;
+
+        InstrumentedPositioner(int returnVal, LaunchParams params) {
+            mReturnVal = returnVal;
+            mParams = params;
+        }
+
+        @Override
+        public int onCalculate(TaskRecord task, WindowLayout layout, ActivityRecord activity,
+                   ActivityRecord source, ActivityOptions options,
+                   LaunchParams currentParams, LaunchParams outParams) {
+            outParams.set(mParams);
+            return mReturnVal;
+        }
+
+        LaunchParams getLaunchParams() {
+            return mParams;
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java b/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java
new file mode 100644
index 0000000..f46d712
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java
@@ -0,0 +1,680 @@
+/*
+ * Copyright 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
+import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
+import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
+import static android.app.StatusBarManager.DISABLE2_MASK;
+import static android.app.StatusBarManager.DISABLE2_NONE;
+import static android.app.StatusBarManager.DISABLE2_NOTIFICATION_SHADE;
+import static android.app.StatusBarManager.DISABLE_HOME;
+import static android.app.StatusBarManager.DISABLE_NOTIFICATION_ALERTS;
+import static android.app.StatusBarManager.DISABLE_NOTIFICATION_ICONS;
+import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_HOME;
+import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_KEYGUARD;
+import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_NONE;
+import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS;
+import static android.os.Process.SYSTEM_UID;
+import static android.telecom.TelecomManager.EMERGENCY_DIALER_COMPONENT;
+
+import static com.android.server.am.LockTaskController.STATUS_BAR_MASK_LOCKED;
+import static com.android.server.am.LockTaskController.STATUS_BAR_MASK_PINNED;
+
+import static org.junit.Assert.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import android.app.StatusBarManager;
+import android.app.admin.DevicePolicyManager;
+import android.app.admin.IDevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.telecom.TelecomManager;
+import android.testing.DexmakerShareClassLoaderRule;
+import android.util.Pair;
+
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.server.LocalServices;
+import com.android.server.statusbar.StatusBarManagerInternal;
+import com.android.server.wm.WindowManagerService;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.verification.VerificationMode;
+
+/**
+ * Unit tests for {@link LockTaskController}.
+ *
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.am.LockTaskControllerTest
+ */
+@Presubmit
+@SmallTest
+public class LockTaskControllerTest {
+    private static final String TEST_PACKAGE_NAME = "com.test.package";
+    private static final String TEST_PACKAGE_NAME_2 = "com.test.package2";
+    private static final String TEST_CLASS_NAME = ".TestClass";
+    private static final int TEST_USER_ID = 123;
+    private static final int TEST_UID = 10467;
+
+    @Rule
+    public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
+            new DexmakerShareClassLoaderRule();
+
+    @Mock private ActivityStackSupervisor mSupervisor;
+    @Mock private IDevicePolicyManager mDevicePolicyManager;
+    @Mock private IStatusBarService mStatusBarService;
+    @Mock private WindowManagerService mWindowManager;
+    @Mock private LockPatternUtils mLockPatternUtils;
+    @Mock private StatusBarManagerInternal mStatusBarManagerInternal;
+    @Mock private TelecomManager mTelecomManager;
+    @Mock private RecentTasks mRecentTasks;
+
+    private LockTaskController mLockTaskController;
+    private Context mContext;
+    private String mLockToAppSetting;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = InstrumentationRegistry.getTargetContext();
+        mLockToAppSetting = Settings.Secure.getString(mContext.getContentResolver(),
+                Settings.Secure.LOCK_TO_APP_EXIT_LOCKED);
+
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+
+        mSupervisor.mRecentTasks = mRecentTasks;
+
+        mLockTaskController = new LockTaskController(mContext, mSupervisor,
+                new ImmediatelyExecuteHandler());
+        mLockTaskController.setWindowManager(mWindowManager);
+        mLockTaskController.mStatusBarService = mStatusBarService;
+        mLockTaskController.mDevicePolicyManager = mDevicePolicyManager;
+        mLockTaskController.mTelecomManager = mTelecomManager;
+        mLockTaskController.mLockPatternUtils = mLockPatternUtils;
+
+        LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
+        LocalServices.addService(StatusBarManagerInternal.class, mStatusBarManagerInternal);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        Settings.Secure.putString(mContext.getContentResolver(),
+                Settings.Secure.LOCK_TO_APP_EXIT_LOCKED, mLockToAppSetting);
+    }
+
+    @Test
+    public void testPreconditions() {
+        // GIVEN nothing has happened
+
+        // THEN current lock task mode should be NONE
+        assertEquals(LOCK_TASK_MODE_NONE, mLockTaskController.getLockTaskModeState());
+    }
+
+    @Test
+    public void testStartLockTaskMode_once() throws Exception {
+        // GIVEN a task record with whitelisted auth
+        TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED);
+
+        // WHEN calling setLockTaskMode for LOCKED mode without resuming
+        mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
+
+        // THEN the lock task mode state should be LOCKED
+        assertEquals(LOCK_TASK_MODE_LOCKED, mLockTaskController.getLockTaskModeState());
+        // THEN the task should be locked
+        assertTrue(mLockTaskController.isTaskLocked(tr));
+
+        // THEN lock task mode should be started
+        verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED, DISABLE2_MASK);
+    }
+
+    @Test
+    public void testStartLockTaskMode_twice() throws Exception {
+        // GIVEN two task records with whitelisted auth
+        TaskRecord tr1 = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED);
+        TaskRecord tr2 = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED);
+
+        // WHEN calling setLockTaskMode for LOCKED mode on both tasks
+        mLockTaskController.startLockTaskMode(tr1, false, TEST_UID);
+        mLockTaskController.startLockTaskMode(tr2, false, TEST_UID);
+
+        // THEN the lock task mode state should be LOCKED
+        assertEquals(LOCK_TASK_MODE_LOCKED, mLockTaskController.getLockTaskModeState());
+        // THEN neither of the tasks should be able to move to back of stack
+        assertTrue(mLockTaskController.isTaskLocked(tr1));
+        assertTrue(mLockTaskController.isTaskLocked(tr2));
+
+        // THEN lock task mode should be started
+        verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED, DISABLE2_MASK);
+    }
+
+    @Test
+    public void testStartLockTaskMode_pinningRequest() throws Exception {
+        // GIVEN a task record that is not whitelisted, i.e. with pinned auth
+        TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_PINNABLE);
+
+        // WHEN calling startLockTaskMode
+        mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
+
+        // THEN a pinning request should be shown
+        verify(mStatusBarManagerInternal).showScreenPinningRequest(anyInt());
+    }
+
+    @Test
+    public void testStartLockTaskMode_pinnedBySystem() throws Exception {
+        // GIVEN a task record with pinned auth
+        TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_PINNABLE);
+
+        // WHEN the system calls startLockTaskMode
+        mLockTaskController.startLockTaskMode(tr, true, SYSTEM_UID);
+
+        // THEN the lock task mode state should be PINNED
+        assertEquals(LOCK_TASK_MODE_PINNED, mLockTaskController.getLockTaskModeState());
+        // THEN the task should be locked
+        assertTrue(mLockTaskController.isTaskLocked(tr));
+
+        // THEN lock task mode should be started
+        verifyLockTaskStarted(STATUS_BAR_MASK_PINNED, DISABLE2_NONE);
+        // THEN screen pinning toast should be shown
+        verify(mStatusBarService).showPinningEnterExitToast(true /* entering */);
+    }
+
+    @Test
+    public void testLockTaskViolation() throws Exception {
+        // GIVEN one task record with whitelisted auth that is in lock task mode
+        TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED);
+        mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
+
+        // THEN it's not a lock task violation to try and launch this task without clearing
+        assertFalse(mLockTaskController.isLockTaskModeViolation(tr, false));
+
+        // THEN it's a lock task violation to launch another task that is not whitelisted
+        assertTrue(mLockTaskController.isLockTaskModeViolation(getTaskRecord(
+                TaskRecord.LOCK_TASK_AUTH_PINNABLE)));
+        // THEN it's a lock task violation to launch another task that is disallowed from lock task
+        assertTrue(mLockTaskController.isLockTaskModeViolation(getTaskRecord(
+                TaskRecord.LOCK_TASK_AUTH_DONT_LOCK)));
+
+        // THEN it's no a lock task violation to launch another task that is whitelisted
+        assertFalse(mLockTaskController.isLockTaskModeViolation(getTaskRecord(
+                TaskRecord.LOCK_TASK_AUTH_WHITELISTED)));
+        assertFalse(mLockTaskController.isLockTaskModeViolation(getTaskRecord(
+                TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE)));
+        // THEN it's not a lock task violation to launch another task that is priv launchable
+        assertFalse(mLockTaskController.isLockTaskModeViolation(getTaskRecord(
+                TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV)));
+    }
+
+    @Test
+    public void testLockTaskViolation_emergencyCall() throws Exception {
+        // GIVEN one task record with whitelisted auth that is in lock task mode
+        TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED);
+        mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
+
+        // GIVEN tasks necessary for emergency calling
+        TaskRecord keypad = getTaskRecord(new Intent().setComponent(EMERGENCY_DIALER_COMPONENT),
+                TaskRecord.LOCK_TASK_AUTH_PINNABLE);
+        TaskRecord callAction = getTaskRecord(new Intent(Intent.ACTION_CALL_EMERGENCY),
+                TaskRecord.LOCK_TASK_AUTH_PINNABLE);
+        TaskRecord dialer = getTaskRecord("com.example.dialer", TaskRecord.LOCK_TASK_AUTH_PINNABLE);
+        when(mTelecomManager.getSystemDialerPackage())
+                .thenReturn(dialer.intent.getComponent().getPackageName());
+
+        // GIVEN keyguard is allowed for lock task mode
+        mLockTaskController.updateLockTaskFeatures(TEST_USER_ID, LOCK_TASK_FEATURE_KEYGUARD);
+
+        // THEN the above tasks should all be allowed
+        assertFalse(mLockTaskController.isLockTaskModeViolation(keypad));
+        assertFalse(mLockTaskController.isLockTaskModeViolation(callAction));
+        assertFalse(mLockTaskController.isLockTaskModeViolation(dialer));
+
+        // GIVEN keyguard is disallowed for lock task mode (default)
+        mLockTaskController.updateLockTaskFeatures(TEST_USER_ID, LOCK_TASK_FEATURE_NONE);
+
+        // THEN the above tasks should all be blocked
+        assertTrue(mLockTaskController.isLockTaskModeViolation(keypad));
+        assertTrue(mLockTaskController.isLockTaskModeViolation(callAction));
+        assertTrue(mLockTaskController.isLockTaskModeViolation(dialer));
+    }
+
+    @Test
+    public void testStopLockTaskMode() throws Exception {
+        // GIVEN one task record with whitelisted auth that is in lock task mode
+        TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED);
+        mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
+
+        // WHEN the same caller calls stopLockTaskMode
+        mLockTaskController.stopLockTaskMode(tr, false, TEST_UID);
+
+        // THEN the lock task mode should be NONE
+        assertEquals(LOCK_TASK_MODE_NONE, mLockTaskController.getLockTaskModeState());
+        // THEN the task should no longer be locked
+        assertFalse(mLockTaskController.isTaskLocked(tr));
+        // THEN lock task mode should have been finished
+        verifyLockTaskStopped(times(1));
+    }
+
+    @Test(expected = SecurityException.class)
+    public void testStopLockTaskMode_differentCaller() throws Exception {
+        // GIVEN one task record with whitelisted auth that is in lock task mode
+        TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED);
+        mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
+
+        // WHEN a different caller calls stopLockTaskMode
+        mLockTaskController.stopLockTaskMode(tr, false, TEST_UID + 1);
+
+        // THEN security exception should be thrown, because different caller tried to unlock
+    }
+
+    @Test
+    public void testStopLockTaskMode_systemCaller() throws Exception {
+        // GIVEN one task record with whitelisted auth that is in lock task mode
+        TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED);
+        mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
+
+        // WHEN system calls stopLockTaskMode
+        mLockTaskController.stopLockTaskMode(tr, true, SYSTEM_UID);
+
+        // THEN lock task mode should still be active
+        assertEquals(LOCK_TASK_MODE_LOCKED, mLockTaskController.getLockTaskModeState());
+    }
+
+    @Test
+    public void testStopLockTaskMode_twoTasks() throws Exception {
+        // GIVEN two task records with whitelisted auth that is in lock task mode
+        TaskRecord tr1 = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED);
+        TaskRecord tr2 = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED);
+        mLockTaskController.startLockTaskMode(tr1, false, TEST_UID);
+        mLockTaskController.startLockTaskMode(tr2, false, TEST_UID);
+
+        // WHEN calling stopLockTaskMode
+        mLockTaskController.stopLockTaskMode(tr2, false, TEST_UID);
+
+        // THEN the lock task mode should still be active
+        assertEquals(LOCK_TASK_MODE_LOCKED, mLockTaskController.getLockTaskModeState());
+        // THEN the first task should still be locked
+        assertTrue(mLockTaskController.isTaskLocked(tr1));
+        // THEN the top task should no longer be locked
+        assertFalse(mLockTaskController.isTaskLocked(tr2));
+        // THEN lock task mode should not have been finished
+        verifyLockTaskStopped(never());
+    }
+
+    @Test
+    public void testStopLockTaskMode_rootTask() throws Exception {
+        // GIVEN two task records with whitelisted auth that is in lock task mode
+        TaskRecord tr1 = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED);
+        TaskRecord tr2 = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED);
+        mLockTaskController.startLockTaskMode(tr1, false, TEST_UID);
+        mLockTaskController.startLockTaskMode(tr2, false, TEST_UID);
+
+        // WHEN calling stopLockTaskMode on the root task
+        mLockTaskController.stopLockTaskMode(tr1, false, TEST_UID);
+
+        // THEN the lock task mode should be inactive
+        assertEquals(LOCK_TASK_MODE_NONE, mLockTaskController.getLockTaskModeState());
+        // THEN the first task should no longer be locked
+        assertFalse(mLockTaskController.isTaskLocked(tr1));
+        // THEN the top task should no longer be locked
+        assertFalse(mLockTaskController.isTaskLocked(tr2));
+        // THEN lock task mode should be finished
+        verifyLockTaskStopped(times(1));
+    }
+
+    @Test
+    public void testStopLockTaskMode_pinned() throws Exception {
+        // GIVEN one task records that is in pinned mode
+        TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_PINNABLE);
+        mLockTaskController.startLockTaskMode(tr, true, SYSTEM_UID);
+        // GIVEN that the keyguard is required to show after unlocking
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.LOCK_TO_APP_EXIT_LOCKED, 1);
+
+        // reset invocation counter
+        reset(mStatusBarService);
+
+        // WHEN calling stopLockTask
+        mLockTaskController.stopLockTaskMode(null, true, SYSTEM_UID);
+
+        // THEN the lock task mode should no longer be active
+        assertEquals(LOCK_TASK_MODE_NONE, mLockTaskController.getLockTaskModeState());
+        // THEN the task should no longer be locked
+        assertFalse(mLockTaskController.isTaskLocked(tr));
+        // THEN lock task mode should have been finished
+        verifyLockTaskStopped(times(1));
+        // THEN the keyguard should be shown
+        verify(mLockPatternUtils).requireCredentialEntry(UserHandle.USER_ALL);
+        // THEN screen pinning toast should be shown
+        verify(mStatusBarService).showPinningEnterExitToast(false /* entering */);
+    }
+
+    @Test
+    public void testClearLockedTasks() throws Exception {
+        // GIVEN two task records with whitelisted auth that is in lock task mode
+        TaskRecord tr1 = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED);
+        TaskRecord tr2 = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED);
+        mLockTaskController.startLockTaskMode(tr1, false, TEST_UID);
+        mLockTaskController.startLockTaskMode(tr2, false, TEST_UID);
+
+        // WHEN calling stopLockTaskMode on the root task
+        mLockTaskController.clearLockedTasks("testClearLockedTasks");
+
+        // THEN the lock task mode should be inactive
+        assertEquals(LOCK_TASK_MODE_NONE, mLockTaskController.getLockTaskModeState());
+        // THEN the first task should no longer be locked
+        assertFalse(mLockTaskController.isTaskLocked(tr1));
+        // THEN the top task should no longer be locked
+        assertFalse(mLockTaskController.isTaskLocked(tr2));
+        // THEN lock task mode should be finished
+        verifyLockTaskStopped(times(1));
+    }
+
+    @Test
+    public void testUpdateLockTaskPackages() throws Exception {
+        String[] whitelist1 = {TEST_PACKAGE_NAME, TEST_PACKAGE_NAME_2};
+        String[] whitelist2 = {TEST_PACKAGE_NAME};
+
+        // No package is whitelisted initially
+        for (String pkg : whitelist1) {
+            assertFalse("Package shouldn't be whitelisted: " + pkg,
+                    mLockTaskController.isPackageWhitelisted(TEST_USER_ID, pkg));
+            assertFalse("Package shouldn't be whitelisted for user 0: " + pkg,
+                    mLockTaskController.isPackageWhitelisted(0, pkg));
+        }
+
+        // Apply whitelist
+        mLockTaskController.updateLockTaskPackages(TEST_USER_ID, whitelist1);
+
+        // Assert the whitelist is applied to the correct user
+        for (String pkg : whitelist1) {
+            assertTrue("Package should be whitelisted: " + pkg,
+                    mLockTaskController.isPackageWhitelisted(TEST_USER_ID, pkg));
+            assertFalse("Package shouldn't be whitelisted for user 0: " + pkg,
+                    mLockTaskController.isPackageWhitelisted(0, pkg));
+        }
+
+        // Update whitelist
+        mLockTaskController.updateLockTaskPackages(TEST_USER_ID, whitelist2);
+
+        // Assert the new whitelist is applied
+        assertTrue("Package should remain whitelisted: " + TEST_PACKAGE_NAME,
+                mLockTaskController.isPackageWhitelisted(TEST_USER_ID, TEST_PACKAGE_NAME));
+        assertFalse("Package should no longer be whitelisted: " + TEST_PACKAGE_NAME_2,
+                mLockTaskController.isPackageWhitelisted(TEST_USER_ID, TEST_PACKAGE_NAME_2));
+    }
+
+    @Test
+    public void testUpdateLockTaskPackages_taskRemoved() throws Exception {
+        // GIVEN two tasks which are whitelisted initially
+        TaskRecord tr1 = getTaskRecordForUpdate(TEST_PACKAGE_NAME, true);
+        TaskRecord tr2 = getTaskRecordForUpdate(TEST_PACKAGE_NAME_2, false);
+        String[] whitelist = {TEST_PACKAGE_NAME, TEST_PACKAGE_NAME_2};
+        mLockTaskController.updateLockTaskPackages(TEST_USER_ID, whitelist);
+
+        // GIVEN the tasks are launched into LockTask mode
+        mLockTaskController.startLockTaskMode(tr1, false, TEST_UID);
+        mLockTaskController.startLockTaskMode(tr2, false, TEST_UID);
+        assertEquals(LOCK_TASK_MODE_LOCKED, mLockTaskController.getLockTaskModeState());
+        assertTrue(mLockTaskController.isTaskLocked(tr1));
+        assertTrue(mLockTaskController.isTaskLocked(tr2));
+        verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED, DISABLE2_MASK);
+
+        // WHEN removing one package from whitelist
+        whitelist = new String[] {TEST_PACKAGE_NAME};
+        mLockTaskController.updateLockTaskPackages(TEST_USER_ID, whitelist);
+
+        // THEN the task running that package should be stopped
+        verify(tr2).performClearTaskLocked();
+        assertFalse(mLockTaskController.isTaskLocked(tr2));
+        // THEN the other task should remain locked
+        assertEquals(LOCK_TASK_MODE_LOCKED, mLockTaskController.getLockTaskModeState());
+        assertTrue(mLockTaskController.isTaskLocked(tr1));
+        verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED, DISABLE2_MASK);
+
+        // WHEN removing the last package from whitelist
+        whitelist = new String[] {};
+        mLockTaskController.updateLockTaskPackages(TEST_USER_ID, whitelist);
+
+        // THEN the last task should be cleared, and the system should quit LockTask mode
+        verify(tr1).performClearTaskLocked();
+        assertFalse(mLockTaskController.isTaskLocked(tr1));
+        assertEquals(LOCK_TASK_MODE_NONE, mLockTaskController.getLockTaskModeState());
+        verifyLockTaskStopped(times(1));
+    }
+
+    @Test
+    public void testUpdateLockTaskFeatures() throws Exception {
+        // GIVEN a locked task
+        TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED);
+        mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
+
+        // THEN lock task mode should be started with default status bar masks
+        verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED, DISABLE2_MASK);
+
+        // reset invocation counter
+        reset(mStatusBarService);
+
+        // WHEN home button is enabled for lock task mode
+        mLockTaskController.updateLockTaskFeatures(TEST_USER_ID, LOCK_TASK_FEATURE_HOME);
+
+        // THEN status bar should be updated to reflect this change
+        int expectedFlags = STATUS_BAR_MASK_LOCKED
+                & ~DISABLE_HOME;
+        int expectedFlags2 = DISABLE2_MASK;
+        verify(mStatusBarService).disable(eq(expectedFlags), any(IBinder.class),
+                eq(mContext.getPackageName()));
+        verify(mStatusBarService).disable2(eq(expectedFlags2), any(IBinder.class),
+                eq(mContext.getPackageName()));
+
+        // reset invocation counter
+        reset(mStatusBarService);
+
+        // WHEN notifications are enabled for lock task mode
+        mLockTaskController.updateLockTaskFeatures(TEST_USER_ID, LOCK_TASK_FEATURE_NOTIFICATIONS);
+
+        // THEN status bar should be updated to reflect this change
+        expectedFlags = STATUS_BAR_MASK_LOCKED
+                & ~DISABLE_NOTIFICATION_ICONS
+                & ~DISABLE_NOTIFICATION_ALERTS;
+        expectedFlags2 = DISABLE2_MASK
+                & ~DISABLE2_NOTIFICATION_SHADE;
+        verify(mStatusBarService).disable(eq(expectedFlags), any(IBinder.class),
+                eq(mContext.getPackageName()));
+        verify(mStatusBarService).disable2(eq(expectedFlags2), any(IBinder.class),
+                eq(mContext.getPackageName()));
+    }
+
+    @Test
+    public void testUpdateLockTaskFeatures_differentUser() throws Exception {
+        // GIVEN a locked task
+        TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED);
+        mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
+
+        // THEN lock task mode should be started with default status bar masks
+        verifyLockTaskStarted(STATUS_BAR_MASK_LOCKED, DISABLE2_MASK);
+
+        // reset invocation counter
+        reset(mStatusBarService);
+
+        // WHEN home button is enabled for lock task mode for another user
+        mLockTaskController.updateLockTaskFeatures(TEST_USER_ID + 1, LOCK_TASK_FEATURE_HOME);
+
+        // THEN status bar shouldn't change
+        verify(mStatusBarService, never()).disable(anyInt(), any(IBinder.class),
+                eq(mContext.getPackageName()));
+        verify(mStatusBarService, never()).disable2(anyInt(), any(IBinder.class),
+                eq(mContext.getPackageName()));
+    }
+
+    @Test
+    public void testUpdateLockTaskFeatures_keyguard() throws Exception {
+        // GIVEN a locked task
+        TaskRecord tr = getTaskRecord(TaskRecord.LOCK_TASK_AUTH_WHITELISTED);
+        mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
+
+        // THEN keyguard should be disabled
+        verify(mWindowManager).disableKeyguard(any(IBinder.class), anyString());
+
+        // WHEN keyguard is enabled for lock task mode
+        mLockTaskController.updateLockTaskFeatures(TEST_USER_ID, LOCK_TASK_FEATURE_KEYGUARD);
+
+        // THEN keyguard should be enabled
+        verify(mWindowManager).reenableKeyguard(any(IBinder.class));
+
+        // WHEN keyguard is disabled again for lock task mode
+        mLockTaskController.updateLockTaskFeatures(TEST_USER_ID, LOCK_TASK_FEATURE_NONE);
+
+        // THEN keyguard should be disabled
+        verify(mWindowManager, times(2)).disableKeyguard(any(IBinder.class), anyString());
+    }
+
+    @Test
+    public void testGetStatusBarDisableFlags() {
+        // Note that we don't enumerate all StatusBarManager flags, but only choose a subset to test
+
+        // WHEN nothing is enabled
+        Pair<Integer, Integer> flags = mLockTaskController.getStatusBarDisableFlags(
+                LOCK_TASK_FEATURE_NONE);
+        // THEN unsupported feature flags should still be untouched
+        assertTrue((~STATUS_BAR_MASK_LOCKED & flags.first) == 0);
+        // THEN everything else should be disabled
+        assertTrue((StatusBarManager.DISABLE_CLOCK & flags.first) != 0);
+        assertTrue((StatusBarManager.DISABLE2_QUICK_SETTINGS & flags.second) != 0);
+
+        // WHEN only home button is enabled
+        flags = mLockTaskController.getStatusBarDisableFlags(
+                LOCK_TASK_FEATURE_HOME);
+        // THEN unsupported feature flags should still be untouched
+        assertTrue((~STATUS_BAR_MASK_LOCKED & flags.first) == 0);
+        // THEN home button should indeed be enabled
+        assertTrue((StatusBarManager.DISABLE_HOME & flags.first) == 0);
+        // THEN other feature flags should remain disabled
+        assertTrue((StatusBarManager.DISABLE2_NOTIFICATION_SHADE & flags.second) != 0);
+
+        // WHEN only global actions menu and notifications are enabled
+        flags = mLockTaskController.getStatusBarDisableFlags(
+                DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS
+                        | DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS);
+        // THEN unsupported feature flags should still be untouched
+        assertTrue((~STATUS_BAR_MASK_LOCKED & flags.first) == 0);
+        // THEN notifications should be enabled
+        assertTrue((StatusBarManager.DISABLE_NOTIFICATION_ICONS & flags.first) == 0);
+        assertTrue((StatusBarManager.DISABLE_NOTIFICATION_ALERTS & flags.first) == 0);
+        assertTrue((StatusBarManager.DISABLE2_NOTIFICATION_SHADE & flags.second) == 0);
+        // THEN global actions should be enabled
+        assertTrue((StatusBarManager.DISABLE2_GLOBAL_ACTIONS & flags.second) == 0);
+        // THEN quick settings should still be disabled
+        assertTrue((StatusBarManager.DISABLE2_QUICK_SETTINGS & flags.second) != 0);
+    }
+
+    private TaskRecord getTaskRecord(int lockTaskAuth) {
+        return getTaskRecord(TEST_PACKAGE_NAME, lockTaskAuth);
+    }
+
+    private TaskRecord getTaskRecord(String pkg, int lockTaskAuth) {
+        final Intent intent = new Intent()
+                .setComponent(ComponentName.createRelative(pkg, TEST_CLASS_NAME));
+        return getTaskRecord(intent, lockTaskAuth);
+    }
+
+    private TaskRecord getTaskRecord(Intent intent, int lockTaskAuth) {
+        TaskRecord tr = mock(TaskRecord.class);
+        tr.mLockTaskAuth = lockTaskAuth;
+        tr.intent = intent;
+        tr.userId = TEST_USER_ID;
+        return tr;
+    }
+
+    /**
+     * @param isAppAware {@code true} if the app has marked if_whitelisted in its manifest
+     */
+    private TaskRecord getTaskRecordForUpdate(String pkg, boolean isAppAware) {
+        final int authIfWhitelisted = isAppAware
+                ? TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE
+                : TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
+        TaskRecord tr = getTaskRecord(pkg, authIfWhitelisted);
+        doAnswer((invocation) -> {
+            boolean isWhitelisted =
+                    mLockTaskController.isPackageWhitelisted(TEST_USER_ID, pkg);
+            tr.mLockTaskAuth = isWhitelisted
+                    ? authIfWhitelisted
+                    : TaskRecord.LOCK_TASK_AUTH_PINNABLE;
+            return null;
+        }).when(tr).setLockTaskAuth();
+        return tr;
+    }
+
+    private void verifyLockTaskStarted(int statusBarMask, int statusBarMask2) throws Exception {
+        // THEN the keyguard should have been disabled
+        verify(mWindowManager).disableKeyguard(any(IBinder.class), anyString());
+        // THEN the status bar should have been disabled
+        verify(mStatusBarService).disable(eq(statusBarMask), any(IBinder.class),
+                eq(mContext.getPackageName()));
+        verify(mStatusBarService).disable2(eq(statusBarMask2), any(IBinder.class),
+                eq(mContext.getPackageName()));
+        // THEN recents should have been notified
+        verify(mRecentTasks).onLockTaskModeStateChanged(anyInt(), eq(TEST_USER_ID));
+        // THEN the DO/PO should be informed about the operation
+        verify(mDevicePolicyManager).notifyLockTaskModeChanged(true, TEST_PACKAGE_NAME,
+                TEST_USER_ID);
+    }
+
+    private void verifyLockTaskStopped(VerificationMode mode) throws Exception {
+        // THEN the keyguard should have been disabled
+        verify(mWindowManager, mode).reenableKeyguard(any(IBinder.class));
+        // THEN the status bar should have been disabled
+        verify(mStatusBarService, mode).disable(eq(StatusBarManager.DISABLE_NONE),
+                any(IBinder.class), eq(mContext.getPackageName()));
+        verify(mStatusBarService, mode).disable2(eq(StatusBarManager.DISABLE2_NONE),
+                any(IBinder.class), eq(mContext.getPackageName()));
+        // THEN the DO/PO should be informed about the operation
+        verify(mDevicePolicyManager, mode).notifyLockTaskModeChanged(false, null, TEST_USER_ID);
+    }
+
+    /**
+     * Special handler implementation that executes any message / runnable posted immediately on the
+     * thread that it's posted on rather than enqueuing them on its looper.
+     */
+    private static class ImmediatelyExecuteHandler extends Handler {
+        @Override
+        public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
+            if (msg.getCallback() != null) {
+                msg.getCallback().run();
+            }
+            return true;
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java b/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java
new file mode 100644
index 0000000..5518ca5
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromMemcg;
+import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromProcfs;
+import static com.android.server.am.MemoryStatUtil.MemoryStat;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MemoryStatUtilTest {
+    private String MEMORY_STAT_CONTENTS = String.join(
+            "\n",
+            "cache 96", // keep different from total_cache to catch reading wrong value
+            "rss 97", // keep different from total_rss to catch reading wrong value
+            "rss_huge 0",
+            "mapped_file 524288",
+            "writeback 0",
+            "swap 95", // keep different from total_rss to catch reading wrong value
+            "pgpgin 16717",
+            "pgpgout 5037",
+            "pgfault 99", // keep different from total_pgfault to catch reading wrong value
+            "pgmajfault 98", // keep different from total_pgmajfault to catch reading wrong value
+            "inactive_anon 503808",
+            "active_anon 46309376",
+            "inactive_file 876544",
+            "active_file 81920",
+            "unevictable 0",
+            "hierarchical_memory_limit 18446744073709551615",
+            "hierarchical_memsw_limit 18446744073709551615",
+            "total_cache 4",
+            "total_rss 3",
+            "total_rss_huge 0",
+            "total_mapped_file 524288",
+            "total_writeback 0",
+            "total_swap 5",
+            "total_pgpgin 16717",
+            "total_pgpgout 5037",
+            "total_pgfault 1",
+            "total_pgmajfault 2",
+            "total_inactive_anon 503808",
+            "total_active_anon 46309376",
+            "total_inactive_file 876544",
+            "total_active_file 81920",
+            "total_unevictable 0");
+
+    private String PROC_STAT_CONTENTS = String.join(
+            " ",
+            "1040",
+            "(system_server)",
+            "S",
+            "544",
+            "544",
+            "0",
+            "0",
+            "-1",
+            "1077936448",
+            "1", // this is pgfault
+            "0",
+            "2", // this is pgmajfault
+            "0",
+            "44533",
+            "13471",
+            "0",
+            "0",
+            "18",
+            "-2",
+            "117",
+            "0",
+            "2206",
+            "1257177088",
+            "3", // this is rss in bytes
+            "4294967295",
+            "2936971264",
+            "2936991289",
+            "3198888320",
+            "3198879848",
+            "2903927664",
+            "0",
+            "4612",
+            "0",
+            "1073775864",
+            "4294967295",
+            "0",
+            "0",
+            "17",
+            "0",
+            "0",
+            "0",
+            "0",
+            "0",
+            "0",
+            "2936999088",
+            "2936999936",
+            "2958692352",
+            "3198888595",
+            "3198888671",
+            "3198888671",
+            "3198889956",
+            "0");
+
+    @Test
+    public void testParseMemoryStatFromMemcg_parsesCorrectValues() throws Exception {
+        MemoryStat stat = parseMemoryStatFromMemcg(MEMORY_STAT_CONTENTS);
+        assertEquals(stat.pgfault, 1);
+        assertEquals(stat.pgmajfault, 2);
+        assertEquals(stat.rssInBytes, 3);
+        assertEquals(stat.cacheInBytes, 4);
+        assertEquals(stat.swapInBytes, 5);
+    }
+
+    @Test
+    public void testParseMemoryStatFromMemcg_emptyMemoryStatContents() throws Exception {
+        MemoryStat stat = parseMemoryStatFromMemcg("");
+        assertNull(stat);
+
+        stat = parseMemoryStatFromMemcg(null);
+        assertNull(stat);
+    }
+
+    @Test
+    public void testParseMemoryStatFromProcfs_parsesCorrectValues() throws Exception {
+        MemoryStat stat = parseMemoryStatFromProcfs(PROC_STAT_CONTENTS);
+        assertEquals(1, stat.pgfault);
+        assertEquals(2, stat.pgmajfault);
+        assertEquals(3, stat.rssInBytes);
+        assertEquals(0, stat.cacheInBytes);
+        assertEquals(0, stat.swapInBytes);
+    }
+
+    @Test
+    public void testParseMemoryStatFromProcfs_emptyContents() throws Exception {
+        MemoryStat stat = parseMemoryStatFromProcfs("");
+        assertNull(stat);
+
+        stat = parseMemoryStatFromProcfs(null);
+        assertNull(stat);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java b/services/tests/servicestests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java
new file mode 100644
index 0000000..2baf995
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import android.annotation.Nullable;
+import android.app.ActivityOptions;
+import android.os.Handler;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.ArrayMap;
+import android.view.RemoteAnimationAdapter;
+
+import com.android.server.testutils.OffsettableClock;
+import com.android.server.testutils.TestHandler;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * atest PendingRemoteAnimationRegistryTest
+ */
+@SmallTest
+@Presubmit
+@FlakyTest
+@RunWith(AndroidJUnit4.class)
+public class PendingRemoteAnimationRegistryTest extends ActivityTestsBase {
+
+    @Mock RemoteAnimationAdapter mAdapter;
+    private PendingRemoteAnimationRegistry mRegistry;
+    private final OffsettableClock mClock = new OffsettableClock.Stopped();
+    private TestHandler mHandler;
+    private ActivityManagerService mService;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        MockitoAnnotations.initMocks(this);
+        mService = createActivityManagerService();
+        mService.mHandlerThread.getThreadHandler().runWithScissors(() -> {
+            mHandler = new TestHandler(null, mClock);
+        }, 0);
+        mRegistry = new PendingRemoteAnimationRegistry(mService, mHandler);
+    }
+
+    @Test
+    public void testOverrideActivityOptions() {
+        mRegistry.addPendingAnimation("com.android.test", mAdapter);
+        ActivityOptions opts = ActivityOptions.makeBasic();
+        opts = mRegistry.overrideOptionsIfNeeded("com.android.test", opts);
+        assertEquals(mAdapter, opts.getRemoteAnimationAdapter());
+    }
+
+    @Test
+    public void testOverrideActivityOptions_null() {
+        mRegistry.addPendingAnimation("com.android.test", mAdapter);
+        final ActivityOptions opts = mRegistry.overrideOptionsIfNeeded("com.android.test", null);
+        assertNotNull(opts);
+        assertEquals(mAdapter, opts.getRemoteAnimationAdapter());
+    }
+
+    @Test
+    public void testTimeout() {
+        mRegistry.addPendingAnimation("com.android.test", mAdapter);
+        mClock.fastForward(5000);
+        mHandler.timeAdvance();
+        assertNull(mRegistry.overrideOptionsIfNeeded("com.android.test", null));
+    }
+
+    @Test
+    public void testTimeout_overridenEntry() {
+        mRegistry.addPendingAnimation("com.android.test", mAdapter);
+        mClock.fastForward(2500);
+        mHandler.timeAdvance();
+        mRegistry.addPendingAnimation("com.android.test", mAdapter);
+        mClock.fastForward(1000);
+        mHandler.timeAdvance();
+        final ActivityOptions opts = mRegistry.overrideOptionsIfNeeded("com.android.test", null);
+        assertEquals(mAdapter, opts.getRemoteAnimationAdapter());
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java b/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java
new file mode 100644
index 0000000..54f93a8
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.am;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.admin.IDeviceAdminService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Pair;
+
+import org.mockito.ArgumentMatchers;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+
+@SmallTest
+public class PersistentConnectionTest extends AndroidTestCase {
+    private static class MyConnection extends PersistentConnection<IDeviceAdminService> {
+        public long uptimeMillis = 12345;
+
+        public ArrayList<Pair<Runnable, Long>> scheduledRunnables = new ArrayList<>();
+
+        public MyConnection(String tag, Context context, Handler handler, int userId,
+                ComponentName componentName, long rebindBackoffSeconds,
+                double rebindBackoffIncrease, long rebindMaxBackoffSeconds) {
+            super(tag, context, handler, userId, componentName,
+                    rebindBackoffSeconds, rebindBackoffIncrease, rebindMaxBackoffSeconds);
+        }
+
+        @Override
+        protected IDeviceAdminService asInterface(IBinder binder) {
+            return (IDeviceAdminService) binder;
+        }
+
+        @Override
+        long injectUptimeMillis() {
+            return uptimeMillis;
+        }
+
+        @Override
+        void injectPostAtTime(Runnable r, long uptimeMillis) {
+            scheduledRunnables.add(Pair.create(r, uptimeMillis));
+        }
+
+        @Override
+        void injectRemoveCallbacks(Runnable r) {
+            for (int i = scheduledRunnables.size() - 1; i >= 0; i--) {
+                if (scheduledRunnables.get(i).first.equals(r)) {
+                    scheduledRunnables.remove(i);
+                }
+            }
+        }
+
+        void elapse(long milliSeconds) {
+            uptimeMillis += milliSeconds;
+
+            // Fire the scheduled runnables.
+
+            // Note we collect first and then run all, because sometimes a scheduled runnable
+            // calls removeCallbacks.
+            final ArrayList<Runnable> list = new ArrayList<>();
+
+            for (int i = scheduledRunnables.size() - 1; i >= 0; i--) {
+                if (scheduledRunnables.get(i).second <= uptimeMillis) {
+                    list.add(scheduledRunnables.get(i).first);
+                    scheduledRunnables.remove(i);
+                }
+            }
+
+            Collections.reverse(list);
+            for (Runnable r : list) {
+                r.run();
+            }
+        }
+    }
+
+    public void testAll() {
+        final Context context = mock(Context.class);
+        final int userId = 11;
+        final ComponentName cn = ComponentName.unflattenFromString("a.b.c/def");
+        final Handler handler = new Handler(Looper.getMainLooper());
+
+        final MyConnection conn = new MyConnection("tag", context, handler, userId, cn,
+                /* rebindBackoffSeconds= */ 5,
+                /* rebindBackoffIncrease= */ 1.5,
+                /* rebindMaxBackoffSeconds= */ 11);
+
+        assertFalse(conn.isBound());
+        assertFalse(conn.isConnected());
+        assertFalse(conn.isRebindScheduled());
+        assertEquals(5000, conn.getNextBackoffMsForTest());
+        assertNull(conn.getServiceBinder());
+
+        when(context.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class), anyInt(),
+                any(Handler.class), any(UserHandle.class)))
+                .thenReturn(true);
+
+        // Call bind.
+        conn.bind();
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertFalse(conn.isRebindScheduled());
+        assertNull(conn.getServiceBinder());
+
+        assertEquals(5000, conn.getNextBackoffMsForTest());
+
+        verify(context).bindServiceAsUser(
+                ArgumentMatchers.argThat(intent -> cn.equals(intent.getComponent())),
+                eq(conn.getServiceConnectionForTest()),
+                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
+                eq(handler), eq(UserHandle.of(userId)));
+
+        // AM responds...
+        conn.getServiceConnectionForTest().onServiceConnected(cn,
+                new IDeviceAdminService.Stub() {});
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertTrue(conn.isConnected());
+        assertNotNull(conn.getServiceBinder());
+        assertFalse(conn.isRebindScheduled());
+
+        assertEquals(5000, conn.getNextBackoffMsForTest());
+
+
+        // Now connected.
+
+        // Call unbind...
+        conn.unbind();
+        assertFalse(conn.isBound());
+        assertFalse(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertNull(conn.getServiceBinder());
+        assertFalse(conn.isRebindScheduled());
+
+        // Caller bind again...
+        conn.bind();
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertFalse(conn.isRebindScheduled());
+        assertNull(conn.getServiceBinder());
+
+        assertEquals(5000, conn.getNextBackoffMsForTest());
+
+
+        // Now connected again.
+
+        // The service got killed...
+        conn.getServiceConnectionForTest().onServiceDisconnected(cn);
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertNull(conn.getServiceBinder());
+        assertFalse(conn.isRebindScheduled());
+
+        assertEquals(5000, conn.getNextBackoffMsForTest());
+
+        // Connected again...
+        conn.getServiceConnectionForTest().onServiceConnected(cn,
+                new IDeviceAdminService.Stub() {});
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertTrue(conn.isConnected());
+        assertNotNull(conn.getServiceBinder());
+        assertFalse(conn.isRebindScheduled());
+
+        assertEquals(5000, conn.getNextBackoffMsForTest());
+
+
+        // Then the binding is "died"...
+        conn.getServiceConnectionForTest().onBindingDied(cn);
+
+        assertFalse(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertNull(conn.getServiceBinder());
+        assertTrue(conn.isRebindScheduled());
+
+        assertEquals(7500, conn.getNextBackoffMsForTest());
+
+        assertEquals(
+                Arrays.asList(Pair.create(conn.getBindForBackoffRunnableForTest(),
+                        conn.uptimeMillis + 5000)),
+                conn.scheduledRunnables);
+
+        // 5000 ms later...
+        conn.elapse(5000);
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertNull(conn.getServiceBinder());
+        assertFalse(conn.isRebindScheduled());
+
+        assertEquals(7500, conn.getNextBackoffMsForTest());
+
+        // Connected.
+        conn.getServiceConnectionForTest().onServiceConnected(cn,
+                new IDeviceAdminService.Stub() {});
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertTrue(conn.isConnected());
+        assertNotNull(conn.getServiceBinder());
+        assertFalse(conn.isRebindScheduled());
+
+        assertEquals(7500, conn.getNextBackoffMsForTest());
+
+        // Then the binding is "died"...
+        conn.getServiceConnectionForTest().onBindingDied(cn);
+
+        assertFalse(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertNull(conn.getServiceBinder());
+        assertTrue(conn.isRebindScheduled());
+
+        assertEquals(11000, conn.getNextBackoffMsForTest());
+
+        assertEquals(
+                Arrays.asList(Pair.create(conn.getBindForBackoffRunnableForTest(),
+                        conn.uptimeMillis + 7500)),
+                conn.scheduledRunnables);
+
+        // Later...
+        conn.elapse(7500);
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertNull(conn.getServiceBinder());
+        assertFalse(conn.isRebindScheduled());
+
+        assertEquals(11000, conn.getNextBackoffMsForTest());
+
+
+        // Then the binding is "died"...
+        conn.getServiceConnectionForTest().onBindingDied(cn);
+
+        assertFalse(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertNull(conn.getServiceBinder());
+        assertTrue(conn.isRebindScheduled());
+
+        assertEquals(11000, conn.getNextBackoffMsForTest());
+
+        assertEquals(
+                Arrays.asList(Pair.create(conn.getBindForBackoffRunnableForTest(),
+                    conn.uptimeMillis + 11000)),
+                conn.scheduledRunnables);
+
+        // Call unbind...
+        conn.unbind();
+        assertFalse(conn.isBound());
+        assertFalse(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertNull(conn.getServiceBinder());
+        assertFalse(conn.isRebindScheduled());
+
+        // Call bind again... And now the backoff is reset to 5000.
+        conn.bind();
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertFalse(conn.isRebindScheduled());
+        assertNull(conn.getServiceBinder());
+
+        assertEquals(5000, conn.getNextBackoffMsForTest());
+    }
+
+    public void testReconnectFiresAfterUnbind() {
+        final Context context = mock(Context.class);
+        final int userId = 11;
+        final ComponentName cn = ComponentName.unflattenFromString("a.b.c/def");
+        final Handler handler = new Handler(Looper.getMainLooper());
+
+        final MyConnection conn = new MyConnection("tag", context, handler, userId, cn,
+                /* rebindBackoffSeconds= */ 5,
+                /* rebindBackoffIncrease= */ 1.5,
+                /* rebindMaxBackoffSeconds= */ 11);
+
+        when(context.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class), anyInt(),
+                any(Handler.class), any(UserHandle.class)))
+                .thenReturn(true);
+
+        // Bind.
+        conn.bind();
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isRebindScheduled());
+
+        conn.elapse(1000);
+
+        // Service crashes.
+        conn.getServiceConnectionForTest().onBindingDied(cn);
+
+        assertFalse(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertTrue(conn.isRebindScheduled());
+
+        assertEquals(7500, conn.getNextBackoffMsForTest());
+
+        // Call unbind.
+        conn.unbind();
+        assertFalse(conn.isBound());
+        assertFalse(conn.shouldBeBoundForTest());
+
+        // Now, at this point, it's possible that the scheduled runnable had already been fired
+        // before during the unbind() call, and waiting on mLock.
+        // To simulate it, we just call the runnable here.
+        conn.getBindForBackoffRunnableForTest().run();
+
+        // Should still not be bound.
+        assertFalse(conn.isBound());
+        assertFalse(conn.shouldBeBoundForTest());
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
new file mode 100644
index 0000000..b73ac89
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
@@ -0,0 +1,1026 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+
+import static java.lang.Integer.MAX_VALUE;
+
+import android.annotation.TestApi;
+import android.app.ActivityManager;
+import android.app.ActivityManager.RecentTaskInfo;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.WindowConfiguration;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.UserInfo;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.MutableLong;
+import android.util.SparseArray;
+import android.util.SparseBooleanArray;
+
+import com.android.server.am.RecentTasks.Callbacks;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+/**
+ * atest FrameworksServicesTests:RecentTasksTest
+ */
+@MediumTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class RecentTasksTest extends ActivityTestsBase {
+    private static final int TEST_USER_0_ID = 0;
+    private static final int TEST_USER_1_ID = 10;
+    private static final int TEST_QUIET_USER_ID = 20;
+    private static final UserInfo DEFAULT_USER_INFO = new UserInfo();
+    private static final UserInfo QUIET_USER_INFO = new UserInfo();
+    private static int LAST_TASK_ID = 1;
+    private static int LAST_STACK_ID = 1;
+    private static int INVALID_STACK_ID = 999;
+
+    private Context mContext = InstrumentationRegistry.getContext();
+    private ActivityManagerService mService;
+    private ActivityDisplay mDisplay;
+    private ActivityDisplay mOtherDisplay;
+    private ActivityStack mStack;
+    private ActivityStack mHomeStack;
+    private TestTaskPersister mTaskPersister;
+    private TestRecentTasks mRecentTasks;
+    private TestRunningTasks mRunningTasks;
+
+    private ArrayList<TaskRecord> mTasks;
+    private ArrayList<TaskRecord> mSameDocumentTasks;
+
+    private CallbacksRecorder mCallbacksRecorder;
+
+    class TestUserController extends UserController {
+        TestUserController(ActivityManagerService service) {
+            super(service);
+        }
+
+        @Override
+        int[] getCurrentProfileIds() {
+            return new int[] { TEST_USER_0_ID, TEST_QUIET_USER_ID };
+        }
+
+        @Override
+        Set<Integer> getProfileIds(int userId) {
+            Set<Integer> profileIds = new HashSet<>();
+            profileIds.add(TEST_USER_0_ID);
+            profileIds.add(TEST_QUIET_USER_ID);
+            return profileIds;
+        }
+
+        @Override
+        UserInfo getUserInfo(int userId) {
+            switch (userId) {
+                case TEST_USER_0_ID:
+                case TEST_USER_1_ID:
+                    return DEFAULT_USER_INFO;
+                case TEST_QUIET_USER_ID:
+                    return QUIET_USER_INFO;
+            }
+            return null;
+        }
+    }
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mTaskPersister = new TestTaskPersister(mContext.getFilesDir());
+        mService = setupActivityManagerService(new MyTestActivityManagerService(mContext));
+        mRecentTasks = (TestRecentTasks) mService.getRecentTasks();
+        mRecentTasks.loadParametersFromResources(mContext.getResources());
+        mHomeStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
+        mStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        ((MyTestActivityStackSupervisor) mService.mStackSupervisor).setHomeStack(mHomeStack);
+        mCallbacksRecorder = new CallbacksRecorder();
+        mRecentTasks.registerCallback(mCallbacksRecorder);
+        QUIET_USER_INFO.flags = UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_QUIET_MODE;
+
+        mTasks = new ArrayList<>();
+        mTasks.add(createTaskBuilder(".Task1").build());
+        mTasks.add(createTaskBuilder(".Task2").build());
+        mTasks.add(createTaskBuilder(".Task3").build());
+        mTasks.add(createTaskBuilder(".Task4").build());
+        mTasks.add(createTaskBuilder(".Task5").build());
+
+        mSameDocumentTasks = new ArrayList<>();
+        mSameDocumentTasks.add(createDocumentTask(".DocumentTask1"));
+        mSameDocumentTasks.add(createDocumentTask(".DocumentTask1"));
+    }
+
+    @Test
+    public void testCallbacks() throws Exception {
+        // Add some tasks
+        mRecentTasks.add(mTasks.get(0));
+        mRecentTasks.add(mTasks.get(1));
+        assertTrue(mCallbacksRecorder.added.contains(mTasks.get(0))
+                && mCallbacksRecorder.added.contains(mTasks.get(1)));
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.isEmpty());
+        mCallbacksRecorder.clear();
+
+        // Remove some tasks
+        mRecentTasks.remove(mTasks.get(0));
+        mRecentTasks.remove(mTasks.get(1));
+        assertTrue(mCallbacksRecorder.added.isEmpty());
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.contains(mTasks.get(0)));
+        assertTrue(mCallbacksRecorder.removed.contains(mTasks.get(1)));
+        mCallbacksRecorder.clear();
+
+        // Remove the callback, ensure we don't get any calls
+        mRecentTasks.unregisterCallback(mCallbacksRecorder);
+        mRecentTasks.add(mTasks.get(0));
+        mRecentTasks.remove(mTasks.get(0));
+        assertTrue(mCallbacksRecorder.added.isEmpty());
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.isEmpty());
+    }
+
+    @Test
+    public void testAddTasksNoMultiple_expectNoTrim() throws Exception {
+        // Add same non-multiple-task document tasks will remove the task (to re-add it) but not
+        // trim it
+        TaskRecord documentTask1 = createDocumentTask(".DocumentTask1");
+        TaskRecord documentTask2 = createDocumentTask(".DocumentTask1");
+        mRecentTasks.add(documentTask1);
+        mRecentTasks.add(documentTask2);
+        assertTrue(mCallbacksRecorder.added.contains(documentTask1));
+        assertTrue(mCallbacksRecorder.added.contains(documentTask2));
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.contains(documentTask1));
+    }
+
+    @Test
+    public void testAddTasksMaxTaskRecents_expectNoTrim() throws Exception {
+        // Add a task hitting max-recents for that app will remove the task (to add the next one)
+        // but not trim it
+        TaskRecord documentTask1 = createDocumentTask(".DocumentTask1");
+        TaskRecord documentTask2 = createDocumentTask(".DocumentTask1");
+        documentTask1.maxRecents = 1;
+        documentTask2.maxRecents = 1;
+        mRecentTasks.add(documentTask1);
+        mRecentTasks.add(documentTask2);
+        assertTrue(mCallbacksRecorder.added.contains(documentTask1));
+        assertTrue(mCallbacksRecorder.added.contains(documentTask2));
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.contains(documentTask1));
+    }
+
+    @Test
+    public void testAddTasksSameTask_expectNoTrim() throws Exception {
+        // Add a task that is already in the task list does not trigger any callbacks, it just
+        // moves in the list
+        TaskRecord documentTask1 = createDocumentTask(".DocumentTask1");
+        mRecentTasks.add(documentTask1);
+        mRecentTasks.add(documentTask1);
+        assertTrue(mCallbacksRecorder.added.size() == 1);
+        assertTrue(mCallbacksRecorder.added.contains(documentTask1));
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.isEmpty());
+    }
+
+    @Test
+    public void testAddTasksMultipleDocumentTasks_expectNoTrim() throws Exception {
+        // Add same multiple-task document tasks does not trim the first tasks
+        TaskRecord documentTask1 = createDocumentTask(".DocumentTask1",
+                FLAG_ACTIVITY_MULTIPLE_TASK);
+        TaskRecord documentTask2 = createDocumentTask(".DocumentTask1",
+                FLAG_ACTIVITY_MULTIPLE_TASK);
+        mRecentTasks.add(documentTask1);
+        mRecentTasks.add(documentTask2);
+        assertTrue(mCallbacksRecorder.added.size() == 2);
+        assertTrue(mCallbacksRecorder.added.contains(documentTask1));
+        assertTrue(mCallbacksRecorder.added.contains(documentTask2));
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.isEmpty());
+    }
+
+    @Test
+    public void testAddTasksMultipleTasks_expectRemovedNoTrim() throws Exception {
+        // Add multiple same-affinity non-document tasks, ensure that it removes the other task,
+        // but that it does not trim it
+        TaskRecord task1 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
+                .build();
+        TaskRecord task2 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
+                .build();
+        mRecentTasks.add(task1);
+        assertTrue(mCallbacksRecorder.added.size() == 1);
+        assertTrue(mCallbacksRecorder.added.contains(task1));
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.isEmpty());
+        mCallbacksRecorder.clear();
+        mRecentTasks.add(task2);
+        assertTrue(mCallbacksRecorder.added.size() == 1);
+        assertTrue(mCallbacksRecorder.added.contains(task2));
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.size() == 1);
+        assertTrue(mCallbacksRecorder.removed.contains(task1));
+    }
+
+    @Test
+    public void testAddTasksDifferentStacks_expectNoRemove() throws Exception {
+        // Adding the same task with different activity types should not trigger removal of the
+        // other task
+        TaskRecord task1 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
+                .setStack(mHomeStack).build();
+        TaskRecord task2 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
+                .setStack(mStack).build();
+        mRecentTasks.add(task1);
+        mRecentTasks.add(task2);
+        assertTrue(mCallbacksRecorder.added.size() == 2);
+        assertTrue(mCallbacksRecorder.added.contains(task1));
+        assertTrue(mCallbacksRecorder.added.contains(task2));
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.isEmpty());
+    }
+
+    @Test
+    public void testAddTaskCompatibleActivityType_expectRemove() throws Exception {
+        // Test with undefined activity type since the type is not persisted by the task persister
+        // and we want to ensure that a new task will match a restored task
+        Configuration config1 = new Configuration();
+        config1.windowConfiguration.setActivityType(ACTIVITY_TYPE_UNDEFINED);
+        TaskRecord task1 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK)
+                .setStack(mStack)
+                .build();
+        task1.onConfigurationChanged(config1);
+        assertTrue(task1.getActivityType() == ACTIVITY_TYPE_UNDEFINED);
+        mRecentTasks.add(task1);
+        mCallbacksRecorder.clear();
+
+        TaskRecord task2 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK)
+                .setStack(mStack)
+                .build();
+        assertTrue(task2.getActivityType() == ACTIVITY_TYPE_STANDARD);
+        mRecentTasks.add(task2);
+        assertTrue(mCallbacksRecorder.added.size() == 1);
+        assertTrue(mCallbacksRecorder.added.contains(task2));
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.size() == 1);
+        assertTrue(mCallbacksRecorder.removed.contains(task1));
+    }
+
+    @Test
+    public void testAddTaskCompatibleActivityTypeDifferentUser_expectNoRemove() throws Exception {
+        Configuration config1 = new Configuration();
+        config1.windowConfiguration.setActivityType(ACTIVITY_TYPE_UNDEFINED);
+        TaskRecord task1 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK)
+                .setStack(mStack)
+                .setUserId(TEST_USER_0_ID)
+                .build();
+        task1.onConfigurationChanged(config1);
+        assertTrue(task1.getActivityType() == ACTIVITY_TYPE_UNDEFINED);
+        mRecentTasks.add(task1);
+        mCallbacksRecorder.clear();
+
+        TaskRecord task2 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK)
+                .setStack(mStack)
+                .setUserId(TEST_USER_1_ID)
+                .build();
+        assertTrue(task2.getActivityType() == ACTIVITY_TYPE_STANDARD);
+        mRecentTasks.add(task2);
+        assertTrue(mCallbacksRecorder.added.size() == 1);
+        assertTrue(mCallbacksRecorder.added.contains(task2));
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.isEmpty());
+    }
+
+    @Test
+    public void testAddTaskCompatibleWindowingMode_expectRemove() throws Exception {
+        Configuration config1 = new Configuration();
+        config1.windowConfiguration.setWindowingMode(WINDOWING_MODE_UNDEFINED);
+        TaskRecord task1 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK)
+                .setStack(mStack)
+                .build();
+        task1.onConfigurationChanged(config1);
+        assertTrue(task1.getWindowingMode() == WINDOWING_MODE_UNDEFINED);
+        mRecentTasks.add(task1);
+        mCallbacksRecorder.clear();
+
+        Configuration config2 = new Configuration();
+        config2.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        TaskRecord task2 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK)
+                .setStack(mStack)
+                .build();
+        task2.onConfigurationChanged(config2);
+        assertTrue(task2.getWindowingMode() == WINDOWING_MODE_FULLSCREEN);
+        mRecentTasks.add(task2);
+
+        assertTrue(mCallbacksRecorder.added.size() == 1);
+        assertTrue(mCallbacksRecorder.added.contains(task2));
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.size() == 1);
+        assertTrue(mCallbacksRecorder.removed.contains(task1));
+    }
+
+    @Test
+    public void testAddTaskIncompatibleWindowingMode_expectNoRemove() throws Exception {
+        Configuration config1 = new Configuration();
+        config1.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        TaskRecord task1 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK)
+                .setStack(mStack)
+                .build();
+        task1.onConfigurationChanged(config1);
+        assertTrue(task1.getWindowingMode() == WINDOWING_MODE_FULLSCREEN);
+        mRecentTasks.add(task1);
+
+        Configuration config2 = new Configuration();
+        config2.windowConfiguration.setWindowingMode(WINDOWING_MODE_PINNED);
+        TaskRecord task2 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK)
+                .setStack(mStack)
+                .build();
+        task2.onConfigurationChanged(config2);
+        assertTrue(task2.getWindowingMode() == WINDOWING_MODE_PINNED);
+        mRecentTasks.add(task2);
+
+        assertTrue(mCallbacksRecorder.added.size() == 2);
+        assertTrue(mCallbacksRecorder.added.contains(task1));
+        assertTrue(mCallbacksRecorder.added.contains(task2));
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.isEmpty());
+    }
+
+    @Test
+    public void testUsersTasks() throws Exception {
+        mRecentTasks.setOnlyTestVisibleRange();
+
+        // Setup some tasks for the users
+        mTaskPersister.userTaskIdsOverride = new SparseBooleanArray();
+        mTaskPersister.userTaskIdsOverride.put(1, true);
+        mTaskPersister.userTaskIdsOverride.put(2, true);
+        mTaskPersister.userTasksOverride = new ArrayList<>();
+        mTaskPersister.userTasksOverride.add(createTaskBuilder(".UserTask1").build());
+        mTaskPersister.userTasksOverride.add(createTaskBuilder(".UserTask2").build());
+
+        // Assert no user tasks are initially loaded
+        assertTrue(mRecentTasks.usersWithRecentsLoadedLocked().length == 0);
+
+        // Load user 0 tasks
+        mRecentTasks.loadUserRecentsLocked(TEST_USER_0_ID);
+        assertTrue(arrayContainsUser(mRecentTasks.usersWithRecentsLoadedLocked(), TEST_USER_0_ID));
+        assertTrue(mRecentTasks.containsTaskId(1, TEST_USER_0_ID));
+        assertTrue(mRecentTasks.containsTaskId(2, TEST_USER_0_ID));
+
+        // Load user 1 tasks
+        mRecentTasks.loadUserRecentsLocked(TEST_USER_1_ID);
+        assertTrue(arrayContainsUser(mRecentTasks.usersWithRecentsLoadedLocked(), TEST_USER_0_ID));
+        assertTrue(arrayContainsUser(mRecentTasks.usersWithRecentsLoadedLocked(), TEST_USER_1_ID));
+        assertTrue(mRecentTasks.containsTaskId(1, TEST_USER_0_ID));
+        assertTrue(mRecentTasks.containsTaskId(2, TEST_USER_0_ID));
+        assertTrue(mRecentTasks.containsTaskId(1, TEST_USER_1_ID));
+        assertTrue(mRecentTasks.containsTaskId(2, TEST_USER_1_ID));
+
+        // Unload user 1 tasks
+        mRecentTasks.unloadUserDataFromMemoryLocked(TEST_USER_1_ID);
+        assertTrue(arrayContainsUser(mRecentTasks.usersWithRecentsLoadedLocked(), TEST_USER_0_ID));
+        assertFalse(arrayContainsUser(mRecentTasks.usersWithRecentsLoadedLocked(), TEST_USER_1_ID));
+        assertTrue(mRecentTasks.containsTaskId(1, TEST_USER_0_ID));
+        assertTrue(mRecentTasks.containsTaskId(2, TEST_USER_0_ID));
+
+        // Unload user 0 tasks
+        mRecentTasks.unloadUserDataFromMemoryLocked(TEST_USER_0_ID);
+        assertFalse(arrayContainsUser(mRecentTasks.usersWithRecentsLoadedLocked(), TEST_USER_0_ID));
+        assertFalse(arrayContainsUser(mRecentTasks.usersWithRecentsLoadedLocked(), TEST_USER_1_ID));
+    }
+
+    @Test
+    public void testOrderedIteration() throws Exception {
+        mRecentTasks.setOnlyTestVisibleRange();
+        TaskRecord task1 = createTaskBuilder(".Task1").build();
+        task1.lastActiveTime = new Random().nextInt();
+        TaskRecord task2 = createTaskBuilder(".Task1").build();
+        task2.lastActiveTime = new Random().nextInt();
+        TaskRecord task3 = createTaskBuilder(".Task1").build();
+        task3.lastActiveTime = new Random().nextInt();
+        TaskRecord task4 = createTaskBuilder(".Task1").build();
+        task4.lastActiveTime = new Random().nextInt();
+        mRecentTasks.add(task1);
+        mRecentTasks.add(task2);
+        mRecentTasks.add(task3);
+        mRecentTasks.add(task4);
+
+        MutableLong prevLastActiveTime = new MutableLong(0);
+        final ArrayList<TaskRecord> tasks = mRecentTasks.getRawTasks();
+        for (int i = 0; i < tasks.size(); i++) {
+            final TaskRecord task = tasks.get(i);
+            assertTrue(task.lastActiveTime >= prevLastActiveTime.value);
+            prevLastActiveTime.value = task.lastActiveTime;
+        }
+    }
+
+    @Test
+    public void testTrimToGlobalMaxNumRecents() throws Exception {
+        mRecentTasks.setOnlyTestVisibleRange();
+
+        // Limit the global maximum number of recent tasks to a fixed size
+        mRecentTasks.setGlobalMaxNumTasks(2 /* globalMaxNumTasks */);
+
+        // Add N+1 tasks
+        mRecentTasks.add(mTasks.get(0));
+        mRecentTasks.add(mTasks.get(1));
+        mRecentTasks.add(mTasks.get(2));
+
+        // Ensure that the last task was trimmed as an inactive task
+        assertTrimmed(mTasks.get(0));
+    }
+
+    @Test
+    public void testTrimQuietProfileTasks() throws Exception {
+        mRecentTasks.setOnlyTestVisibleRange();
+        TaskRecord qt1 = createTaskBuilder(".QuietTask1").setUserId(TEST_QUIET_USER_ID).build();
+        TaskRecord qt2 = createTaskBuilder(".QuietTask2").setUserId(TEST_QUIET_USER_ID).build();
+        mRecentTasks.add(qt1);
+        mRecentTasks.add(qt2);
+
+        mRecentTasks.add(mTasks.get(0));
+        mRecentTasks.add(mTasks.get(1));
+
+        // Ensure that the quiet user's tasks was trimmed once the new tasks were added
+        assertTrimmed(qt1, qt2);
+    }
+
+    @Test
+    public void testSessionDuration() throws Exception {
+        mRecentTasks.setOnlyTestVisibleRange();
+        mRecentTasks.setParameters(-1 /* min */, -1 /* max */, 50 /* ms */);
+
+        TaskRecord t1 = createTaskBuilder(".Task1").build();
+        t1.touchActiveTime();
+        mRecentTasks.add(t1);
+
+        // Force a small sleep just beyond the session duration
+        SystemClock.sleep(75);
+
+        TaskRecord t2 = createTaskBuilder(".Task2").build();
+        t2.touchActiveTime();
+        mRecentTasks.add(t2);
+
+        // Assert that the old task has been removed due to being out of the active session
+        assertTrimmed(t1);
+    }
+
+    @Test
+    public void testVisibleTasks_excludedFromRecents() throws Exception {
+        mRecentTasks.setOnlyTestVisibleRange();
+        mRecentTasks.setParameters(-1 /* min */, 4 /* max */, -1 /* ms */);
+
+        TaskRecord excludedTask1 = createTaskBuilder(".ExcludedTask1")
+                .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+                .build();
+        TaskRecord excludedTask2 = createTaskBuilder(".ExcludedTask2")
+                .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+                .build();
+
+        mRecentTasks.add(excludedTask1);
+        mRecentTasks.add(mTasks.get(0));
+        mRecentTasks.add(mTasks.get(1));
+        mRecentTasks.add(mTasks.get(2));
+        mRecentTasks.add(excludedTask2);
+
+        // The last excluded task should be trimmed, while the first-most excluded task should not
+        assertTrimmed(excludedTask1);
+    }
+
+    @Test
+    public void testVisibleTasks_minNum() throws Exception {
+        mRecentTasks.setOnlyTestVisibleRange();
+        mRecentTasks.setParameters(5 /* min */, -1 /* max */, 25 /* ms */);
+
+        for (int i = 0; i < 4; i++) {
+            final TaskRecord task = mTasks.get(i);
+            task.touchActiveTime();
+            mRecentTasks.add(task);
+        }
+
+        // Force a small sleep just beyond the session duration
+        SystemClock.sleep(50);
+
+        // Add a new task to trigger tasks to be trimmed
+        mRecentTasks.add(mTasks.get(4));
+
+        // Ensure that there are a minimum number of tasks regardless of session length
+        assertNoTasksTrimmed();
+    }
+
+    @Test
+    public void testVisibleTasks_maxNum() throws Exception {
+        mRecentTasks.setOnlyTestVisibleRange();
+        mRecentTasks.setParameters(-1 /* min */, 3 /* max */, -1 /* ms */);
+
+        for (int i = 0; i < 5; i++) {
+            final TaskRecord task = mTasks.get(i);
+            task.touchActiveTime();
+            mRecentTasks.add(task);
+        }
+
+        // Ensure that only the last number of max tasks are kept
+        assertTrimmed(mTasks.get(0), mTasks.get(1));
+    }
+
+    @Test
+    public void testBackStackTasks_expectNoTrim() throws Exception {
+        mRecentTasks.setParameters(-1 /* min */, 1 /* max */, -1 /* ms */);
+
+        final MyTestActivityStackSupervisor supervisor =
+                (MyTestActivityStackSupervisor) mService.mStackSupervisor;
+        final ActivityStack homeStack = new MyTestActivityStack(mDisplay, supervisor);
+        final ActivityStack aboveHomeStack = new MyTestActivityStack(mDisplay, supervisor);
+        supervisor.setHomeStack(homeStack);
+
+        // Add a number of tasks (beyond the max) but ensure that nothing is trimmed because all
+        // the tasks belong in stacks above the home stack
+        mRecentTasks.add(createTaskBuilder(".HomeTask1").setStack(homeStack).build());
+        mRecentTasks.add(createTaskBuilder(".Task1").setStack(aboveHomeStack).build());
+        mRecentTasks.add(createTaskBuilder(".Task2").setStack(aboveHomeStack).build());
+        mRecentTasks.add(createTaskBuilder(".Task3").setStack(aboveHomeStack).build());
+
+        assertNoTasksTrimmed();
+    }
+
+    @Test
+    public void testBehindHomeStackTasks_expectTaskTrimmed() throws Exception {
+        mRecentTasks.setParameters(-1 /* min */, 1 /* max */, -1 /* ms */);
+
+        final MyTestActivityStackSupervisor supervisor =
+                (MyTestActivityStackSupervisor) mService.mStackSupervisor;
+        final ActivityStack behindHomeStack = new MyTestActivityStack(mDisplay, supervisor);
+        final ActivityStack homeStack = new MyTestActivityStack(mDisplay, supervisor);
+        final ActivityStack aboveHomeStack = new MyTestActivityStack(mDisplay, supervisor);
+        supervisor.setHomeStack(homeStack);
+
+        // Add a number of tasks (beyond the max) but ensure that only the task in the stack behind
+        // the home stack is trimmed once a new task is added
+        final TaskRecord behindHomeTask = createTaskBuilder(".Task1")
+                .setStack(behindHomeStack)
+                .build();
+        mRecentTasks.add(behindHomeTask);
+        mRecentTasks.add(createTaskBuilder(".HomeTask1").setStack(homeStack).build());
+        mRecentTasks.add(createTaskBuilder(".Task2").setStack(aboveHomeStack).build());
+
+        assertTrimmed(behindHomeTask);
+    }
+
+    @Test
+    public void testOtherDisplayTasks_expectNoTrim() throws Exception {
+        mRecentTasks.setParameters(-1 /* min */, 1 /* max */, -1 /* ms */);
+
+        final MyTestActivityStackSupervisor supervisor =
+                (MyTestActivityStackSupervisor) mService.mStackSupervisor;
+        final ActivityStack homeStack = new MyTestActivityStack(mDisplay, supervisor);
+        final ActivityStack otherDisplayStack = new MyTestActivityStack(mOtherDisplay, supervisor);
+        supervisor.setHomeStack(homeStack);
+
+        // Add a number of tasks (beyond the max) on each display, ensure that the tasks are not
+        // removed
+        mRecentTasks.add(createTaskBuilder(".HomeTask1").setStack(homeStack).build());
+        mRecentTasks.add(createTaskBuilder(".Task1").setStack(otherDisplayStack).build());
+        mRecentTasks.add(createTaskBuilder(".Task2").setStack(otherDisplayStack).build());
+        mRecentTasks.add(createTaskBuilder(".HomeTask2").setStack(homeStack).build());
+
+        assertNoTasksTrimmed();
+    }
+
+    @Test
+    public void testRemovePackageByName() throws Exception {
+        // Add a number of tasks with the same package name
+        mRecentTasks.add(createTaskBuilder("com.android.pkg1", ".Task1").build());
+        mRecentTasks.add(createTaskBuilder("com.android.pkg2", ".Task2").build());
+        mRecentTasks.add(createTaskBuilder("com.android.pkg3", ".Task3").build());
+        mRecentTasks.add(createTaskBuilder("com.android.pkg1", ".Task4").build());
+        mRecentTasks.removeTasksByPackageName("com.android.pkg1", TEST_USER_0_ID);
+
+        final ArrayList<TaskRecord> tasks = mRecentTasks.getRawTasks();
+        for (int i = 0; i < tasks.size(); i++) {
+            if (tasks.get(i).intent.getComponent().getPackageName().equals("com.android.pkg1")) {
+                fail("Expected com.android.pkg1 tasks to be removed");
+            }
+        }
+    }
+
+    @Test
+    public void testNotRecentsComponent_denyApiAccess() throws Exception {
+        doReturn(PackageManager.PERMISSION_DENIED).when(mService).checkPermission(anyString(),
+                anyInt(), anyInt());
+
+        // Expect the following methods to fail due to recents component not being set
+        mRecentTasks.setIsCallerRecentsOverride(TestRecentTasks.DENY_THROW_SECURITY_EXCEPTION);
+        testRecentTasksApis(false /* expectNoSecurityException */);
+        // Don't throw for the following tests
+        mRecentTasks.setIsCallerRecentsOverride(TestRecentTasks.DENY);
+        testGetTasksApis(false /* expectNoSecurityException */);
+    }
+
+    @Test
+    public void testRecentsComponent_allowApiAccessWithoutPermissions() throws Exception {
+        doReturn(PackageManager.PERMISSION_DENIED).when(mService).checkPermission(anyString(),
+                anyInt(), anyInt());
+
+        // Set the recents component and ensure that the following calls do not fail
+        mRecentTasks.setIsCallerRecentsOverride(TestRecentTasks.GRANT);
+        testRecentTasksApis(true /* expectNoSecurityException */);
+        testGetTasksApis(true /* expectNoSecurityException */);
+    }
+
+    private void testRecentTasksApis(boolean expectCallable) {
+        assertSecurityException(expectCallable, () -> mService.removeStack(INVALID_STACK_ID));
+        assertSecurityException(expectCallable,
+                () -> mService.removeStacksInWindowingModes(new int[] {WINDOWING_MODE_UNDEFINED}));
+        assertSecurityException(expectCallable,
+                () -> mService.removeStacksWithActivityTypes(new int[] {ACTIVITY_TYPE_UNDEFINED}));
+        assertSecurityException(expectCallable, () -> mService.removeTask(0));
+        assertSecurityException(expectCallable,
+                () -> mService.setTaskWindowingMode(0, WINDOWING_MODE_UNDEFINED, true));
+        assertSecurityException(expectCallable,
+                () -> mService.moveTaskToStack(0, INVALID_STACK_ID, true));
+        assertSecurityException(expectCallable,
+                () -> mService.setTaskWindowingModeSplitScreenPrimary(0,
+                        SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, true, true, new Rect(), true));
+        assertSecurityException(expectCallable, () -> mService.dismissSplitScreenMode(true));
+        assertSecurityException(expectCallable, () -> mService.dismissPip(true, 0));
+        assertSecurityException(expectCallable,
+                () -> mService.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect()));
+        assertSecurityException(expectCallable,
+                () -> mService.resizeStack(INVALID_STACK_ID, new Rect(), true, true, true, 0));
+        assertSecurityException(expectCallable,
+                () -> mService.resizeDockedStack(new Rect(), new Rect(), new Rect(), new Rect(),
+                        new Rect()));
+        assertSecurityException(expectCallable,
+                () -> mService.resizePinnedStack(new Rect(), new Rect()));
+        assertSecurityException(expectCallable, () -> mService.getAllStackInfos());
+        assertSecurityException(expectCallable,
+                () -> mService.getStackInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_UNDEFINED));
+        assertSecurityException(expectCallable, () -> {
+            try {
+                mService.getFocusedStackInfo();
+            } catch (RemoteException e) {
+                // Ignore
+            }
+        });
+        assertSecurityException(expectCallable,
+                () -> mService.moveTasksToFullscreenStack(INVALID_STACK_ID, true));
+        assertSecurityException(expectCallable,
+                () -> mService.startActivityFromRecents(0, new Bundle()));
+        assertSecurityException(expectCallable,
+                () -> mService.getTaskSnapshot(0, true));
+        assertSecurityException(expectCallable, () -> {
+            try {
+                mService.registerTaskStackListener(null);
+            } catch (RemoteException e) {
+                // Ignore
+            }
+        });
+        assertSecurityException(expectCallable, () -> {
+            try {
+                mService.unregisterTaskStackListener(null);
+            } catch (RemoteException e) {
+                // Ignore
+            }
+        });
+        assertSecurityException(expectCallable, () -> mService.getTaskDescription(0));
+        assertSecurityException(expectCallable, () -> mService.cancelTaskWindowTransition(0));
+        assertSecurityException(expectCallable, () -> mService.startRecentsActivity(null, null,
+                null));
+        assertSecurityException(expectCallable, () -> mService.cancelRecentsAnimation(true));
+        assertSecurityException(expectCallable, () -> mService.stopAppSwitches());
+        assertSecurityException(expectCallable, () -> mService.resumeAppSwitches());
+    }
+
+    private void testGetTasksApis(boolean expectCallable) {
+        mService.getRecentTasks(MAX_VALUE, 0, TEST_USER_0_ID);
+        mService.getTasks(MAX_VALUE);
+        if (expectCallable) {
+            assertTrue(mRecentTasks.lastAllowed);
+            assertTrue(mRunningTasks.lastAllowed);
+        } else {
+            assertFalse(mRecentTasks.lastAllowed);
+            assertFalse(mRunningTasks.lastAllowed);
+        }
+    }
+
+    private TaskBuilder createTaskBuilder(String className) {
+        return createTaskBuilder(mContext.getPackageName(), className);
+    }
+
+    private TaskBuilder createTaskBuilder(String packageName, String className) {
+        return new TaskBuilder(mService.mStackSupervisor)
+                .setComponent(new ComponentName(packageName, className))
+                .setStack(mStack)
+                .setTaskId(LAST_TASK_ID++)
+                .setUserId(TEST_USER_0_ID);
+    }
+
+    private TaskRecord createDocumentTask(String className) {
+        return createDocumentTask(className, 0);
+    }
+
+    private TaskRecord createDocumentTask(String className, int flags) {
+        TaskRecord task = createTaskBuilder(className)
+                .setFlags(FLAG_ACTIVITY_NEW_DOCUMENT | flags)
+                .build();
+        task.affinity = null;
+        task.maxRecents = ActivityManager.getMaxAppRecentsLimitStatic();
+        return task;
+    }
+
+    private boolean arrayContainsUser(int[] userIds, int targetUserId) {
+        Arrays.sort(userIds);
+        return Arrays.binarySearch(userIds, targetUserId) >= 0;
+    }
+
+    private void assertNoTasksTrimmed() {
+        assertTrimmed();
+    }
+
+    private void assertTrimmed(TaskRecord... tasks) {
+        final ArrayList<TaskRecord> trimmed = mCallbacksRecorder.trimmed;
+        final ArrayList<TaskRecord> removed = mCallbacksRecorder.removed;
+        assertTrue("Expected " + tasks.length + " trimmed tasks, got " + trimmed.size(),
+                trimmed.size() == tasks.length);
+        assertTrue("Expected " + tasks.length + " removed tasks, got " + removed.size(),
+                removed.size() == tasks.length);
+        for (TaskRecord task : tasks) {
+            assertTrue("Expected trimmed task: " + task, trimmed.contains(task));
+            assertTrue("Expected removed task: " + task, removed.contains(task));
+        }
+    }
+
+    private void assertSecurityException(boolean expectCallable, Runnable runnable) {
+        boolean noSecurityException = true;
+        try {
+            runnable.run();
+        } catch (SecurityException se) {
+            noSecurityException = false;
+        } catch (Exception e) {
+            // We only care about SecurityExceptions, fall through here
+            e.printStackTrace();
+        }
+        if (noSecurityException != expectCallable) {
+            fail("Expected callable: " + expectCallable + " but got no security exception: "
+                    + noSecurityException);
+        }
+    }
+
+    private class MyTestActivityManagerService extends TestActivityManagerService {
+        MyTestActivityManagerService(Context context) {
+            super(context);
+        }
+
+        @Override
+        protected ActivityStackSupervisor createTestSupervisor() {
+            return new MyTestActivityStackSupervisor(this, mHandlerThread.getLooper());
+        }
+
+        @Override
+        protected RecentTasks createRecentTasks() {
+            return new TestRecentTasks(this, mTaskPersister, new TestUserController(this));
+        }
+
+        @Override
+        public boolean isUserRunning(int userId, int flags) {
+            return true;
+        }
+    }
+
+    private class MyTestActivityStackSupervisor extends TestActivityStackSupervisor {
+        public MyTestActivityStackSupervisor(ActivityManagerService service, Looper looper) {
+            super(service, looper);
+        }
+
+        @Override
+        public void initialize() {
+            super.initialize();
+            mDisplay = new TestActivityDisplay(this, DEFAULT_DISPLAY);
+            mOtherDisplay = new TestActivityDisplay(this, DEFAULT_DISPLAY);
+            attachDisplay(mOtherDisplay);
+            attachDisplay(mDisplay);
+        }
+
+        @Override
+        RunningTasks createRunningTasks() {
+            mRunningTasks = new TestRunningTasks();
+            return mRunningTasks;
+        }
+
+        void setHomeStack(ActivityStack stack) {
+            mHomeStack = stack;
+        }
+    }
+
+    private class MyTestActivityStack extends TestActivityStack {
+        private ActivityDisplay mDisplay = null;
+
+        MyTestActivityStack(ActivityDisplay display, ActivityStackSupervisor supervisor) {
+            super(display, LAST_STACK_ID++, supervisor, WINDOWING_MODE_FULLSCREEN,
+                    ACTIVITY_TYPE_STANDARD, true);
+            mDisplay = display;
+        }
+
+        @Override
+        ActivityDisplay getDisplay() {
+            if (mDisplay != null) {
+                return mDisplay;
+            }
+            return super.getDisplay();
+        }
+    }
+
+    private static class CallbacksRecorder implements Callbacks {
+        ArrayList<TaskRecord> added = new ArrayList<>();
+        ArrayList<TaskRecord> trimmed = new ArrayList<>();
+        ArrayList<TaskRecord> removed = new ArrayList<>();
+
+        void clear() {
+            added.clear();
+            trimmed.clear();
+            removed.clear();
+        }
+
+        @Override
+        public void onRecentTaskAdded(TaskRecord task) {
+            added.add(task);
+        }
+
+        @Override
+        public void onRecentTaskRemoved(TaskRecord task, boolean wasTrimmed) {
+            if (wasTrimmed) {
+                trimmed.add(task);
+            }
+            removed.add(task);
+        }
+    }
+
+    private static class TestTaskPersister extends TaskPersister {
+        SparseBooleanArray userTaskIdsOverride;
+        ArrayList<TaskRecord> userTasksOverride;
+
+        TestTaskPersister(File workingDir) {
+            super(workingDir);
+        }
+
+        @Override
+        SparseBooleanArray loadPersistedTaskIdsForUser(int userId) {
+            if (userTaskIdsOverride != null) {
+                return userTaskIdsOverride;
+            }
+            return super.loadPersistedTaskIdsForUser(userId);
+        }
+
+        @Override
+        List<TaskRecord> restoreTasksForUserLocked(int userId, SparseBooleanArray preaddedTasks) {
+            if (userTasksOverride != null) {
+                return userTasksOverride;
+            }
+            return super.restoreTasksForUserLocked(userId, preaddedTasks);
+        }
+    }
+
+    private static class TestRecentTasks extends RecentTasks {
+        static final int GRANT = 0;
+        static final int DENY = 1;
+        static final int DENY_THROW_SECURITY_EXCEPTION = 2;
+
+        private boolean mOverrideIsCallerRecents;
+        private boolean mIsTrimmableOverride;
+        private int mIsCallerRecentsPolicy;
+
+        boolean lastAllowed;
+
+        TestRecentTasks(ActivityManagerService service, TaskPersister taskPersister,
+                UserController userController) {
+            super(service, taskPersister, userController);
+        }
+
+        @Override
+        boolean isCallerRecents(int callingUid) {
+            if (mOverrideIsCallerRecents) {
+                switch (mIsCallerRecentsPolicy) {
+                    case GRANT:
+                        return true;
+                    case DENY:
+                        return false;
+                    case DENY_THROW_SECURITY_EXCEPTION:
+                        throw new SecurityException();
+                }
+            }
+            return super.isCallerRecents(callingUid);
+        }
+
+        void setIsCallerRecentsOverride(int policy) {
+            mOverrideIsCallerRecents = true;
+            mIsCallerRecentsPolicy = policy;
+        }
+
+        /**
+         * To simplify the setup for some tests, the caller can request that we only rely on the
+         * visible range test to determine what is trimmable. In this case, we don't try to
+         * use the stack order to determine additionally if the task is trimmable when it is not
+         * in the visible range.
+         */
+        void setOnlyTestVisibleRange() {
+            mIsTrimmableOverride = true;
+        }
+
+        @Override
+        ParceledListSlice<RecentTaskInfo> getRecentTasks(int maxNum, int flags,
+                boolean getTasksAllowed,
+                boolean getDetailedTasks, int userId, int callingUid) {
+            lastAllowed = getTasksAllowed;
+            return super.getRecentTasks(maxNum, flags, getTasksAllowed, getDetailedTasks, userId,
+                    callingUid);
+        }
+
+        @Override
+        protected boolean isTrimmable(TaskRecord task) {
+            return mIsTrimmableOverride || super.isTrimmable(task);
+        }
+    }
+
+    private static class TestRunningTasks extends RunningTasks {
+        boolean lastAllowed;
+
+        @Override
+        void getTasks(int maxNum, List<RunningTaskInfo> list, int ignoreActivityType,
+                int ignoreWindowingMode, SparseArray<ActivityDisplay> activityDisplays,
+                int callingUid, boolean allowed) {
+            lastAllowed = allowed;
+            super.getTasks(maxNum, list, ignoreActivityType, ignoreWindowingMode, activityDisplays,
+                    callingUid, allowed);
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java b/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java
new file mode 100644
index 0000000..eefd973
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.IRecentsAnimationRunner;
+import com.android.server.AttributeCache;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * atest FrameworksServicesTests:RecentsAnimationTest
+ */
+@MediumTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class RecentsAnimationTest extends ActivityTestsBase {
+    private static final int TEST_CALLING_PID = 3;
+
+    private Context mContext = InstrumentationRegistry.getContext();
+    private ActivityManagerService mService;
+    private ComponentName mRecentsComponent;
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mRecentsComponent = new ComponentName(mContext.getPackageName(), "RecentsActivity");
+        mService = setupActivityManagerService(new MyTestActivityManagerService(mContext));
+        AttributeCache.init(mContext);
+    }
+
+    @Test
+    public void testCancelAnimationOnStackOrderChange() throws Exception {
+        ActivityStack fullscreenStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        ActivityStack recentsStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS, true /* onTop */);
+        ActivityRecord recentsActivity = new ActivityBuilder(mService)
+                .setComponent(mRecentsComponent)
+                .setCreateTask(true)
+                .setStack(recentsStack)
+                .build();
+        ActivityStack fullscreenStack2 = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        ActivityRecord fsActivity = new ActivityBuilder(mService)
+                .setComponent(new ComponentName(mContext.getPackageName(), "App1"))
+                .setCreateTask(true)
+                .setStack(fullscreenStack2)
+                .build();
+        doReturn(true).when(mService.mWindowManager).canStartRecentsAnimation();
+
+        // Start the recents animation
+        Intent recentsIntent = new Intent();
+        recentsIntent.setComponent(mRecentsComponent);
+        mService.startRecentsActivity(recentsIntent, null, mock(IRecentsAnimationRunner.class));
+
+        fullscreenStack.moveToFront("Activity start");
+
+        // Ensure that the recents animation was canceled
+        verify(mService.mWindowManager, times(1)).cancelRecentsAnimationSynchronously(
+                eq(REORDER_KEEP_IN_PLACE), any());
+    }
+
+    private class MyTestActivityManagerService extends TestActivityManagerService {
+        MyTestActivityManagerService(Context context) {
+            super(context);
+        }
+
+        @Override
+        protected RecentTasks createRecentTasks() {
+            RecentTasks recents = mock(RecentTasks.class);
+            doReturn(mRecentsComponent).when(recents).getRecentsComponent();
+            System.out.println(mRecentsComponent);
+            return recents;
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java
new file mode 100644
index 0000000..c6ce7e1
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import static com.android.server.am.ActivityDisplay.POSITION_BOTTOM;
+
+import static org.junit.Assert.assertTrue;
+
+import android.app.ActivityManager.RunningTaskInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.SparseArray;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+
+/**
+ * runtest --path frameworks/base/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java
+ */
+@MediumTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class RunningTasksTest extends ActivityTestsBase {
+
+    private Context mContext = InstrumentationRegistry.getContext();
+    private ActivityManagerService mService;
+
+    private RunningTasks mRunningTasks;
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mService = createActivityManagerService();
+        mRunningTasks = new RunningTasks();
+    }
+
+    @Test
+    public void testCollectTasksByLastActiveTime() throws Exception {
+        // Create a number of stacks with tasks (of incrementing active time)
+        final ActivityStackSupervisor supervisor = mService.mStackSupervisor;
+        final SparseArray<ActivityDisplay> displays = new SparseArray<>();
+        final ActivityDisplay display = new TestActivityDisplay(supervisor, DEFAULT_DISPLAY);
+        displays.put(DEFAULT_DISPLAY, display);
+
+        final int numStacks = 2;
+        for (int stackIndex = 0; stackIndex < numStacks; stackIndex++) {
+            final ActivityStack stack = new TestActivityStack(display, stackIndex, supervisor,
+                    WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true);
+            display.addChild(stack, POSITION_BOTTOM);
+        }
+
+        final int numTasks = 10;
+        int activeTime = 0;
+        for (int i = 0; i < numTasks; i++) {
+            createTask(display.getChildAt(i % numStacks), ".Task" + i, i, activeTime++);
+        }
+
+        // Ensure that the latest tasks were returned in order of decreasing last active time,
+        // collected from all tasks across all the stacks
+        final int numFetchTasks = 5;
+        ArrayList<RunningTaskInfo> tasks = new ArrayList<>();
+        mRunningTasks.getTasks(5, tasks, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED,
+                displays, -1 /* callingUid */, true /* allowed */);
+        assertTrue(tasks.size() == numFetchTasks);
+        for (int i = 0; i < numFetchTasks; i++) {
+            assertTrue(tasks.get(i).id == (numTasks - i - 1));
+        }
+
+        // Ensure that requesting more than the total number of tasks only returns the subset
+        // and does not crash
+        tasks.clear();
+        mRunningTasks.getTasks(100, tasks, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED,
+                displays, -1 /* callingUid */, true /* allowed */);
+        assertTrue(tasks.size() == numTasks);
+        for (int i = 0; i < numTasks; i++) {
+            assertTrue(tasks.get(i).id == (numTasks - i - 1));
+        }
+    }
+
+    /**
+     * Create a task with a single activity in it, with the given last active time.
+     */
+    private TaskRecord createTask(ActivityStack stack, String className, int taskId,
+            int lastActiveTime) {
+        final TaskRecord task = new TaskBuilder(mService.mStackSupervisor)
+                .setComponent(new ComponentName(mContext.getPackageName(), className))
+                .setTaskId(taskId)
+                .setStack(stack)
+                .build();
+        task.lastActiveTime = lastActiveTime;
+        final ActivityRecord activity = new ActivityBuilder(mService)
+                .setTask(task)
+                .setComponent(new ComponentName(mContext.getPackageName(), ".TaskActivity"))
+                .build();
+        return task;
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/am/SafeActivityOptionsTest.java b/services/tests/servicestests/src/com/android/server/am/SafeActivityOptionsTest.java
new file mode 100644
index 0000000..168bc17
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/SafeActivityOptionsTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import static org.junit.Assert.assertEquals;
+
+import android.app.ActivityOptions;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@Presubmit
+@FlakyTest
+@RunWith(AndroidJUnit4.class)
+public class SafeActivityOptionsTest {
+
+    @Test
+    public void testMerge() {
+        final ActivityOptions opts1 = ActivityOptions.makeBasic();
+        opts1.setLaunchDisplayId(5);
+        final ActivityOptions opts2 = ActivityOptions.makeBasic();
+        opts2.setLaunchDisplayId(6);
+        final SafeActivityOptions options = new SafeActivityOptions(opts1);
+        final ActivityOptions result = options.mergeActivityOptions(opts1, opts2);
+        assertEquals(6, result.getLaunchDisplayId());
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java b/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java
new file mode 100644
index 0000000..3d323f0
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import android.content.pm.ActivityInfo.WindowLayout;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import android.view.Gravity;
+
+import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.mockito.invocation.InvocationOnMock;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+
+import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.doAnswer;
+import static org.junit.Assert.assertEquals;
+
+
+/**
+ * Tests for exercising resizing task bounds.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:TaskLaunchParamsModifierTests
+ */
+@MediumTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
+    private final static int STACK_WIDTH = 100;
+    private final static int STACK_HEIGHT = 200;
+
+    private final static Rect STACK_BOUNDS = new Rect(0, 0, STACK_WIDTH, STACK_HEIGHT);
+
+    private ActivityManagerService mService;
+    private ActivityStack mStack;
+    private TaskRecord mTask;
+
+    private TaskLaunchParamsModifier mPositioner;
+
+    private LaunchParamsController.LaunchParams mCurrent;
+    private LaunchParamsController.LaunchParams mResult;
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mService = createActivityManagerService();
+        mStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        mStack.requestResize(STACK_BOUNDS);
+
+        // We must create the task after resizing to make sure it does not inherit the stack
+        // dimensions on resize.
+        mTask = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
+
+        mPositioner = new TaskLaunchParamsModifier();
+
+        mResult = new LaunchParamsController.LaunchParams();
+        mCurrent = new LaunchParamsController.LaunchParams();
+    }
+
+    /**
+     * Ensures that the setup bounds are set as expected with the stack bounds set and the task
+     * bounds still {@code null}.
+     * @throws Exception
+     */
+    @Test
+    public void testInitialBounds() throws Exception {
+        assertEquals(mStack.getOverrideBounds(), STACK_BOUNDS);
+        assertEquals(mTask.getOverrideBounds(), new Rect());
+    }
+
+    /**
+     * Ensures that a task positioned with no {@link WindowLayout} receives the default launch
+     * position.
+     * @throws Exception
+     */
+    @Test
+    public void testLaunchNoWindowLayout() throws Exception {
+        assertEquals(RESULT_CONTINUE, mPositioner.onCalculate(mTask, null /*layout*/,
+                null /*record*/, null /*source*/, null /*options*/, mCurrent, mResult));
+        assertEquals(getDefaultBounds(Gravity.NO_GRAVITY), mResult.mBounds);
+    }
+
+    /**
+     * Ensures that a task positioned with an empty {@link WindowLayout} receives the default launch
+     * position.
+     * @throws Exception
+     */
+    @Test
+    public void testlaunchEmptyWindowLayout() throws Exception {
+        assertEquals(RESULT_CONTINUE, mPositioner.onCalculate(mTask,
+                new WindowLayout(0, 0, 0, 0, Gravity.NO_GRAVITY, 0, 0), null /*activity*/,
+                null /*source*/, null /*options*/, mCurrent, mResult));
+        assertEquals(mResult.mBounds, getDefaultBounds(Gravity.NO_GRAVITY));
+    }
+
+    /**
+     * Ensures that a task positioned with a {@link WindowLayout} gravity specified is positioned
+     * according to specification.
+     * @throws Exception
+     */
+    @Test
+    public void testlaunchWindowLayoutGravity() throws Exception {
+        // Unspecified gravity should be ignored
+        testGravity(Gravity.NO_GRAVITY);
+
+        // Unsupported gravity should be ignored
+        testGravity(Gravity.LEFT);
+        testGravity(Gravity.RIGHT);
+
+        // Test defaults for vertical gravities
+        testGravity(Gravity.TOP);
+        testGravity(Gravity.BOTTOM);
+
+        // Test corners
+        testGravity(Gravity.TOP | Gravity.LEFT);
+        testGravity(Gravity.TOP | Gravity.RIGHT);
+        testGravity(Gravity.BOTTOM | Gravity.LEFT);
+        testGravity(Gravity.BOTTOM | Gravity.RIGHT);
+    }
+
+    private void testGravity(int gravity) {
+        try {
+            assertEquals(RESULT_CONTINUE, mPositioner.onCalculate(mTask,
+                    new WindowLayout(0, 0, 0, 0, gravity, 0, 0), null /*activity*/,
+                    null /*source*/, null /*options*/, mCurrent, mResult));
+            assertEquals(mResult.mBounds, getDefaultBounds(gravity));
+        } finally {
+            mCurrent.reset();
+            mResult.reset();
+        }
+    }
+
+    /**
+     * Ensures that a task which causes a conflict with another task when positioned is adjusted as
+     * expected.
+     * @throws Exception
+     */
+    @Test
+    public void testLaunchWindowCenterConflict() throws Exception {
+        testConflict(Gravity.NO_GRAVITY);
+        testConflict(Gravity.TOP);
+        testConflict(Gravity.BOTTOM);
+        testConflict(Gravity.TOP | Gravity.LEFT);
+        testConflict(Gravity.TOP | Gravity.RIGHT);
+        testConflict(Gravity.BOTTOM | Gravity.LEFT);
+        testConflict(Gravity.BOTTOM | Gravity.RIGHT);
+    }
+
+    private void testConflict(int gravity) {
+        final WindowLayout layout = new WindowLayout(0, 0, 0, 0, gravity, 0, 0);
+
+        // layout first task
+        mService.mStackSupervisor.getLaunchParamsController().layoutTask(mTask, layout);
+
+        // Second task will be laid out on top of the first so starting bounds is the same.
+        final Rect expectedBounds = new Rect(mTask.getOverrideBounds());
+
+        ActivityRecord activity = null;
+        TaskRecord secondTask = null;
+
+        // wrap with try/finally to ensure cleanup of activity/stack.
+        try {
+            // empty tasks are ignored in conflicts
+            activity = new ActivityBuilder(mService).setTask(mTask).build();
+
+            // Create secondary task
+            secondTask = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
+
+            // layout second task
+            assertEquals(RESULT_CONTINUE,
+                    mPositioner.onCalculate(secondTask, layout, null /*activity*/,
+                            null /*source*/, null /*options*/, mCurrent, mResult));
+
+            if ((gravity & (Gravity.TOP | Gravity.RIGHT)) == (Gravity.TOP | Gravity.RIGHT)
+                    || (gravity & (Gravity.BOTTOM | Gravity.RIGHT))
+                    == (Gravity.BOTTOM | Gravity.RIGHT)) {
+                expectedBounds.offset(-TaskLaunchParamsModifier.getHorizontalStep(
+                        mStack.getOverrideBounds()), 0);
+            } else if ((gravity & Gravity.TOP) == Gravity.TOP
+                    || (gravity & Gravity.BOTTOM) == Gravity.BOTTOM) {
+                expectedBounds.offset(
+                        TaskLaunchParamsModifier.getHorizontalStep(mStack.getOverrideBounds()), 0);
+            } else {
+                expectedBounds.offset(
+                        TaskLaunchParamsModifier.getHorizontalStep(mStack.getOverrideBounds()),
+                        TaskLaunchParamsModifier.getVerticalStep(mStack.getOverrideBounds()));
+            }
+
+            assertEquals(mResult.mBounds, expectedBounds);
+        } finally {
+            // Remove task and activity to prevent influencing future tests
+            if (activity != null) {
+                mTask.removeActivity(activity);
+            }
+
+            if (secondTask != null) {
+                mStack.removeTask(secondTask, "cleanup", ActivityStack.REMOVE_TASK_MODE_DESTROYING);
+            }
+        }
+    }
+
+    private Rect getDefaultBounds(int gravity) {
+        final Rect bounds = new Rect();
+        bounds.set(mStack.getOverrideBounds());
+
+        final int verticalInset =
+                TaskLaunchParamsModifier.getFreeformStartTop(mStack.getOverrideBounds());
+        final int horizontalInset =
+                TaskLaunchParamsModifier.getFreeformStartLeft(mStack.getOverrideBounds());
+
+        bounds.inset(horizontalInset, verticalInset);
+
+        if ((gravity & (Gravity.TOP | Gravity.RIGHT)) == (Gravity.TOP | Gravity.RIGHT)) {
+            bounds.offsetTo(horizontalInset * 2, 0);
+        } else if ((gravity & Gravity.TOP) == Gravity.TOP) {
+            bounds.offsetTo(0, 0);
+        } else if ((gravity & (Gravity.BOTTOM | Gravity.RIGHT))
+                == (Gravity.BOTTOM | Gravity.RIGHT)) {
+            bounds.offsetTo(horizontalInset * 2, verticalInset * 2);
+        } else if ((gravity & Gravity.BOTTOM) == Gravity.BOTTOM) {
+            bounds.offsetTo(0, verticalInset * 2);
+        }
+
+        return bounds;
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java b/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java
new file mode 100644
index 0000000..9e6055d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.content.pm.UserInfo;
+import android.os.Environment;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.test.AndroidTestCase;
+import android.util.Log;
+import android.util.SparseBooleanArray;
+
+import com.android.server.am.TaskPersister;
+
+import java.io.File;
+import java.util.Random;
+
+/**
+ * atest FrameworksServicesTests:TaskPersisterTest
+ */
+public class TaskPersisterTest extends AndroidTestCase {
+    private static final String TEST_USER_NAME = "AM-Test-User";
+
+    private TaskPersister mTaskPersister;
+    private int testUserId;
+    private UserManager mUserManager;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mUserManager = UserManager.get(getContext());
+        mTaskPersister = new TaskPersister(getContext().getFilesDir());
+        testUserId = createUser(TEST_USER_NAME, 0);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        mTaskPersister.unloadUserDataFromMemory(testUserId);
+        removeUser(testUserId);
+    }
+
+    private int getRandomTaskIdForUser(int userId) {
+        int taskId = (int) (Math.random() * UserHandle.PER_USER_RANGE);
+        taskId += UserHandle.PER_USER_RANGE * userId;
+        return taskId;
+    }
+
+    public void testTaskIdsPersistence() {
+        SparseBooleanArray taskIdsOnFile = new SparseBooleanArray();
+        for (int i = 0; i < 100; i++) {
+            taskIdsOnFile.put(getRandomTaskIdForUser(testUserId), true);
+        }
+        mTaskPersister.writePersistedTaskIdsForUser(taskIdsOnFile, testUserId);
+        SparseBooleanArray newTaskIdsOnFile = mTaskPersister
+                .loadPersistedTaskIdsForUser(testUserId);
+        assertTrue("TaskIds written differ from TaskIds read back from file",
+                taskIdsOnFile.equals(newTaskIdsOnFile));
+    }
+
+    private int createUser(String name, int flags) {
+        UserInfo user = mUserManager.createUser(name, flags);
+        if (user == null) {
+            fail("Error while creating the test user: " + TEST_USER_NAME);
+        }
+        return user.id;
+    }
+
+    private void removeUser(int userId) {
+        if (!mUserManager.removeUser(userId)) {
+            fail("Error while removing the test user: " + TEST_USER_NAME);
+        }
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java b/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java
new file mode 100644
index 0000000..057fdc8
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.server.am;
+
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.app.ActivityManager;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.res.XmlResourceParser;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.service.voice.IVoiceInteractionSession;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Xml;
+
+import com.android.frameworks.servicestests.R;
+import com.android.internal.app.IVoiceInteractor;
+import com.android.server.am.TaskRecord.TaskRecordFactory;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Comparator;
+
+/**
+ * Tests for exercising {@link TaskRecord}.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:com.android.server.am.TaskRecordTests
+ */
+@MediumTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class TaskRecordTests extends ActivityTestsBase {
+
+    private static final String TASK_TAG = "task";
+
+    private ActivityManagerService mService;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        TaskRecord.setTaskRecordFactory(null);
+        mService = createActivityManagerService();
+    }
+
+    @Test
+    public void testRestoreWindowedTask() throws Exception {
+        final TaskRecord expected = createTaskRecord(64);
+        expected.mLastNonFullscreenBounds = new Rect(50, 50, 100, 100);
+
+        final File serializedFile = serializeToFile(expected);
+
+        try {
+            final TaskRecord actual = restoreFromFile(serializedFile);
+            assertEquals(expected.taskId, actual.taskId);
+            assertEquals(expected.mLastNonFullscreenBounds, actual.mLastNonFullscreenBounds);
+        } finally {
+            serializedFile.delete();
+        }
+    }
+
+    @Test
+    public void testDefaultTaskFactoryNotNull() throws Exception {
+        assertNotNull(TaskRecord.getTaskRecordFactory());
+    }
+
+    @Test
+    public void testCreateTestRecordUsingCustomizedFactory() throws Exception {
+        TestTaskRecordFactory factory = new TestTaskRecordFactory();
+        TaskRecord.setTaskRecordFactory(factory);
+
+        assertFalse(factory.mCreated);
+
+        TaskRecord.create(null, 0, null, null, null, null);
+
+        assertTrue(factory.mCreated);
+    }
+
+    @Test
+    public void testReturnsToHomeStack() throws Exception {
+        final TaskRecord task = createTaskRecord(1);
+        assertFalse(task.returnsToHomeStack());
+        task.intent = null;
+        assertFalse(task.returnsToHomeStack());
+        task.intent = new Intent();
+        assertFalse(task.returnsToHomeStack());
+        task.intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME);
+        assertTrue(task.returnsToHomeStack());
+    }
+
+    private File serializeToFile(TaskRecord r) throws IOException, XmlPullParserException {
+        final File tmpFile = File.createTempFile(r.taskId + "_task_", "xml");
+
+        try (final OutputStream os = new FileOutputStream(tmpFile)) {
+            final XmlSerializer serializer = Xml.newSerializer();
+            serializer.setOutput(os, "UTF-8");
+            serializer.startDocument(null, true);
+            serializer.startTag(null, TASK_TAG);
+            r.saveToXml(serializer);
+            serializer.endTag(null, TASK_TAG);
+            serializer.endDocument();
+        }
+
+        return tmpFile;
+    }
+
+    private TaskRecord restoreFromFile(File file) throws IOException, XmlPullParserException {
+        try (final Reader reader = new BufferedReader(new FileReader(file))) {
+            final XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(reader);
+            assertEquals(XmlPullParser.START_TAG, parser.next());
+            assertEquals(TASK_TAG, parser.getName());
+            return TaskRecord.restoreFromXml(parser, mService.mStackSupervisor);
+        }
+    }
+
+    private TaskRecord createTaskRecord(int taskId) {
+        return new TaskRecord(mService, taskId, new Intent(), null, null, null, null, null, false,
+                false, false, 0, 10050, null, new ArrayList<>(), 0, false, null, 0, 0, 0, 0, 0,
+                null, 0, false, false, false, 0, 0);
+    }
+
+    private static class TestTaskRecordFactory extends TaskRecordFactory {
+        private boolean mCreated = false;
+
+        @Override
+        TaskRecord create(ActivityManagerService service, int taskId, ActivityInfo info,
+                Intent intent,
+                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
+            mCreated = true;
+            return null;
+        }
+
+        @Override
+        TaskRecord create(ActivityManagerService service, int taskId, ActivityInfo info,
+                Intent intent,
+                ActivityManager.TaskDescription taskDescription) {
+            mCreated = true;
+            return null;
+        }
+
+        @Override
+        TaskRecord create(ActivityManagerService service, int taskId, Intent intent,
+                Intent affinityIntent, String affinity, String rootAffinity,
+                ComponentName realActivity,
+                ComponentName origActivity, boolean rootWasReset, boolean autoRemoveRecents,
+                boolean askedCompatMode, int userId, int effectiveUid, String lastDescription,
+                ArrayList<ActivityRecord> activities, long lastTimeMoved,
+                boolean neverRelinquishIdentity,
+                ActivityManager.TaskDescription lastTaskDescription,
+                int taskAffiliation, int prevTaskId, int nextTaskId, int taskAffiliationColor,
+                int callingUid, String callingPackage, int resizeMode,
+                boolean supportsPictureInPicture,
+                boolean realActivitySuspended, boolean userSetupComplete, int minWidth,
+                int minHeight) {
+            mCreated = true;
+            return null;
+        }
+
+        @Override
+        TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
+                throws IOException, XmlPullParserException {
+            mCreated = true;
+            return null;
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java b/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
new file mode 100644
index 0000000..0359096
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityManager.TaskDescription;
+import android.app.IActivityManager;
+import android.app.ITaskStackListener;
+import android.app.Instrumentation.ActivityMonitor;
+import android.app.TaskStackListener;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.res.Resources.Theme;
+import android.os.RemoteException;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.UiDevice;
+import android.text.TextUtils;
+import android.util.Pair;
+import com.android.internal.annotations.GuardedBy;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class TaskStackChangedListenerTest {
+
+    private IActivityManager mService;
+    private ITaskStackListener mTaskStackListener;
+
+    private static final Object sLock = new Object();
+    @GuardedBy("sLock")
+    private static boolean sTaskStackChangedCalled;
+    private static boolean sActivityBResumed;
+
+    @Before
+    public void setUp() throws Exception {
+        mService = ActivityManager.getService();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mService.unregisterTaskStackListener(mTaskStackListener);
+        mTaskStackListener = null;
+    }
+
+    @Test
+    public void testTaskStackChanged_afterFinish() throws Exception {
+        registerTaskStackChangedListener(new TaskStackListener() {
+            @Override
+            public void onTaskStackChanged() throws RemoteException {
+                synchronized (sLock) {
+                    sTaskStackChangedCalled = true;
+                }
+            }
+        });
+
+        Context ctx = InstrumentationRegistry.getContext();
+        ctx.startActivity(new Intent(ctx, ActivityA.class));
+        UiDevice.getInstance(getInstrumentation()).waitForIdle();
+        synchronized (sLock) {
+            Assert.assertTrue(sTaskStackChangedCalled);
+        }
+        Assert.assertTrue(sActivityBResumed);
+    }
+
+    @Test
+    public void testTaskDescriptionChanged() throws Exception {
+        final Object[] params = new Object[2];
+        final CountDownLatch latch = new CountDownLatch(1);
+        registerTaskStackChangedListener(new TaskStackListener() {
+            int taskId = -1;
+
+            @Override
+            public void onTaskCreated(int taskId, ComponentName componentName)
+                    throws RemoteException {
+                this.taskId = taskId;
+            }
+            @Override
+            public void onTaskDescriptionChanged(int taskId, TaskDescription td)
+                    throws RemoteException {
+                if (this.taskId == taskId && !TextUtils.isEmpty(td.getLabel())) {
+                    params[0] = taskId;
+                    params[1] = td;
+                    latch.countDown();
+                }
+            }
+        });
+        final Activity activity = startTestActivity(ActivityTaskDescriptionChange.class);
+        waitForCallback(latch);
+        assertEquals(activity.getTaskId(), params[0]);
+        assertEquals("Test Label", ((TaskDescription) params[1]).getLabel());
+    }
+
+    @Test
+    public void testActivityRequestedOrientationChanged() throws Exception {
+        final int[] params = new int[2];
+        final CountDownLatch latch = new CountDownLatch(1);
+        registerTaskStackChangedListener(new TaskStackListener() {
+            @Override
+            public void onActivityRequestedOrientationChanged(int taskId,
+                    int requestedOrientation) {
+                params[0] = taskId;
+                params[1] = requestedOrientation;
+                latch.countDown();
+            }
+        });
+        final Activity activity = startTestActivity(ActivityRequestedOrientationChange.class);
+        waitForCallback(latch);
+        assertEquals(activity.getTaskId(), params[0]);
+        assertEquals(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT, params[1]);
+    }
+
+    @Test
+    /**
+     * Tests for onTaskCreated, onTaskMovedToFront, onTaskRemoved and onTaskRemovalStarted.
+     */
+    public void testTaskChangeCallBacks() throws Exception {
+        final Object[] params = new Object[2];
+        final CountDownLatch taskCreatedLaunchLatch = new CountDownLatch(1);
+        final CountDownLatch taskMovedToFrontLatch = new CountDownLatch(1);
+        final CountDownLatch taskRemovedLatch = new CountDownLatch(1);
+        final CountDownLatch taskRemovalStartedLatch = new CountDownLatch(1);
+        final CountDownLatch onDetachedFromWindowLatch = new CountDownLatch(1);
+        registerTaskStackChangedListener(new TaskStackListener() {
+            @Override
+            public void onTaskCreated(int taskId, ComponentName componentName)
+                    throws RemoteException {
+                params[0] = taskId;
+                params[1] = componentName;
+                taskCreatedLaunchLatch.countDown();
+            }
+
+            @Override
+            public void onTaskMovedToFront(int taskId) throws RemoteException {
+                params[0] = taskId;
+                taskMovedToFrontLatch.countDown();
+            }
+
+            @Override
+            public void onTaskRemovalStarted(int taskId) {
+                params[0] = taskId;
+                taskRemovalStartedLatch.countDown();
+            }
+
+            @Override
+            public void onTaskRemoved(int taskId) throws RemoteException {
+                params[0] = taskId;
+                taskRemovedLatch.countDown();
+            }
+        });
+
+        final ActivityTaskChangeCallbacks activity =
+                (ActivityTaskChangeCallbacks) startTestActivity(ActivityTaskChangeCallbacks.class);
+        final int id = activity.getTaskId();
+
+        // Test for onTaskCreated.
+        waitForCallback(taskCreatedLaunchLatch);
+        assertEquals(id, params[0]);
+        ComponentName componentName = (ComponentName) params[1];
+        assertEquals(ActivityTaskChangeCallbacks.class.getName(), componentName.getClassName());
+
+        // Test for onTaskMovedToFront.
+        assertEquals(1, taskMovedToFrontLatch.getCount());
+        mService.moveTaskToFront(id, 0, null);
+        waitForCallback(taskMovedToFrontLatch);
+        assertEquals(activity.getTaskId(), params[0]);
+
+        // Test for onTaskRemovalStarted.
+        assertEquals(1, taskRemovalStartedLatch.getCount());
+        activity.finishAndRemoveTask();
+        waitForCallback(taskRemovalStartedLatch);
+        // onTaskRemovalStarted happens before the activity's window is removed.
+        assertFalse(activity.onDetachedFromWindowCalled);
+        assertEquals(id, params[0]);
+
+        // Test for onTaskRemoved.
+        assertEquals(1, taskRemovedLatch.getCount());
+        waitForCallback(taskRemovedLatch);
+        assertEquals(id, params[0]);
+        assertTrue(activity.onDetachedFromWindowCalled);
+    }
+
+    /**
+     * Starts the provided activity and returns the started instance.
+     */
+    private Activity startTestActivity(Class<?> activityClass) {
+        final Context context = InstrumentationRegistry.getContext();
+        final ActivityMonitor monitor =
+                new ActivityMonitor(activityClass.getName(), null, false);
+        InstrumentationRegistry.getInstrumentation().addMonitor(monitor);
+        context.startActivity(new Intent(context, activityClass));
+        final Activity activity = monitor.waitForActivityWithTimeout(1000);
+        if (activity == null) {
+            throw new RuntimeException("Timed out waiting for Activity");
+        }
+        return activity;
+    }
+
+    private void registerTaskStackChangedListener(ITaskStackListener listener) throws Exception {
+        mTaskStackListener = listener;
+        mService.registerTaskStackListener(listener);
+    }
+
+    private void waitForCallback(CountDownLatch latch) {
+        try {
+        final boolean result = latch.await(2, TimeUnit.SECONDS);
+            if (!result) {
+                throw new RuntimeException("Timed out waiting for task stack change notification");
+            }
+        }catch (InterruptedException e) {}
+    }
+
+    public static class ActivityA extends Activity {
+
+        private boolean mActivityBLaunched = false;
+
+        @Override
+        protected void onPostResume() {
+            super.onPostResume();
+            if (mActivityBLaunched) {
+                return;
+            }
+            mActivityBLaunched = true;
+            finish();
+            startActivity(new Intent(this, ActivityB.class));
+        }
+    }
+
+    public static class ActivityB extends Activity {
+
+        @Override
+        protected void onPostResume() {
+            super.onPostResume();
+            synchronized (sLock) {
+                sTaskStackChangedCalled = false;
+            }
+            sActivityBResumed = true;
+            finish();
+        }
+    }
+
+    public static class ActivityRequestedOrientationChange extends Activity {
+        @Override
+        protected void onPostResume() {
+            super.onPostResume();
+            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+            finish();
+        }
+    }
+
+    public static class ActivityTaskDescriptionChange extends Activity {
+        @Override
+        protected void onPostResume() {
+            super.onPostResume();
+            setTaskDescription(new TaskDescription("Test Label"));
+            finish();
+        }
+    }
+
+    public static class ActivityTaskChangeCallbacks extends Activity {
+        public boolean onDetachedFromWindowCalled = false;;
+
+        @Override
+        public void onDetachedFromWindow() {
+            onDetachedFromWindowCalled = true;
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
new file mode 100644
index 0000000..cc4f519
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -0,0 +1,441 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import android.app.IUserSwitchObserver;
+import android.content.Context;
+import android.content.IIntentReceiver;
+import android.content.Intent;
+import android.content.pm.UserInfo;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IRemoteCallback;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.UserManagerInternal;
+import android.platform.test.annotations.Presubmit;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+
+import com.android.server.pm.UserManagerService;
+import com.android.server.wm.WindowManagerService;
+
+import org.mockito.Mockito;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader;
+import static com.android.server.am.UserController.CONTINUE_USER_SWITCH_MSG;
+import static com.android.server.am.UserController.REPORT_LOCKED_BOOT_COMPLETE_MSG;
+import static com.android.server.am.UserController.REPORT_USER_SWITCH_COMPLETE_MSG;
+import static com.android.server.am.UserController.REPORT_USER_SWITCH_MSG;
+import static com.android.server.am.UserController.SYSTEM_USER_CURRENT_MSG;
+import static com.android.server.am.UserController.SYSTEM_USER_START_MSG;
+import static com.android.server.am.UserController.USER_SWITCH_TIMEOUT_MSG;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.when;
+
+/**
+ * Usage: bit FrameworksServicesTests:com.android.server.am.UserControllerTest
+ */
+@Presubmit
+public class UserControllerTest extends AndroidTestCase {
+    private static final int TEST_USER_ID = 10;
+    private static final int NONEXIST_USER_ID = 2;
+    private static String TAG = UserControllerTest.class.getSimpleName();
+    private UserController mUserController;
+    private TestInjector mInjector;
+
+    private static final List<String> START_FOREGROUND_USER_ACTIONS =
+            Arrays.asList(
+                    Intent.ACTION_USER_STARTED,
+                    Intent.ACTION_USER_SWITCHED,
+                    Intent.ACTION_USER_STARTING);
+
+    private static final List<String> START_BACKGROUND_USER_ACTIONS =
+            Arrays.asList(
+                    Intent.ACTION_USER_STARTED,
+                    Intent.ACTION_LOCKED_BOOT_COMPLETED,
+                    Intent.ACTION_USER_STARTING);
+
+    private static final Set<Integer> START_FOREGROUND_USER_MESSAGE_CODES =
+            new HashSet<>(Arrays.asList(REPORT_USER_SWITCH_MSG, USER_SWITCH_TIMEOUT_MSG,
+                    SYSTEM_USER_START_MSG, SYSTEM_USER_CURRENT_MSG));
+
+    private static final Set<Integer> START_BACKGROUND_USER_MESSAGE_CODES =
+            new HashSet<>(Arrays.asList(SYSTEM_USER_START_MSG, REPORT_LOCKED_BOOT_COMPLETE_MSG));
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        runWithDexmakerShareClassLoader(() -> {
+            mInjector = Mockito.spy(new TestInjector(getContext()));
+            doNothing().when(mInjector).clearAllLockedTasks(anyString());
+            doNothing().when(mInjector).startHomeActivity(anyInt(), anyString());
+            doReturn(false).when(mInjector).stackSupervisorSwitchUser(anyInt(), any());
+            doNothing().when(mInjector).stackSupervisorResumeFocusedStackTopActivity();
+            mUserController = new UserController(mInjector);
+            setUpUser(TEST_USER_ID, 0);
+        });
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mInjector.handlerThread.quit();
+        Mockito.validateMockitoUsage();
+    }
+
+    @SmallTest
+    public void testStartUser_foreground() throws RemoteException {
+        mUserController.startUser(TEST_USER_ID, true /* foreground */);
+        Mockito.verify(mInjector.getWindowManager()).startFreezingScreen(anyInt(), anyInt());
+        Mockito.verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
+        Mockito.verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(anyBoolean());
+        Mockito.verify(mInjector.getWindowManager()).setSwitchingUser(true);
+        Mockito.verify(mInjector).clearAllLockedTasks(anyString());
+        startForegroundUserAssertions();
+    }
+
+    @SmallTest
+    public void testStartUser_background() throws RemoteException {
+        mUserController.startUser(TEST_USER_ID, false /* foreground */);
+        Mockito.verify(
+                mInjector.getWindowManager(), never()).startFreezingScreen(anyInt(), anyInt());
+        Mockito.verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
+        Mockito.verify(mInjector, never()).clearAllLockedTasks(anyString());
+        startBackgroundUserAssertions();
+    }
+
+    @SmallTest
+    public void testStartUserUIDisabled() throws RemoteException {
+        mUserController.mUserSwitchUiEnabled = false;
+        mUserController.startUser(TEST_USER_ID, true /* foreground */);
+        Mockito.verify(mInjector.getWindowManager(), never())
+                .startFreezingScreen(anyInt(), anyInt());
+        Mockito.verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
+        Mockito.verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
+        startForegroundUserAssertions();
+    }
+
+    private void startUserAssertions(
+            List<String> expectedActions, Set<Integer> expectedMessageCodes)
+            throws RemoteException {
+        assertEquals(expectedActions, getActions(mInjector.sentIntents));
+        Set<Integer> actualCodes = mInjector.handler.getMessageCodes();
+        assertEquals("Unexpected message sent", expectedMessageCodes, actualCodes);
+    }
+
+    private void startBackgroundUserAssertions() throws RemoteException {
+        startUserAssertions(START_BACKGROUND_USER_ACTIONS, START_BACKGROUND_USER_MESSAGE_CODES);
+    }
+
+    private void startForegroundUserAssertions() throws RemoteException {
+        startUserAssertions(START_FOREGROUND_USER_ACTIONS, START_FOREGROUND_USER_MESSAGE_CODES);
+        Message reportMsg = mInjector.handler.getMessageForCode(REPORT_USER_SWITCH_MSG);
+        assertNotNull(reportMsg);
+        UserState userState = (UserState) reportMsg.obj;
+        assertNotNull(userState);
+        assertEquals(TEST_USER_ID, userState.mHandle.getIdentifier());
+        assertEquals("User must be in STATE_BOOTING", UserState.STATE_BOOTING, userState.state);
+        assertEquals("Unexpected old user id", 0, reportMsg.arg1);
+        assertEquals("Unexpected new user id", TEST_USER_ID, reportMsg.arg2);
+    }
+
+    @SmallTest
+    public void testFailedStartUserInForeground() throws RemoteException {
+        mUserController.mUserSwitchUiEnabled = false;
+        mUserController.startUserInForeground(NONEXIST_USER_ID);
+        Mockito.verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(anyBoolean());
+        Mockito.verify(mInjector.getWindowManager()).setSwitchingUser(false);
+    }
+
+    @SmallTest
+    public void testDispatchUserSwitch() throws RemoteException {
+        // Prepare mock observer and register it
+        IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
+        when(observer.asBinder()).thenReturn(new Binder());
+        doAnswer(invocation -> {
+            IRemoteCallback callback = (IRemoteCallback) invocation.getArguments()[1];
+            callback.sendResult(null);
+            return null;
+        }).when(observer).onUserSwitching(anyInt(), any());
+        mUserController.registerUserSwitchObserver(observer, "mock");
+        // Start user -- this will update state of mUserController
+        mUserController.startUser(TEST_USER_ID, true);
+        Message reportMsg = mInjector.handler.getMessageForCode(REPORT_USER_SWITCH_MSG);
+        assertNotNull(reportMsg);
+        UserState userState = (UserState) reportMsg.obj;
+        int oldUserId = reportMsg.arg1;
+        int newUserId = reportMsg.arg2;
+        // Call dispatchUserSwitch and verify that observer was called only once
+        mInjector.handler.clearAllRecordedMessages();
+        mUserController.dispatchUserSwitch(userState, oldUserId, newUserId);
+        Mockito.verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any());
+        Set<Integer> expectedCodes = Collections.singleton(CONTINUE_USER_SWITCH_MSG);
+        Set<Integer> actualCodes = mInjector.handler.getMessageCodes();
+        assertEquals("Unexpected message sent", expectedCodes, actualCodes);
+        Message conMsg = mInjector.handler.getMessageForCode(CONTINUE_USER_SWITCH_MSG);
+        assertNotNull(conMsg);
+        userState = (UserState) conMsg.obj;
+        assertNotNull(userState);
+        assertEquals(TEST_USER_ID, userState.mHandle.getIdentifier());
+        assertEquals("User must be in STATE_BOOTING", UserState.STATE_BOOTING, userState.state);
+        assertEquals("Unexpected old user id", 0, conMsg.arg1);
+        assertEquals("Unexpected new user id", TEST_USER_ID, conMsg.arg2);
+    }
+
+    @SmallTest
+    public void testDispatchUserSwitchBadReceiver() throws RemoteException {
+        // Prepare mock observer which doesn't notify the callback and register it
+        IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
+        when(observer.asBinder()).thenReturn(new Binder());
+        mUserController.registerUserSwitchObserver(observer, "mock");
+        // Start user -- this will update state of mUserController
+        mUserController.startUser(TEST_USER_ID, true);
+        Message reportMsg = mInjector.handler.getMessageForCode(REPORT_USER_SWITCH_MSG);
+        assertNotNull(reportMsg);
+        UserState userState = (UserState) reportMsg.obj;
+        int oldUserId = reportMsg.arg1;
+        int newUserId = reportMsg.arg2;
+        // Call dispatchUserSwitch and verify that observer was called only once
+        mInjector.handler.clearAllRecordedMessages();
+        mUserController.dispatchUserSwitch(userState, oldUserId, newUserId);
+        Mockito.verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any());
+        // Verify that CONTINUE_USER_SWITCH_MSG is not sent (triggers timeout)
+        Set<Integer> actualCodes = mInjector.handler.getMessageCodes();
+        assertTrue("No messages should be sent", actualCodes.isEmpty());
+    }
+
+    @SmallTest
+    public void testContinueUserSwitch() throws RemoteException {
+        // Start user -- this will update state of mUserController
+        mUserController.startUser(TEST_USER_ID, true);
+        Message reportMsg = mInjector.handler.getMessageForCode(REPORT_USER_SWITCH_MSG);
+        assertNotNull(reportMsg);
+        UserState userState = (UserState) reportMsg.obj;
+        int oldUserId = reportMsg.arg1;
+        int newUserId = reportMsg.arg2;
+        mInjector.handler.clearAllRecordedMessages();
+        // Verify that continueUserSwitch worked as expected
+        mUserController.continueUserSwitch(userState, oldUserId, newUserId);
+        Mockito.verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen();
+        continueUserSwitchAssertions();
+    }
+
+    @SmallTest
+    public void testContinueUserSwitchUIDisabled() throws RemoteException {
+        mUserController.mUserSwitchUiEnabled = false;
+        // Start user -- this will update state of mUserController
+        mUserController.startUser(TEST_USER_ID, true);
+        Message reportMsg = mInjector.handler.getMessageForCode(REPORT_USER_SWITCH_MSG);
+        assertNotNull(reportMsg);
+        UserState userState = (UserState) reportMsg.obj;
+        int oldUserId = reportMsg.arg1;
+        int newUserId = reportMsg.arg2;
+        mInjector.handler.clearAllRecordedMessages();
+        // Verify that continueUserSwitch worked as expected
+        mUserController.continueUserSwitch(userState, oldUserId, newUserId);
+        Mockito.verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
+        continueUserSwitchAssertions();
+    }
+
+    private void continueUserSwitchAssertions() throws RemoteException {
+        Set<Integer> expectedCodes = Collections.singleton(REPORT_USER_SWITCH_COMPLETE_MSG);
+        Set<Integer> actualCodes = mInjector.handler.getMessageCodes();
+        assertEquals("Unexpected message sent", expectedCodes, actualCodes);
+        Message msg = mInjector.handler.getMessageForCode(REPORT_USER_SWITCH_COMPLETE_MSG);
+        assertNotNull(msg);
+        assertEquals("Unexpected userId", TEST_USER_ID, msg.arg1);
+    }
+
+    @SmallTest
+    public void testDispatchUserSwitchComplete() throws RemoteException {
+        // Prepare mock observer and register it
+        IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
+        when(observer.asBinder()).thenReturn(new Binder());
+        mUserController.registerUserSwitchObserver(observer, "mock");
+        // Start user -- this will update state of mUserController
+        mUserController.startUser(TEST_USER_ID, true);
+        Message reportMsg = mInjector.handler.getMessageForCode(REPORT_USER_SWITCH_MSG);
+        assertNotNull(reportMsg);
+        int newUserId = reportMsg.arg2;
+        mInjector.handler.clearAllRecordedMessages();
+        // Mockito can't reset only interactions, so just verify that this hasn't been
+        // called with 'false' until after dispatchUserSwitchComplete.
+        Mockito.verify(mInjector.getWindowManager(), never()).setSwitchingUser(false);
+        // Call dispatchUserSwitchComplete
+        mUserController.dispatchUserSwitchComplete(newUserId);
+        Mockito.verify(observer, times(1)).onUserSwitchComplete(anyInt());
+        Mockito.verify(observer).onUserSwitchComplete(TEST_USER_ID);
+        Mockito.verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(false);
+    }
+
+    private void setUpUser(int userId, int flags) {
+        UserInfo userInfo = new UserInfo(userId, "User" + userId, flags);
+        when(mInjector.userManagerMock.getUserInfo(eq(userId))).thenReturn(userInfo);
+    }
+
+    private static List<String> getActions(List<Intent> intents) {
+        List<String> result = new ArrayList<>();
+        for (Intent intent : intents) {
+            result.add(intent.getAction());
+        }
+        return result;
+    }
+
+    // Should be public to allow mocking
+    public static class TestInjector extends UserController.Injector {
+        TestHandler handler;
+        TestHandler uiHandler;
+        HandlerThread handlerThread;
+        UserManagerService userManagerMock;
+        UserManagerInternal userManagerInternalMock;
+        WindowManagerService windowManagerMock;
+        private Context mCtx;
+        List<Intent> sentIntents = new ArrayList<>();
+
+        TestInjector(Context ctx) {
+            super(null);
+            mCtx = ctx;
+            handlerThread = new HandlerThread(TAG);
+            handlerThread.start();
+            handler = new TestHandler(handlerThread.getLooper());
+            uiHandler = new TestHandler(handlerThread.getLooper());
+            userManagerMock = mock(UserManagerService.class);
+            userManagerInternalMock = mock(UserManagerInternal.class);
+            windowManagerMock = mock(WindowManagerService.class);
+        }
+
+        @Override
+        protected Handler getHandler(Handler.Callback callback) {
+            return handler;
+        }
+
+        @Override
+        protected Handler getUiHandler(Handler.Callback callback) {
+            return uiHandler;
+        }
+
+        @Override
+        protected UserManagerService getUserManager() {
+            return userManagerMock;
+        }
+
+        @Override
+        UserManagerInternal getUserManagerInternal() {
+            return userManagerInternalMock;
+        }
+
+        @Override
+        protected Context getContext() {
+            return mCtx;
+        }
+
+        @Override
+        int checkCallingPermission(String permission) {
+            Log.i(TAG, "checkCallingPermission " + permission);
+            return PERMISSION_GRANTED;
+        }
+
+        @Override
+        WindowManagerService getWindowManager() {
+            return windowManagerMock;
+        }
+
+        @Override
+        void updateUserConfiguration() {
+            Log.i(TAG, "updateUserConfiguration");
+        }
+
+        @Override
+        protected int broadcastIntent(Intent intent, String resolvedType,
+                IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras,
+                String[] requiredPermissions, int appOp, Bundle bOptions, boolean ordered,
+                boolean sticky, int callingPid, int callingUid, int userId) {
+            Log.i(TAG, "broadcastIntentLocked " + intent);
+            sentIntents.add(intent);
+            return 0;
+        }
+
+        @Override
+        void reportGlobalUsageEventLocked(int event) {
+        }
+
+        @Override
+        void reportCurWakefulnessUsageEvent() {
+        }
+    }
+
+    private static class TestHandler extends Handler {
+        private final List<Message> mMessages = new ArrayList<>();
+
+        TestHandler(Looper looper) {
+            super(looper);
+        }
+
+        Set<Integer> getMessageCodes() {
+            Set<Integer> result = new LinkedHashSet<>();
+            for (Message msg : mMessages) {
+                result.add(msg.what);
+            }
+            return result;
+        }
+
+        Message getMessageForCode(int what) {
+            for (Message msg : mMessages) {
+                if (msg.what == what) {
+                    return msg;
+                }
+            }
+            return null;
+        }
+
+        void clearAllRecordedMessages() {
+            mMessages.clear();
+        }
+
+        @Override
+        public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
+            Message copy = new Message();
+            copy.copyFrom(msg);
+            mMessages.add(copy);
+            return super.sendMessageAtTime(msg, uptimeMillis);
+        }
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java b/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java
new file mode 100644
index 0000000..7487d44
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.policy;
+
+import android.annotation.Nullable;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.util.proto.ProtoOutputStream;
+import android.view.Display;
+import android.view.DisplayCutout;
+import android.view.IApplicationToken;
+import android.view.WindowManager;
+
+import com.android.server.wm.utils.WmDisplayCutout;
+
+public class FakeWindowState implements WindowManagerPolicy.WindowState {
+
+    public final Rect parentFrame = new Rect();
+    public final Rect displayFrame = new Rect();
+    public final Rect overscanFrame = new Rect();
+    public final Rect contentFrame = new Rect();
+    public final Rect visibleFrame = new Rect();
+    public final Rect decorFrame = new Rect();
+    public final Rect stableFrame = new Rect();
+    public Rect outsetFrame = new Rect();
+
+    public WmDisplayCutout displayCutout;
+
+    public WindowManager.LayoutParams attrs;
+    public int displayId;
+    public boolean isVoiceInteraction;
+    public boolean inMultiWindowMode;
+    public boolean visible = true;
+    public int surfaceLayer = 1;
+    public boolean isDimming = false;
+
+    public boolean policyVisible = true;
+
+    @Override
+    public int getOwningUid() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public String getOwningPackage() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public void computeFrameLw(Rect parentFrame, Rect displayFrame, Rect overlayFrame,
+            Rect contentFrame, Rect visibleFrame, Rect decorFrame, Rect stableFrame,
+            @Nullable Rect outsetFrame, WmDisplayCutout displayCutout,
+            boolean parentFrameWasClippedByDisplayCutout) {
+        this.parentFrame.set(parentFrame);
+        this.displayFrame.set(displayFrame);
+        this.overscanFrame.set(overlayFrame);
+        this.contentFrame.set(contentFrame);
+        this.visibleFrame.set(visibleFrame);
+        this.decorFrame.set(decorFrame);
+        this.stableFrame.set(stableFrame);
+        this.outsetFrame = outsetFrame == null ? null : new Rect(outsetFrame);
+        this.displayCutout = displayCutout;
+    }
+
+    @Override
+    public Rect getFrameLw() {
+        return parentFrame;
+    }
+
+    @Override
+    public Rect getDisplayFrameLw() {
+        return displayFrame;
+    }
+
+    @Override
+    public Rect getOverscanFrameLw() {
+        return overscanFrame;
+    }
+
+    @Override
+    public Rect getContentFrameLw() {
+        return contentFrame;
+    }
+
+    @Override
+    public Rect getVisibleFrameLw() {
+        return visibleFrame;
+    }
+
+    @Override
+    public boolean getGivenInsetsPendingLw() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public Rect getGivenContentInsetsLw() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public Rect getGivenVisibleInsetsLw() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public WindowManager.LayoutParams getAttrs() {
+        return attrs;
+    }
+
+    @Override
+    public boolean getNeedsMenuLw(WindowManagerPolicy.WindowState bottom) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public int getSystemUiVisibility() {
+        return attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility;
+    }
+
+    @Override
+    public int getSurfaceLayer() {
+        return surfaceLayer;
+    }
+
+    @Override
+    public int getBaseType() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public IApplicationToken getAppToken() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public boolean isVoiceInteraction() {
+        return isVoiceInteraction;
+    }
+
+    @Override
+    public boolean hasAppShownWindows() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public boolean isVisibleLw() {
+        return visible && policyVisible;
+    }
+
+    @Override
+    public boolean isDisplayedLw() {
+        return isVisibleLw();
+    }
+
+    @Override
+    public boolean isAnimatingLw() {
+        return false;
+    }
+
+    @Override
+    public boolean canAffectSystemUiFlags() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public boolean isGoneForLayoutLw() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public boolean isDrawnLw() {
+        return true;
+    }
+
+    @Override
+    public boolean hasDrawnLw() {
+        return true;
+    }
+
+    @Override
+    public boolean hideLw(boolean doAnimation) {
+        if (!policyVisible) {
+            return false;
+        }
+        policyVisible = false;
+        return true;
+    }
+
+    @Override
+    public boolean showLw(boolean doAnimation) {
+        if (policyVisible) {
+            return false;
+        }
+        policyVisible = true;
+        return true;
+    }
+
+    @Override
+    public boolean isAlive() {
+        return true;
+    }
+
+    @Override
+    public boolean isDefaultDisplay() {
+        return displayId == Display.DEFAULT_DISPLAY;
+    }
+
+    @Override
+    public boolean isDimming() {
+        return isDimming;
+    }
+
+    @Override
+    public int getWindowingMode() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public boolean isInMultiWindowMode() {
+        return inMultiWindowMode;
+    }
+
+    @Override
+    public int getRotationAnimationHint() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public boolean isInputMethodWindow() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public int getDisplayId() {
+        return displayId;
+    }
+
+    @Override
+    public boolean canAcquireSleepToken() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public void writeIdentifierToProto(ProtoOutputStream proto, long fieldId){
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    public boolean isInputMethodTarget() {
+        return false;
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerInsetsTest.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerInsetsTest.java
new file mode 100644
index 0000000..7e18ce7
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerInsetsTest.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.policy;
+
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.Display;
+import android.view.DisplayInfo;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ErrorCollector;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class PhoneWindowManagerInsetsTest extends PhoneWindowManagerTestBase {
+
+    @Rule
+    public final ErrorCollector mErrorCollector = new ErrorCollector();
+
+    @Before
+    public void setUp() throws Exception {
+        addStatusBar();
+        addNavigationBar();
+    }
+
+    @Test
+    public void portrait() throws Exception {
+        DisplayInfo di = displayInfoForRotation(ROTATION_0, false /* withCutout */);
+
+        verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
+        verifyNonDecorInsets(di, 0, 0, 0, NAV_BAR_HEIGHT);
+        verifyConsistency(di);
+    }
+
+    @Test
+    public void portrait_withCutout() throws Exception {
+        DisplayInfo di = displayInfoForRotation(ROTATION_0, true /* withCutout */);
+
+        verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
+        verifyNonDecorInsets(di, 0, DISPLAY_CUTOUT_HEIGHT, 0, NAV_BAR_HEIGHT);
+        verifyConsistency(di);
+    }
+
+    @Test
+    public void landscape() throws Exception {
+        DisplayInfo di = displayInfoForRotation(ROTATION_90, false /* withCutout */);
+
+        verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+        verifyNonDecorInsets(di, 0, 0, NAV_BAR_HEIGHT, 0);
+        verifyConsistency(di);
+    }
+
+    @Test
+    public void landscape_withCutout() throws Exception {
+        DisplayInfo di = displayInfoForRotation(ROTATION_90, true /* withCutout */);
+
+        verifyStableInsets(di, DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+        verifyNonDecorInsets(di, DISPLAY_CUTOUT_HEIGHT, 0, NAV_BAR_HEIGHT, 0);
+        verifyConsistency(di);
+    }
+
+    @Test
+    public void seascape() throws Exception {
+        DisplayInfo di = displayInfoForRotation(ROTATION_270, false /* withCutout */);
+
+        verifyStableInsets(di, NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0);
+        verifyNonDecorInsets(di, NAV_BAR_HEIGHT, 0, 0, 0);
+        verifyConsistency(di);
+    }
+
+    @Test
+    public void seascape_withCutout() throws Exception {
+        DisplayInfo di = displayInfoForRotation(ROTATION_270, true /* withCutout */);
+
+        verifyStableInsets(di, NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0);
+        verifyNonDecorInsets(di, NAV_BAR_HEIGHT, 0, DISPLAY_CUTOUT_HEIGHT, 0);
+        verifyConsistency(di);
+    }
+
+    @Test
+    public void upsideDown() throws Exception {
+        DisplayInfo di = displayInfoForRotation(ROTATION_180, false /* withCutout */);
+
+        verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
+        verifyNonDecorInsets(di, 0, 0, 0, NAV_BAR_HEIGHT);
+        verifyConsistency(di);
+    }
+
+    @Test
+    public void upsideDown_withCutout() throws Exception {
+        DisplayInfo di = displayInfoForRotation(ROTATION_180, true /* withCutout */);
+
+        verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT + DISPLAY_CUTOUT_HEIGHT);
+        verifyNonDecorInsets(di, 0, 0, 0, NAV_BAR_HEIGHT + DISPLAY_CUTOUT_HEIGHT);
+        verifyConsistency(di);
+    }
+
+    private void verifyStableInsets(DisplayInfo di, int left, int top, int right, int bottom) {
+        mErrorCollector.checkThat("stableInsets", getStableInsetsLw(di), equalTo(new Rect(
+                left, top, right, bottom)));
+    }
+
+    private void verifyNonDecorInsets(DisplayInfo di, int left, int top, int right, int bottom) {
+        mErrorCollector.checkThat("nonDecorInsets", getNonDecorInsetsLw(di), equalTo(new Rect(
+                left, top, right, bottom)));
+    }
+
+    private void verifyConsistency(DisplayInfo di) {
+        verifyConsistency("configDisplay", di, getStableInsetsLw(di),
+                getConfigDisplayWidth(di), getConfigDisplayHeight(di));
+        verifyConsistency("nonDecorDisplay", di, getNonDecorInsetsLw(di),
+                getNonDecorDisplayWidth(di), getNonDecorDisplayHeight(di));
+    }
+
+    private void verifyConsistency(String what, DisplayInfo di, Rect insets, int width,
+            int height) {
+        mErrorCollector.checkThat(what + ":width", width,
+                equalTo(di.logicalWidth - insets.left - insets.right));
+        mErrorCollector.checkThat(what + ":height", height,
+                equalTo(di.logicalHeight - insets.top - insets.bottom));
+    }
+
+    private Rect getStableInsetsLw(DisplayInfo di) {
+        Rect result = new Rect();
+        mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
+                di.displayCutout, result);
+        return result;
+    }
+
+    private Rect getNonDecorInsetsLw(DisplayInfo di) {
+        Rect result = new Rect();
+        mPolicy.getNonDecorInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
+                di.displayCutout, result);
+        return result;
+    }
+
+    private int getNonDecorDisplayWidth(DisplayInfo di) {
+        return mPolicy.getNonDecorDisplayWidth(di.logicalWidth, di.logicalHeight, di.rotation,
+                0 /* ui */, Display.DEFAULT_DISPLAY, di.displayCutout);
+    }
+
+    private int getNonDecorDisplayHeight(DisplayInfo di) {
+        return mPolicy.getNonDecorDisplayHeight(di.logicalWidth, di.logicalHeight, di.rotation,
+                0 /* ui */, Display.DEFAULT_DISPLAY, di.displayCutout);
+    }
+
+    private int getConfigDisplayWidth(DisplayInfo di) {
+        return mPolicy.getConfigDisplayWidth(di.logicalWidth, di.logicalHeight, di.rotation,
+                0 /* ui */, Display.DEFAULT_DISPLAY, di.displayCutout);
+    }
+
+    private int getConfigDisplayHeight(DisplayInfo di) {
+        return mPolicy.getConfigDisplayHeight(di.logicalWidth, di.logicalHeight, di.rotation,
+                0 /* ui */, Display.DEFAULT_DISPLAY, di.displayCutout);
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java
new file mode 100644
index 0000000..97a716f
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.policy;
+
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
+import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
+import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.DisplayCutout;
+import android.view.WindowManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class PhoneWindowManagerLayoutTest extends PhoneWindowManagerTestBase {
+
+    private FakeWindowState mAppWindow;
+
+    @Before
+    public void setUp() throws Exception {
+        mAppWindow = new FakeWindowState();
+        mAppWindow.attrs = new WindowManager.LayoutParams(MATCH_PARENT, MATCH_PARENT,
+                TYPE_APPLICATION,
+                FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
+                PixelFormat.TRANSLUCENT);
+
+        addStatusBar();
+        addNavigationBar();
+    }
+
+    @Test
+    public void layoutWindowLw_appDrawsBars() throws Exception {
+        mAppWindow.attrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+        mPolicy.addWindow(mAppWindow);
+
+        mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        mPolicy.layoutWindowLw(mAppWindow, null, mFrames);
+
+        assertInsetByTopBottom(mAppWindow.parentFrame, 0, 0);
+        assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetBy(mAppWindow.displayFrame, 0, 0, 0, 0);
+    }
+
+    @Test
+    public void layoutWindowLw_appWontDrawBars() throws Exception {
+        mAppWindow.attrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+        mPolicy.addWindow(mAppWindow);
+
+        mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        mPolicy.layoutWindowLw(mAppWindow, null, mFrames);
+
+        assertInsetByTopBottom(mAppWindow.parentFrame, 0, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.decorFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.displayFrame, 0, NAV_BAR_HEIGHT);
+    }
+
+    @Test
+    public void layoutWindowLw_appWontDrawBars_forceStatus() throws Exception {
+        mAppWindow.attrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+        mAppWindow.attrs.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+        mPolicy.addWindow(mAppWindow);
+
+        mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        mPolicy.layoutWindowLw(mAppWindow, null, mFrames);
+
+        assertInsetByTopBottom(mAppWindow.parentFrame, 0, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.decorFrame, 0, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.displayFrame, 0, NAV_BAR_HEIGHT);
+    }
+
+    @Test
+    public void addingWindow_doesNotTamperWithSysuiFlags() {
+        mAppWindow.attrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+        mPolicy.addWindow(mAppWindow);
+
+        assertEquals(0, mAppWindow.attrs.systemUiVisibility);
+        assertEquals(0, mAppWindow.attrs.subtreeSystemUiVisibility);
+    }
+
+    @Test
+    public void layoutWindowLw_withDisplayCutout() {
+        addDisplayCutout();
+
+        mPolicy.addWindow(mAppWindow);
+
+        mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        mPolicy.layoutWindowLw(mAppWindow, null, mFrames);
+
+        assertInsetByTopBottom(mAppWindow.parentFrame, 0, 0);
+        assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetByTopBottom(mAppWindow.displayFrame, 0, 0);
+    }
+
+    @Test
+    public void layoutWindowLw_withhDisplayCutout_never() {
+        addDisplayCutout();
+
+        mAppWindow.attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
+        mPolicy.addWindow(mAppWindow);
+
+        mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        mPolicy.layoutWindowLw(mAppWindow, null, mFrames);
+
+        assertInsetByTopBottom(mAppWindow.parentFrame, STATUS_BAR_HEIGHT, 0);
+        assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetByTopBottom(mAppWindow.displayFrame, STATUS_BAR_HEIGHT, 0);
+    }
+
+    @Test
+    public void layoutWindowLw_withDisplayCutout_layoutFullscreen() {
+        addDisplayCutout();
+
+        mAppWindow.attrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+        mPolicy.addWindow(mAppWindow);
+
+        mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        mPolicy.layoutWindowLw(mAppWindow, null, mFrames);
+
+        assertInsetByTopBottom(mAppWindow.parentFrame, 0, 0);
+        assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetBy(mAppWindow.displayFrame, 0, 0, 0, 0);
+    }
+
+    @Test
+    public void layoutWindowLw_withDisplayCutout_fullscreen() {
+        addDisplayCutout();
+
+        mAppWindow.attrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
+        mPolicy.addWindow(mAppWindow);
+
+        mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        mPolicy.layoutWindowLw(mAppWindow, null, mFrames);
+
+        assertInsetByTopBottom(mAppWindow.parentFrame, STATUS_BAR_HEIGHT, 0);
+        assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetByTopBottom(mAppWindow.displayFrame, STATUS_BAR_HEIGHT, 0);
+    }
+
+    @Test
+    public void layoutWindowLw_withDisplayCutout_fullscreenInCutout() {
+        addDisplayCutout();
+
+        mAppWindow.attrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
+        mAppWindow.attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+        mPolicy.addWindow(mAppWindow);
+
+        mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        mPolicy.layoutWindowLw(mAppWindow, null, mFrames);
+
+        assertInsetByTopBottom(mAppWindow.parentFrame, 0, 0);
+        assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+        assertInsetByTopBottom(mAppWindow.displayFrame, 0, 0);
+    }
+
+
+    @Test
+    public void layoutWindowLw_withDisplayCutout_landscape() {
+        addDisplayCutout();
+        setRotation(ROTATION_90);
+        mPolicy.addWindow(mAppWindow);
+
+        mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        mPolicy.layoutWindowLw(mAppWindow, null, mFrames);
+
+        assertInsetBy(mAppWindow.parentFrame, DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+        assertInsetBy(mAppWindow.stableFrame, 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+        assertInsetBy(mAppWindow.contentFrame,
+                DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+        assertInsetBy(mAppWindow.decorFrame, 0, 0, 0, 0);
+        assertInsetBy(mAppWindow.displayFrame, DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+    }
+
+    @Test
+    public void layoutWindowLw_withDisplayCutout_seascape() {
+        addDisplayCutout();
+        setRotation(ROTATION_270);
+        mPolicy.addWindow(mAppWindow);
+
+        mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        mPolicy.layoutWindowLw(mAppWindow, null, mFrames);
+
+        assertInsetBy(mAppWindow.parentFrame, 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
+        assertInsetBy(mAppWindow.stableFrame, NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0);
+        assertInsetBy(mAppWindow.contentFrame,
+                NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0);
+        assertInsetBy(mAppWindow.decorFrame, 0, 0, 0, 0);
+        assertInsetBy(mAppWindow.displayFrame, 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
+    }
+
+    @Test
+    public void layoutWindowLw_withDisplayCutout_fullscreen_landscape() {
+        addDisplayCutout();
+        setRotation(ROTATION_90);
+
+        mAppWindow.attrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+        mPolicy.addWindow(mAppWindow);
+
+        mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        mPolicy.layoutWindowLw(mAppWindow, null, mFrames);
+
+        assertInsetBy(mAppWindow.parentFrame, DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+        assertInsetBy(mAppWindow.stableFrame, 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+        assertInsetBy(mAppWindow.contentFrame,
+                DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+        assertInsetBy(mAppWindow.decorFrame, 0, 0, 0, 0);
+    }
+
+    @Test
+    public void layoutWindowLw_withDisplayCutout_floatingInScreen() {
+        addDisplayCutout();
+
+        mAppWindow.attrs.flags = FLAG_LAYOUT_IN_SCREEN;
+        mAppWindow.attrs.type = TYPE_APPLICATION_OVERLAY;
+        mAppWindow.attrs.width = DISPLAY_WIDTH;
+        mAppWindow.attrs.height = DISPLAY_HEIGHT;
+        mPolicy.addWindow(mAppWindow);
+
+        mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        mPolicy.layoutWindowLw(mAppWindow, null, mFrames);
+
+        assertInsetByTopBottom(mAppWindow.parentFrame, 0, NAV_BAR_HEIGHT);
+        assertInsetByTopBottom(mAppWindow.displayFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+    }
+
+    @Test
+    public void layoutWindowLw_withDisplayCutout_fullscreenInCutout_landscape() {
+        addDisplayCutout();
+        setRotation(ROTATION_90);
+
+        mAppWindow.attrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+        mAppWindow.attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+        mPolicy.addWindow(mAppWindow);
+
+        mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        mPolicy.layoutWindowLw(mAppWindow, null, mFrames);
+
+        assertInsetBy(mAppWindow.parentFrame, 0, 0, 0, 0);
+        assertInsetBy(mAppWindow.stableFrame, 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+        assertInsetBy(mAppWindow.contentFrame,
+                DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+        assertInsetBy(mAppWindow.decorFrame, 0, 0, 0, 0);
+    }
+
+    @Test
+    public void layoutHint_screenDecorWindow() {
+        addDisplayCutout();
+        mAppWindow.attrs.privateFlags |= PRIVATE_FLAG_IS_SCREEN_DECOR;
+
+        mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+
+        final Rect frame = new Rect();
+        final Rect content = new Rect();
+        final Rect stable = new Rect();
+        final Rect outsets = new Rect();
+        final DisplayCutout.ParcelableWrapper cutout = new DisplayCutout.ParcelableWrapper();
+        mPolicy.getLayoutHintLw(mAppWindow.attrs, null /* taskBounds */, mFrames, frame, content,
+                stable, outsets, cutout);
+
+        assertThat(frame, equalTo(mFrames.mUnrestricted));
+        assertThat(content, equalTo(new Rect()));
+        assertThat(stable, equalTo(new Rect()));
+        assertThat(outsets, equalTo(new Rect()));
+        assertThat(cutout.get(), equalTo(DisplayCutout.NO_CUTOUT));
+    }
+
+    @Test
+    public void layoutHint_appWindow() {
+        // Initialize DisplayFrames
+        mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+
+        final Rect outFrame = new Rect();
+        final Rect outContentInsets = new Rect();
+        final Rect outStableInsets = new Rect();
+        final Rect outOutsets = new Rect();
+        final DisplayCutout.ParcelableWrapper outDisplayCutout =
+                new DisplayCutout.ParcelableWrapper();
+
+        mPolicy.getLayoutHintLw(mAppWindow.attrs, null, mFrames, outFrame, outContentInsets,
+                outStableInsets, outOutsets, outDisplayCutout);
+
+        assertThat(outFrame, is(mFrames.mUnrestricted));
+        assertThat(outContentInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
+        assertThat(outStableInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
+        assertThat(outOutsets, is(new Rect()));
+        assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+    }
+
+    @Test
+    public void layoutHint_appWindowInTask() {
+        // Initialize DisplayFrames
+        mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+
+        final Rect taskBounds = new Rect(100, 100, 200, 200);
+
+        final Rect outFrame = new Rect();
+        final Rect outContentInsets = new Rect();
+        final Rect outStableInsets = new Rect();
+        final Rect outOutsets = new Rect();
+        final DisplayCutout.ParcelableWrapper outDisplayCutout =
+                new DisplayCutout.ParcelableWrapper();
+
+        mPolicy.getLayoutHintLw(mAppWindow.attrs, taskBounds, mFrames, outFrame, outContentInsets,
+                outStableInsets, outOutsets, outDisplayCutout);
+
+        assertThat(outFrame, is(taskBounds));
+        assertThat(outContentInsets, is(new Rect()));
+        assertThat(outStableInsets, is(new Rect()));
+        assertThat(outOutsets, is(new Rect()));
+        assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java
new file mode 100644
index 0000000..30665b5
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.policy;
+
+import static android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
+import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.DOCKED_BOTTOM;
+import static android.view.WindowManager.DOCKED_LEFT;
+import static android.view.WindowManager.DOCKED_RIGHT;
+import static android.view.WindowManager.DOCKED_TOP;
+
+import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_LEFT;
+import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM;
+import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_RIGHT;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.graphics.PixelFormat;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.WindowManager;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class PhoneWindowManagerTest {
+
+    private static FakeWindowState createOpaqueFullscreen(boolean hasLightNavBar) {
+        final FakeWindowState state = new FakeWindowState();
+        state.attrs = new WindowManager.LayoutParams(MATCH_PARENT, MATCH_PARENT,
+                TYPE_BASE_APPLICATION,
+                FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
+                PixelFormat.OPAQUE);
+        state.attrs.subtreeSystemUiVisibility =
+                hasLightNavBar ? SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR : 0;
+        return state;
+    }
+
+    private static FakeWindowState createDimmingDialogWindow(boolean canBeImTarget) {
+        final FakeWindowState state = new FakeWindowState();
+        state.attrs = new WindowManager.LayoutParams(WRAP_CONTENT, WRAP_CONTENT,
+                TYPE_APPLICATION,
+                FLAG_DIM_BEHIND  | (canBeImTarget ? 0 : FLAG_ALT_FOCUSABLE_IM),
+                PixelFormat.TRANSLUCENT);
+        state.isDimming = true;
+        return state;
+    }
+
+    private static FakeWindowState createInputMethodWindow(boolean visible, boolean drawNavBar,
+            boolean hasLightNavBar) {
+        final FakeWindowState state = new FakeWindowState();
+        state.attrs = new WindowManager.LayoutParams(MATCH_PARENT, MATCH_PARENT,
+                TYPE_INPUT_METHOD,
+                FLAG_NOT_FOCUSABLE | FLAG_LAYOUT_IN_SCREEN
+                        | (drawNavBar ? FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS : 0),
+                PixelFormat.TRANSPARENT);
+        state.attrs.subtreeSystemUiVisibility =
+                hasLightNavBar ? SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR : 0;
+        state.visible = visible;
+        state.policyVisible = visible;
+        return state;
+    }
+
+
+    @Test
+    public void testChooseNavigationColorWindowLw() throws Exception {
+        final FakeWindowState opaque = createOpaqueFullscreen(false);
+
+        final FakeWindowState dimmingImTarget = createDimmingDialogWindow(true);
+        final FakeWindowState dimmingNonImTarget = createDimmingDialogWindow(false);
+
+        final FakeWindowState visibleIme = createInputMethodWindow(true, true, false);
+        final FakeWindowState invisibleIme = createInputMethodWindow(false, true, false);
+        final FakeWindowState imeNonDrawNavBar = createInputMethodWindow(true, false, false);
+
+        // If everything is null, return null
+        assertNull(null, PhoneWindowManager.chooseNavigationColorWindowLw(
+                null, null, null, NAV_BAR_BOTTOM));
+
+        assertEquals(opaque, PhoneWindowManager.chooseNavigationColorWindowLw(
+                opaque, opaque, null, NAV_BAR_BOTTOM));
+        assertEquals(dimmingImTarget, PhoneWindowManager.chooseNavigationColorWindowLw(
+                opaque, dimmingImTarget, null, NAV_BAR_BOTTOM));
+        assertEquals(dimmingNonImTarget, PhoneWindowManager.chooseNavigationColorWindowLw(
+                opaque, dimmingNonImTarget, null, NAV_BAR_BOTTOM));
+
+        assertEquals(visibleIme, PhoneWindowManager.chooseNavigationColorWindowLw(
+                null, null, visibleIme, NAV_BAR_BOTTOM));
+        assertEquals(visibleIme, PhoneWindowManager.chooseNavigationColorWindowLw(
+                null, dimmingImTarget, visibleIme, NAV_BAR_BOTTOM));
+        assertEquals(dimmingNonImTarget, PhoneWindowManager.chooseNavigationColorWindowLw(
+                null, dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM));
+        assertEquals(visibleIme, PhoneWindowManager.chooseNavigationColorWindowLw(
+                opaque, opaque, visibleIme, NAV_BAR_BOTTOM));
+        assertEquals(visibleIme, PhoneWindowManager.chooseNavigationColorWindowLw(
+                opaque, dimmingImTarget, visibleIme, NAV_BAR_BOTTOM));
+        assertEquals(dimmingNonImTarget, PhoneWindowManager.chooseNavigationColorWindowLw(
+                opaque, dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM));
+
+        assertEquals(opaque, PhoneWindowManager.chooseNavigationColorWindowLw(
+                opaque, opaque, invisibleIme, NAV_BAR_BOTTOM));
+        assertEquals(opaque, PhoneWindowManager.chooseNavigationColorWindowLw(
+                opaque, opaque, invisibleIme, NAV_BAR_BOTTOM));
+        assertEquals(opaque, PhoneWindowManager.chooseNavigationColorWindowLw(
+                opaque, opaque, visibleIme, NAV_BAR_RIGHT));
+
+        // Only IME windows that have FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS should be navigation color
+        // window.
+        assertEquals(opaque, PhoneWindowManager.chooseNavigationColorWindowLw(
+                opaque, opaque, imeNonDrawNavBar, NAV_BAR_BOTTOM));
+        assertEquals(dimmingImTarget, PhoneWindowManager.chooseNavigationColorWindowLw(
+                opaque, dimmingImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM));
+        assertEquals(dimmingNonImTarget, PhoneWindowManager.chooseNavigationColorWindowLw(
+                opaque, dimmingNonImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM));
+    }
+
+    @Test
+    public void testUpdateLightNavigationBarLw() throws Exception {
+        final FakeWindowState opaqueDarkNavBar = createOpaqueFullscreen(false);
+        final FakeWindowState opaqueLightNavBar = createOpaqueFullscreen(true);
+
+        final FakeWindowState dimming = createDimmingDialogWindow(false);
+
+        final FakeWindowState imeDrawDarkNavBar = createInputMethodWindow(true,true, false);
+        final FakeWindowState imeDrawLightNavBar = createInputMethodWindow(true,true, true);
+
+        assertEquals(SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR,
+                PhoneWindowManager.updateLightNavigationBarLw(
+                        SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, null, null,
+                        null, null));
+
+        // Opaque top fullscreen window overrides SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR flag.
+        assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw(
+                0, opaqueDarkNavBar, opaqueDarkNavBar, null, opaqueDarkNavBar));
+        assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw(
+                SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, opaqueDarkNavBar, opaqueDarkNavBar, null,
+                opaqueDarkNavBar));
+        assertEquals(SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR,
+                PhoneWindowManager.updateLightNavigationBarLw(0, opaqueLightNavBar,
+                        opaqueLightNavBar, null, opaqueLightNavBar));
+        assertEquals(SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR,
+                PhoneWindowManager.updateLightNavigationBarLw(SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR,
+                        opaqueLightNavBar, opaqueLightNavBar, null, opaqueLightNavBar));
+
+        // Dimming window clears SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR.
+        assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw(
+                0, opaqueDarkNavBar, dimming, null, dimming));
+        assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw(
+                0, opaqueLightNavBar, dimming, null, dimming));
+        assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw(
+                SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, opaqueDarkNavBar, dimming, null, dimming));
+        assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw(
+                SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, opaqueLightNavBar, dimming, null, dimming));
+        assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw(
+                SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, opaqueLightNavBar, dimming, imeDrawLightNavBar,
+                dimming));
+
+        // IME window clears SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
+        assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw(
+                SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, null, null, imeDrawDarkNavBar,
+                imeDrawDarkNavBar));
+
+        // Even if the top fullscreen has SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, IME window wins.
+        assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw(
+                SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, opaqueLightNavBar, opaqueLightNavBar,
+                imeDrawDarkNavBar, imeDrawDarkNavBar));
+
+        // IME window should be able to use SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR.
+        assertEquals(SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR,
+                PhoneWindowManager.updateLightNavigationBarLw(0, opaqueDarkNavBar,
+                        opaqueDarkNavBar, imeDrawLightNavBar, imeDrawLightNavBar));
+    }
+
+    @Test
+    public void testIsDockSideAllowedDockTop() throws Exception {
+        // Docked top is always allowed
+        assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_TOP, DOCKED_LEFT, NAV_BAR_BOTTOM,
+                true /* navigationBarCanMove */));
+        assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_TOP, DOCKED_LEFT, NAV_BAR_BOTTOM,
+                false /* navigationBarCanMove */));
+    }
+
+    @Test
+    public void testIsDockSideAllowedDockBottom() throws Exception {
+        // Cannot dock bottom
+        assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_BOTTOM, DOCKED_LEFT, NAV_BAR_BOTTOM,
+                true /* navigationBarCanMove */));
+    }
+
+    @Test
+    public void testIsDockSideAllowedNavigationBarMovable() throws Exception {
+        assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_LEFT, NAV_BAR_BOTTOM,
+                true /* navigationBarCanMove */));
+        assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_LEFT, NAV_BAR_LEFT,
+                true /* navigationBarCanMove */));
+        assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_LEFT, NAV_BAR_RIGHT,
+                true /* navigationBarCanMove */));
+        assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_LEFT, NAV_BAR_BOTTOM,
+                true /* navigationBarCanMove */));
+        assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_LEFT, NAV_BAR_RIGHT,
+                true /* navigationBarCanMove */));
+        assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_LEFT, NAV_BAR_LEFT,
+                true /* navigationBarCanMove */));
+    }
+
+    @Test
+    public void testIsDockSideAllowedNavigationBarNotMovable() throws Exception {
+        // Navigation bar is not movable such as tablets
+        assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_LEFT, NAV_BAR_BOTTOM,
+                false /* navigationBarCanMove */));
+        assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_TOP, NAV_BAR_BOTTOM,
+                false /* navigationBarCanMove */));
+        assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_RIGHT, NAV_BAR_BOTTOM,
+                false /* navigationBarCanMove */));
+        assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_LEFT, NAV_BAR_BOTTOM,
+                false /* navigationBarCanMove */));
+        assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_TOP, NAV_BAR_BOTTOM,
+                false /* navigationBarCanMove */));
+        assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_RIGHT, NAV_BAR_BOTTOM,
+                false /* navigationBarCanMove */));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
new file mode 100644
index 0000000..2c47a94
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.policy;
+
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+
+import static com.android.server.wm.utils.CoordinateTransforms.transformPhysicalToLogicalCoordinates;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.Matrix;
+import android.graphics.Path;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.os.IBinder;
+import android.os.UserHandle;
+import android.support.test.InstrumentationRegistry;
+import android.testing.TestableResources;
+import android.util.Pair;
+import android.view.Display;
+import android.view.DisplayCutout;
+import android.view.DisplayInfo;
+import android.view.Gravity;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.IAccessibilityManager;
+
+import com.android.server.policy.keyguard.KeyguardServiceDelegate;
+import com.android.server.wm.DisplayFrames;
+import com.android.server.wm.utils.WmDisplayCutout;
+
+import org.junit.Before;
+
+public class PhoneWindowManagerTestBase {
+    static final int DISPLAY_WIDTH = 500;
+    static final int DISPLAY_HEIGHT = 1000;
+
+    static final int STATUS_BAR_HEIGHT = 10;
+    static final int NAV_BAR_HEIGHT = 15;
+    static final int DISPLAY_CUTOUT_HEIGHT = 8;
+
+    TestablePhoneWindowManager mPolicy;
+    TestContextWrapper mContext;
+    DisplayFrames mFrames;
+
+    FakeWindowState mStatusBar;
+    FakeWindowState mNavigationBar;
+    private boolean mHasDisplayCutout;
+    private int mRotation = ROTATION_0;
+
+    @Before
+    public void setUpBase() throws Exception {
+        mContext = new TestContextWrapper(InstrumentationRegistry.getTargetContext());
+        mContext.getResourceMocker().addOverride(
+                com.android.internal.R.dimen.status_bar_height_portrait, STATUS_BAR_HEIGHT);
+        mContext.getResourceMocker().addOverride(
+                com.android.internal.R.dimen.status_bar_height_landscape, STATUS_BAR_HEIGHT);
+        mContext.getResourceMocker().addOverride(
+                com.android.internal.R.dimen.navigation_bar_height, NAV_BAR_HEIGHT);
+        mContext.getResourceMocker().addOverride(
+                com.android.internal.R.dimen.navigation_bar_height_landscape, NAV_BAR_HEIGHT);
+        mContext.getResourceMocker().addOverride(
+                com.android.internal.R.dimen.navigation_bar_width, NAV_BAR_HEIGHT);
+
+        mPolicy = TestablePhoneWindowManager.create(mContext);
+
+        updateDisplayFrames();
+    }
+
+    public void setRotation(int rotation) {
+        mRotation = rotation;
+        updateDisplayFrames();
+    }
+
+    private void updateDisplayFrames() {
+        Pair<DisplayInfo, WmDisplayCutout> info = displayInfoAndCutoutForRotation(mRotation,
+                mHasDisplayCutout);
+        mFrames = new DisplayFrames(Display.DEFAULT_DISPLAY, info.first, info.second);
+    }
+
+    public void addStatusBar() {
+        mStatusBar = new FakeWindowState();
+        mStatusBar.attrs = new WindowManager.LayoutParams(MATCH_PARENT, STATUS_BAR_HEIGHT,
+                TYPE_STATUS_BAR, 0 /* flags */, PixelFormat.TRANSLUCENT);
+        mStatusBar.attrs.gravity = Gravity.TOP;
+
+        mPolicy.addWindow(mStatusBar);
+        mPolicy.mLastSystemUiFlags |= View.STATUS_BAR_TRANSPARENT;
+    }
+
+    public void addNavigationBar() {
+        mNavigationBar = new FakeWindowState();
+        mNavigationBar.attrs = new WindowManager.LayoutParams(MATCH_PARENT, NAV_BAR_HEIGHT,
+                TYPE_NAVIGATION_BAR, 0 /* flags */, PixelFormat.TRANSLUCENT);
+        mNavigationBar.attrs.gravity = Gravity.BOTTOM;
+
+        mPolicy.addWindow(mNavigationBar);
+        mPolicy.mHasNavigationBar = true;
+        mPolicy.mLastSystemUiFlags |= View.NAVIGATION_BAR_TRANSPARENT;
+    }
+
+    public void addDisplayCutout() {
+        mHasDisplayCutout = true;
+        updateDisplayFrames();
+    }
+
+    /** Asserts that {@code actual} is inset by the given amounts from the full display rect. */
+    public void assertInsetBy(Rect actual, int expectedInsetLeft, int expectedInsetTop,
+            int expectedInsetRight, int expectedInsetBottom) {
+        assertEquals(new Rect(expectedInsetLeft, expectedInsetTop,
+                mFrames.mDisplayWidth - expectedInsetRight,
+                mFrames.mDisplayHeight - expectedInsetBottom), actual);
+    }
+
+    /**
+     * Asserts that {@code actual} is inset by the given amounts from the full display rect.
+     *
+     * Convenience wrapper for when only the top and bottom inset are non-zero.
+     */
+    public void assertInsetByTopBottom(Rect actual, int expectedInsetTop, int expectedInsetBottom) {
+        assertInsetBy(actual, 0, expectedInsetTop, 0, expectedInsetBottom);
+    }
+
+    public static DisplayInfo displayInfoForRotation(int rotation, boolean withDisplayCutout) {
+        return displayInfoAndCutoutForRotation(rotation, withDisplayCutout).first;
+    }
+    public static Pair<DisplayInfo, WmDisplayCutout> displayInfoAndCutoutForRotation(int rotation,
+            boolean withDisplayCutout) {
+        DisplayInfo info = new DisplayInfo();
+        WmDisplayCutout cutout = null;
+
+        final boolean flippedDimensions = rotation == ROTATION_90 || rotation == ROTATION_270;
+        info.logicalWidth = flippedDimensions ? DISPLAY_HEIGHT : DISPLAY_WIDTH;
+        info.logicalHeight = flippedDimensions ? DISPLAY_WIDTH : DISPLAY_HEIGHT;
+        info.rotation = rotation;
+        if (withDisplayCutout) {
+            cutout = WmDisplayCutout.computeSafeInsets(
+                    displayCutoutForRotation(rotation), info.logicalWidth,
+                    info.logicalHeight);
+            info.displayCutout = cutout.getDisplayCutout();
+        } else {
+            info.displayCutout = null;
+        }
+        return Pair.create(info, cutout);
+    }
+
+    private static DisplayCutout displayCutoutForRotation(int rotation) {
+        Path p = new Path();
+        p.addRect(DISPLAY_WIDTH / 4, 0, DISPLAY_WIDTH * 3 / 4, DISPLAY_CUTOUT_HEIGHT,
+                Path.Direction.CCW);
+
+        Matrix m = new Matrix();
+        transformPhysicalToLogicalCoordinates(rotation, DISPLAY_WIDTH, DISPLAY_HEIGHT, m);
+        p.transform(m);
+
+        return DisplayCutout.fromBounds(p);
+    }
+
+    static class TestContextWrapper extends ContextWrapper {
+        private final TestableResources mResourceMocker;
+
+        public TestContextWrapper(Context targetContext) {
+            super(targetContext);
+            mResourceMocker = new TestableResources(targetContext.getResources());
+        }
+
+        @Override
+        public int checkPermission(String permission, int pid, int uid) {
+            return PackageManager.PERMISSION_GRANTED;
+        }
+
+        @Override
+        public int checkPermission(String permission, int pid, int uid, IBinder callerToken) {
+            return PackageManager.PERMISSION_GRANTED;
+        }
+
+        @Override
+        public Resources getResources() {
+            return mResourceMocker.getResources();
+        }
+
+        public TestableResources getResourceMocker() {
+            return mResourceMocker;
+        }
+    }
+
+    static class TestablePhoneWindowManager extends PhoneWindowManager {
+
+        public TestablePhoneWindowManager() {
+        }
+
+        @Override
+        void initializeHdmiState() {
+            // Do nothing.
+        }
+
+        @Override
+        Context getSystemUiContext() {
+            return mContext;
+        }
+
+        void addWindow(WindowState state) {
+            if (state instanceof FakeWindowState) {
+                ((FakeWindowState) state).surfaceLayer =
+                        getWindowLayerFromTypeLw(state.getAttrs().type,
+                                true /* canAddInternalSystemWindow */);
+            }
+            adjustWindowParamsLw(state, state.getAttrs(), true /* hasStatusBarPermission */);
+            assertEquals(WindowManagerGlobal.ADD_OKAY, prepareAddWindowLw(state, state.getAttrs()));
+        }
+
+        public static TestablePhoneWindowManager create(Context context) {
+            TestablePhoneWindowManager[] policy = new TestablePhoneWindowManager[1];
+            InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+                policy[0] = new TestablePhoneWindowManager();
+                policy[0].mContext = context;
+                policy[0].mKeyguardDelegate = mock(KeyguardServiceDelegate.class);
+                policy[0].mAccessibilityManager = new AccessibilityManager(context,
+                        mock(IAccessibilityManager.class), UserHandle.USER_CURRENT);
+                policy[0].mSystemGestures = mock(SystemGesturesPointerEventListener.class);
+                policy[0].mNavigationBarCanMove = true;
+                policy[0].mPortraitRotation = ROTATION_0;
+                policy[0].mLandscapeRotation = ROTATION_90;
+                policy[0].mUpsideDownRotation = ROTATION_180;
+                policy[0].mSeascapeRotation = ROTATION_270;
+                policy[0].onConfigurationChanged();
+            });
+            return policy[0];
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java b/services/tests/servicestests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java
new file mode 100644
index 0000000..164c80b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for the {@link TaskStack} class.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:com.android.server.wm.AnimatingAppWindowTokenRegistryTest
+ */
+@SmallTest
+@Presubmit
+@FlakyTest(detail = "Promote once confirmed non-flaky")
+@RunWith(AndroidJUnit4.class)
+public class AnimatingAppWindowTokenRegistryTest extends WindowTestsBase {
+
+    @Mock
+    AnimationAdapter mAdapter;
+
+    @Mock
+    Runnable mMockEndDeferFinishCallback1;
+    @Mock
+    Runnable mMockEndDeferFinishCallback2;
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void testDeferring() throws Exception {
+        final AppWindowToken window1 = createAppWindowToken(mDisplayContent,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final AppWindowToken window2 = createAppWindow(window1.getTask(), ACTIVITY_TYPE_STANDARD,
+                "window2").mAppToken;
+        final AnimatingAppWindowTokenRegistry registry =
+                window1.getStack().getAnimatingAppWindowTokenRegistry();
+
+        window1.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */);
+        window2.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */);
+        assertTrue(window1.isSelfAnimating());
+        assertTrue(window2.isSelfAnimating());
+
+        // Make sure that first animation finish is deferred, second one is not deferred, and first
+        // one gets cancelled.
+        assertTrue(registry.notifyAboutToFinish(window1, mMockEndDeferFinishCallback1));
+        assertFalse(registry.notifyAboutToFinish(window2, mMockEndDeferFinishCallback2));
+        verify(mMockEndDeferFinishCallback1).run();
+        verifyZeroInteractions(mMockEndDeferFinishCallback2);
+    }
+
+    @Test
+    public void testContainerRemoved() throws Exception {
+        final AppWindowToken window1 = createAppWindowToken(mDisplayContent,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final AppWindowToken window2 = createAppWindow(window1.getTask(), ACTIVITY_TYPE_STANDARD,
+                "window2").mAppToken;
+        final AnimatingAppWindowTokenRegistry registry =
+                window1.getStack().getAnimatingAppWindowTokenRegistry();
+
+        window1.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */);
+        window2.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */);
+        assertTrue(window1.isSelfAnimating());
+        assertTrue(window2.isSelfAnimating());
+
+        // Make sure that first animation finish is deferred, and removing the second window stops
+        // finishes all pending deferred finishings.
+        registry.notifyAboutToFinish(window1, mMockEndDeferFinishCallback1);
+        window2.setParent(null);
+        verify(mMockEndDeferFinishCallback1).run();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java
new file mode 100644
index 0000000..be7d781
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
+import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
+import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
+import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for {@link AppTransition}.
+ *
+ * atest AppTransitionTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class AppTransitionTests {
+
+    @Rule
+    public final WindowManagerServiceRule mRule = new WindowManagerServiceRule();
+    private WindowManagerService mWm;
+
+    @Before
+    public void setUp() throws Exception {
+        final Context context = InstrumentationRegistry.getTargetContext();
+        mWm = mRule.getWindowManagerService();
+    }
+
+    @Test
+    public void testKeyguardOverride() throws Exception {
+        mWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */);
+        mWm.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */);
+        assertEquals(TRANSIT_KEYGUARD_GOING_AWAY, mWm.mAppTransition.getAppTransition());
+    }
+
+    @Test
+    public void testKeyguardKeep() throws Exception {
+        mWm.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */);
+        mWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */);
+        assertEquals(TRANSIT_KEYGUARD_GOING_AWAY, mWm.mAppTransition.getAppTransition());
+    }
+
+    @Test
+    public void testForceOverride() throws Exception {
+        mWm.prepareAppTransition(TRANSIT_KEYGUARD_UNOCCLUDE, false /* alwaysKeepCurrent */);
+        mWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */,
+                0 /* flags */, true /* forceOverride */);
+        assertEquals(TRANSIT_ACTIVITY_OPEN, mWm.mAppTransition.getAppTransition());
+    }
+
+    @Test
+    public void testCrashing() throws Exception {
+        mWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */);
+        mWm.prepareAppTransition(TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
+        assertEquals(TRANSIT_CRASHING_ACTIVITY_CLOSE, mWm.mAppTransition.getAppTransition());
+    }
+
+    @Test
+    public void testKeepKeyguard_withCrashing() throws Exception {
+        mWm.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */);
+        mWm.prepareAppTransition(TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
+        assertEquals(TRANSIT_KEYGUARD_GOING_AWAY, mWm.mAppTransition.getAppTransition());
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
new file mode 100644
index 0000000..e0645b1
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import android.support.test.filters.FlakyTest;
+import org.junit.Test;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.content.res.Configuration.EMPTY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import com.android.server.wm.WindowTestUtils.TestTaskWindowContainerController;
+
+/**
+ * Test class for {@link AppWindowContainerController}.
+ *
+ * atest FrameworksServicesTests:com.android.server.wm.AppWindowContainerControllerTests
+ */
+@SmallTest
+@Presubmit
+@FlakyTest(bugId = 74078662)
+@org.junit.runner.RunWith(AndroidJUnit4.class)
+public class AppWindowContainerControllerTests extends WindowTestsBase {
+
+    @Test
+    public void testRemoveContainer() throws Exception {
+        final WindowTestUtils.TestAppWindowContainerController controller =
+                createAppWindowController();
+
+        // Assert token was added to display.
+        assertNotNull(mDisplayContent.getWindowToken(controller.mToken.asBinder()));
+        // Assert that the container was created and linked.
+        assertNotNull(controller.mContainer);
+
+        controller.removeContainer(mDisplayContent.getDisplayId());
+
+        // Assert token was remove from display.
+        assertNull(mDisplayContent.getWindowToken(controller.mToken.asBinder()));
+        // Assert that the container was removed.
+        assertNull(controller.mContainer);
+    }
+
+    @Test
+    public void testSetOrientation() throws Exception {
+        final WindowTestUtils.TestAppWindowContainerController controller =
+                createAppWindowController();
+
+        // Assert orientation is unspecified to start.
+        assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, controller.getOrientation());
+
+        controller.setOrientation(SCREEN_ORIENTATION_LANDSCAPE, mDisplayContent.getDisplayId(),
+                EMPTY /* displayConfig */, false /* freezeScreenIfNeeded */);
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, controller.getOrientation());
+
+        controller.removeContainer(mDisplayContent.getDisplayId());
+        // Assert orientation is unspecified to after container is removed.
+        assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, controller.getOrientation());
+
+        // Reset display frozen state
+        sWm.mDisplayFrozen = false;
+    }
+
+    private void assertHasStartingWindow(AppWindowToken atoken) {
+        assertNotNull(atoken.startingSurface);
+        assertNotNull(atoken.startingData);
+        assertNotNull(atoken.startingWindow);
+    }
+
+    private void assertNoStartingWindow(AppWindowToken atoken) {
+        assertNull(atoken.startingSurface);
+        assertNull(atoken.startingWindow);
+        assertNull(atoken.startingData);
+        atoken.forAllWindows(windowState -> {
+            assertFalse(windowState.getBaseType() == TYPE_APPLICATION_STARTING);
+        }, true);
+    }
+
+    @Test
+    public void testCreateRemoveStartingWindow() throws Exception {
+        final WindowTestUtils.TestAppWindowContainerController controller =
+                createAppWindowController();
+        controller.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
+                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
+                false, false);
+        waitUntilHandlersIdle();
+        final AppWindowToken atoken = controller.getAppWindowToken(mDisplayContent);
+        assertHasStartingWindow(atoken);
+        controller.removeStartingWindow();
+        waitUntilHandlersIdle();
+        assertNoStartingWindow(atoken);
+    }
+
+    @Test
+    public void testAddRemoveRace() throws Exception {
+
+        // There was once a race condition between adding and removing starting windows
+        for (int i = 0; i < 1000; i++) {
+            final WindowTestUtils.TestAppWindowContainerController controller =
+                    createAppWindowController();
+            controller.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
+                    android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
+                    false, false);
+            controller.removeStartingWindow();
+            waitUntilHandlersIdle();
+            assertNoStartingWindow(controller.getAppWindowToken(mDisplayContent));
+
+            controller.getAppWindowToken(mDisplayContent).getParent().getParent().removeImmediately();
+        }
+    }
+
+    @Test
+    public void testTransferStartingWindow() throws Exception {
+        final WindowTestUtils.TestAppWindowContainerController controller1 =
+                createAppWindowController();
+        final WindowTestUtils.TestAppWindowContainerController controller2 =
+                createAppWindowController();
+        controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
+                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
+                false, false);
+        waitUntilHandlersIdle();
+        controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
+                android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(),
+                true, true, false, true, false, false);
+        waitUntilHandlersIdle();
+        assertNoStartingWindow(controller1.getAppWindowToken(mDisplayContent));
+        assertHasStartingWindow(controller2.getAppWindowToken(mDisplayContent));
+    }
+
+    @Test
+    public void testTransferStartingWindowWhileCreating() throws Exception {
+        final WindowTestUtils.TestAppWindowContainerController controller1 =
+                createAppWindowController();
+        final WindowTestUtils.TestAppWindowContainerController controller2 =
+                createAppWindowController();
+        ((TestWindowManagerPolicy) sWm.mPolicy).setRunnableWhenAddingSplashScreen(() -> {
+
+            // Surprise, ...! Transfer window in the middle of the creation flow.
+            controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
+                    android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(),
+                    true, true, false, true, false, false);
+        });
+        controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
+                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
+                false, false);
+        waitUntilHandlersIdle();
+        assertNoStartingWindow(controller1.getAppWindowToken(mDisplayContent));
+        assertHasStartingWindow(controller2.getAppWindowToken(mDisplayContent));
+    }
+
+    @Test
+    public void testTryTransferStartingWindowFromHiddenAboveToken() throws Exception {
+
+        // Add two tasks on top of each other.
+        TestTaskWindowContainerController taskController =
+                new WindowTestUtils.TestTaskWindowContainerController(this);
+        final WindowTestUtils.TestAppWindowContainerController controllerTop =
+                createAppWindowController(taskController);
+        final WindowTestUtils.TestAppWindowContainerController controllerBottom =
+                createAppWindowController(taskController);
+
+        // Add a starting window.
+        controllerTop.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
+                android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
+                false, false);
+        waitUntilHandlersIdle();
+
+        // Make the top one invisible, and try transfering the starting window from the top to the
+        // bottom one.
+        controllerTop.setVisibility(false, false);
+        controllerBottom.mContainer.transferStartingWindowFromHiddenAboveTokenIfNeeded();
+
+        // Assert that the bottom window now has the starting window.
+        assertNoStartingWindow(controllerTop.getAppWindowToken(mDisplayContent));
+        assertHasStartingWindow(controllerBottom.getAppWindowToken(mDisplayContent));
+    }
+
+    @Test
+    public void testReparent() throws Exception {
+        final StackWindowController stackController =
+            createStackControllerOnDisplay(mDisplayContent);
+        final WindowTestUtils.TestTaskWindowContainerController taskController1 =
+                new WindowTestUtils.TestTaskWindowContainerController(stackController);
+        final WindowTestUtils.TestAppWindowContainerController appWindowController1 =
+                createAppWindowController(taskController1);
+        final WindowTestUtils.TestTaskWindowContainerController taskController2 =
+                new WindowTestUtils.TestTaskWindowContainerController(stackController);
+        final WindowTestUtils.TestAppWindowContainerController appWindowController2 =
+                createAppWindowController(taskController2);
+        final WindowTestUtils.TestTaskWindowContainerController taskController3 =
+                new WindowTestUtils.TestTaskWindowContainerController(stackController);
+
+        try {
+            appWindowController1.reparent(taskController1, 0);
+            fail("Should not be able to reparent to the same parent");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            taskController3.setContainer(null);
+            appWindowController1.reparent(taskController3, 0);
+            fail("Should not be able to reparent to a task that doesn't have a container");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        // Reparent the app window and ensure that it is moved
+        appWindowController1.reparent(taskController2, 0);
+        assertEquals(taskController2.mContainer, appWindowController1.mContainer.getParent());
+        assertEquals(0, ((WindowTestUtils.TestAppWindowToken) appWindowController1.mContainer)
+                .positionInParent());
+        assertEquals(1, ((WindowTestUtils.TestAppWindowToken) appWindowController2.mContainer)
+                .positionInParent());
+    }
+
+    private WindowTestUtils.TestAppWindowContainerController createAppWindowController() {
+        return createAppWindowController(
+                new WindowTestUtils.TestTaskWindowContainerController(this));
+    }
+
+    private WindowTestUtils.TestAppWindowContainerController createAppWindowController(
+            WindowTestUtils.TestTaskWindowContainerController taskController) {
+        return new WindowTestUtils.TestAppWindowContainerController(taskController);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
new file mode 100644
index 0000000..f6599dc
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.Surface;
+import android.view.WindowManager;
+
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.TRANSIT_UNSET;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+/**
+ * Tests for the {@link AppWindowToken} class.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:com.android.server.wm.AppWindowTokenTests
+ */
+@SmallTest
+// TODO: b/68267650
+// @Presubmit
+@RunWith(AndroidJUnit4.class)
+public class AppWindowTokenTests extends WindowTestsBase {
+
+    TaskStack mStack;
+    Task mTask;
+    WindowTestUtils.TestAppWindowToken mToken;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mStack = createTaskStackOnDisplay(mDisplayContent);
+        mTask = createTaskInStack(mStack, 0 /* userId */);
+        mToken = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
+
+        mTask.addChild(mToken, 0);
+    }
+
+    @Test
+    @Presubmit
+    public void testAddWindow_Order() throws Exception {
+        assertEquals(0, mToken.getWindowsCount());
+
+        final WindowState win1 = createWindow(null, TYPE_APPLICATION, mToken, "win1");
+        final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, mToken,
+                "startingWin");
+        final WindowState baseWin = createWindow(null, TYPE_BASE_APPLICATION, mToken, "baseWin");
+        final WindowState win4 = createWindow(null, TYPE_APPLICATION, mToken, "win4");
+
+        // Should not contain the windows that were added above.
+        assertEquals(4, mToken.getWindowsCount());
+        assertTrue(mToken.hasWindow(win1));
+        assertTrue(mToken.hasWindow(startingWin));
+        assertTrue(mToken.hasWindow(baseWin));
+        assertTrue(mToken.hasWindow(win4));
+
+        // The starting window should be on-top of all other windows.
+        assertEquals(startingWin, mToken.getLastChild());
+
+        // The base application window should be below all other windows.
+        assertEquals(baseWin, mToken.getFirstChild());
+        mToken.removeImmediately();
+    }
+
+    @Test
+    @Presubmit
+    public void testFindMainWindow() throws Exception {
+        assertNull(mToken.findMainWindow());
+
+        final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, mToken, "window1");
+        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, mToken, "window11");
+        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, mToken, "window12");
+        assertEquals(window1, mToken.findMainWindow());
+        window1.mAnimatingExit = true;
+        assertEquals(window1, mToken.findMainWindow());
+        final WindowState window2 = createWindow(null, TYPE_APPLICATION_STARTING, mToken, "window2");
+        assertEquals(window2, mToken.findMainWindow());
+        mToken.removeImmediately();
+    }
+
+    @Test
+    @Presubmit
+    public void testGetTopFullscreenWindow() throws Exception {
+        assertNull(mToken.getTopFullscreenWindow());
+
+        final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, mToken, "window1");
+        final WindowState window11 = createWindow(null, TYPE_APPLICATION, mToken, "window11");
+        final WindowState window12 = createWindow(null, TYPE_APPLICATION, mToken, "window12");
+        assertEquals(window12, mToken.getTopFullscreenWindow());
+        window12.mAttrs.width = 500;
+        assertEquals(window11, mToken.getTopFullscreenWindow());
+        window11.mAttrs.width = 500;
+        assertEquals(window1, mToken.getTopFullscreenWindow());
+        mToken.removeImmediately();
+    }
+
+    @Test
+    public void testLandscapeSeascapeRotationByApp() throws Exception {
+        // Some plumbing to get the service ready for rotation updates.
+        sWm.mDisplayReady = true;
+        sWm.mDisplayEnabled = true;
+
+        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
+                TYPE_BASE_APPLICATION);
+        attrs.setTitle("AppWindow");
+        final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, mToken);
+        mToken.addWindow(appWindow);
+
+        // Set initial orientation and update.
+        mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+        sWm.updateOrientationFromAppTokens(mDisplayContent.getOverrideConfiguration(), null,
+                mDisplayContent.getDisplayId());
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mDisplayContent.getLastOrientation());
+        appWindow.resizeReported = false;
+
+        // Update the orientation to perform 180 degree rotation and check that resize was reported.
+        mToken.setOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
+        sWm.updateOrientationFromAppTokens(mDisplayContent.getOverrideConfiguration(), null,
+                mDisplayContent.getDisplayId());
+        sWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
+        assertEquals(SCREEN_ORIENTATION_REVERSE_LANDSCAPE, mDisplayContent.getLastOrientation());
+        assertTrue(appWindow.resizeReported);
+        appWindow.removeImmediately();
+    }
+
+    @Test
+    public void testLandscapeSeascapeRotationByPolicy() throws Exception {
+        // Some plumbing to get the service ready for rotation updates.
+        sWm.mDisplayReady = true;
+        sWm.mDisplayEnabled = true;
+
+        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
+                TYPE_BASE_APPLICATION);
+        attrs.setTitle("AppWindow");
+        final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, mToken);
+        mToken.addWindow(appWindow);
+
+        // Set initial orientation and update.
+        performRotation(Surface.ROTATION_90);
+        appWindow.resizeReported = false;
+
+        // Update the rotation to perform 180 degree rotation and check that resize was reported.
+        performRotation(Surface.ROTATION_270);
+        assertTrue(appWindow.resizeReported);
+        appWindow.removeImmediately();
+    }
+
+    private void performRotation(int rotationToReport) {
+        ((TestWindowManagerPolicy) sWm.mPolicy).rotationToReport = rotationToReport;
+        sWm.updateRotation(false, false);
+        // Simulate animator finishing orientation change
+        sWm.mRoot.mOrientationChangeComplete = true;
+        sWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
+    }
+
+    @Test
+    @Presubmit
+    public void testGetOrientation() throws Exception {
+        mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+
+        mToken.setFillsParent(false);
+        // Can specify orientation if app doesn't fill parent.
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mToken.getOrientation());
+
+        mToken.setFillsParent(true);
+        mToken.setHidden(true);
+        mToken.sendingToBottom = true;
+        // Can not specify orientation if app isn't visible even though it fills parent.
+        assertEquals(SCREEN_ORIENTATION_UNSET, mToken.getOrientation());
+        // Can specify orientation if the current orientation candidate is orientation behind.
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mToken.getOrientation(SCREEN_ORIENTATION_BEHIND));
+    }
+
+    @Test
+    @Presubmit
+    public void testKeyguardFlagsDuringRelaunch() throws Exception {
+        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
+                TYPE_BASE_APPLICATION);
+        attrs.flags |= FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD;
+        attrs.setTitle("AppWindow");
+        final WindowTestUtils.TestWindowState appWindow = createWindowState(attrs, mToken);
+
+        // Add window with show when locked flag
+        mToken.addWindow(appWindow);
+        assertTrue(mToken.containsShowWhenLockedWindow() && mToken.containsDismissKeyguardWindow());
+
+        // Start relaunching
+        mToken.startRelaunching();
+        assertTrue(mToken.containsShowWhenLockedWindow() && mToken.containsDismissKeyguardWindow());
+
+        // Remove window and make sure that we still report back flag
+        mToken.removeChild(appWindow);
+        assertTrue(mToken.containsShowWhenLockedWindow() && mToken.containsDismissKeyguardWindow());
+
+        // Finish relaunching and ensure flag is now not reported
+        mToken.finishRelaunching();
+        assertFalse(mToken.containsShowWhenLockedWindow() || mToken.containsDismissKeyguardWindow());
+    }
+
+    @Test
+    @FlakyTest(detail = "Promote once confirmed non-flaky")
+    public void testStuckExitingWindow() throws Exception {
+        final WindowState closingWindow = createWindow(null, FIRST_APPLICATION_WINDOW,
+                "closingWindow");
+        closingWindow.mAnimatingExit = true;
+        closingWindow.mRemoveOnExit = true;
+        closingWindow.mAppToken.setVisibility(null, false /* visible */, TRANSIT_UNSET,
+                true /* performLayout */, false /* isVoiceInteraction */);
+
+        // We pretended that we were running an exit animation, but that should have been cleared up
+        // by changing visibility of AppWindowToken
+        closingWindow.removeIfPossible();
+        assertTrue(closingWindow.mRemoved);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
new file mode 100644
index 0000000..ff631e7
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
@@ -0,0 +1,595 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static com.android.server.wm.BoundsAnimationController.NO_PIP_MODE_CHANGED_CALLBACKS;
+import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_END;
+import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_START;
+import static com.android.server.wm.BoundsAnimationController.SchedulePipModeChangedState;
+
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.Looper;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.server.wm.WindowManagerInternal.AppTransitionListener;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.server.wm.BoundsAnimationController.BoundsAnimator;
+
+/**
+ * Test class for {@link BoundsAnimationController} to ensure that it sends the right callbacks
+ * depending on the various interactions.
+ *
+ * We are really concerned about only three of the transition states [F = fullscreen, !F = floating]
+ * F->!F, !F->!F, and !F->F. Each animation can only be cancelled from the target mid-transition,
+ * or if a new animation starts on the same target.  The tests below verifies that the target is
+ * notified of all the cases where it is animating and cancelled so that it can respond
+ * appropriately.
+ *
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.wm.BoundsAnimationControllerTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class BoundsAnimationControllerTests extends WindowTestsBase {
+
+    /**
+     * Mock value animator to simulate updates with.
+     */
+    private class MockValueAnimator extends ValueAnimator {
+
+        private float mFraction;
+
+        public MockValueAnimator getWithValue(float fraction) {
+            mFraction = fraction;
+            return this;
+        }
+
+        @Override
+        public Object getAnimatedValue() {
+            return mFraction;
+        }
+    }
+
+    /**
+     * Mock app transition to fire notifications to the bounds animator.
+     */
+    private class MockAppTransition extends AppTransition {
+
+        private AppTransitionListener mListener;
+
+        MockAppTransition(Context context) {
+            super(context, null);
+        }
+
+        @Override
+        void registerListenerLocked(AppTransitionListener listener) {
+            mListener = listener;
+        }
+
+        public void notifyTransitionPending() {
+            mListener.onAppTransitionPendingLocked();
+        }
+
+        public void notifyTransitionCancelled(int transit) {
+            mListener.onAppTransitionCancelledLocked(transit);
+        }
+
+        public void notifyTransitionStarting(int transit) {
+            mListener.onAppTransitionStartingLocked(transit, null, null, 0, 0, 0);
+        }
+
+        public void notifyTransitionFinished() {
+            mListener.onAppTransitionFinishedLocked(null);
+        }
+    }
+
+    /**
+     * A test animate bounds user to track callbacks from the bounds animation.
+     */
+    private class TestBoundsAnimationTarget implements BoundsAnimationTarget {
+
+        boolean mAwaitingAnimationStart;
+        boolean mMovedToFullscreen;
+        boolean mAnimationStarted;
+        boolean mSchedulePipModeChangedOnStart;
+        boolean mForcePipModeChangedCallback;
+        boolean mAnimationEnded;
+        Rect mAnimationEndFinalStackBounds;
+        boolean mSchedulePipModeChangedOnEnd;
+        boolean mBoundsUpdated;
+        boolean mCancelRequested;
+        Rect mStackBounds;
+        Rect mTaskBounds;
+
+        void initialize(Rect from) {
+            mAwaitingAnimationStart = true;
+            mMovedToFullscreen = false;
+            mAnimationStarted = false;
+            mAnimationEnded = false;
+            mAnimationEndFinalStackBounds = null;
+            mForcePipModeChangedCallback = false;
+            mSchedulePipModeChangedOnStart = false;
+            mSchedulePipModeChangedOnEnd = false;
+            mStackBounds = from;
+            mTaskBounds = null;
+            mBoundsUpdated = false;
+        }
+
+        @Override
+        public void onAnimationStart(boolean schedulePipModeChangedCallback, boolean forceUpdate) {
+            mAwaitingAnimationStart = false;
+            mAnimationStarted = true;
+            mSchedulePipModeChangedOnStart = schedulePipModeChangedCallback;
+            mForcePipModeChangedCallback = forceUpdate;
+        }
+
+        @Override
+        public boolean shouldDeferStartOnMoveToFullscreen() {
+            return true;
+        }
+
+        @Override
+        public boolean setPinnedStackSize(Rect stackBounds, Rect taskBounds) {
+            // TODO: Once we break the runs apart, we should fail() here if this is called outside
+            //       of onAnimationStart() and onAnimationEnd()
+            if (mCancelRequested) {
+                mCancelRequested = false;
+                return false;
+            } else {
+                mBoundsUpdated = true;
+                mStackBounds = stackBounds;
+                mTaskBounds = taskBounds;
+                return true;
+            }
+        }
+
+        @Override
+        public void onAnimationEnd(boolean schedulePipModeChangedCallback, Rect finalStackBounds,
+                boolean moveToFullscreen) {
+            mAnimationEnded = true;
+            mAnimationEndFinalStackBounds = finalStackBounds;
+            mSchedulePipModeChangedOnEnd = schedulePipModeChangedCallback;
+            mMovedToFullscreen = moveToFullscreen;
+            mTaskBounds = null;
+        }
+    }
+
+    /**
+     * Drives the animations, makes common assertions along the way.
+     */
+    private class BoundsAnimationDriver {
+
+        private BoundsAnimationController mController;
+        private TestBoundsAnimationTarget mTarget;
+        private BoundsAnimator mAnimator;
+
+        private Rect mFrom;
+        private Rect mTo;
+        private Rect mLargerBounds;
+        private Rect mExpectedFinalBounds;
+
+        BoundsAnimationDriver(BoundsAnimationController controller,
+                TestBoundsAnimationTarget target) {
+            mController = controller;
+            mTarget = target;
+        }
+
+        BoundsAnimationDriver start(Rect from, Rect to) {
+            if (mAnimator != null) {
+                throw new IllegalArgumentException("Call restart() to restart an animation");
+            }
+
+            boolean fromFullscreen = from.equals(BOUNDS_FULL);
+            boolean toFullscreen = to.equals(BOUNDS_FULL);
+
+            mTarget.initialize(from);
+
+            // Started, not running
+            assertTrue(mTarget.mAwaitingAnimationStart);
+            assertTrue(!mTarget.mAnimationStarted);
+
+            startImpl(from, to);
+
+            // Ensure that the animator is paused for the all windows drawn signal when animating
+            // to/from fullscreen
+            if (fromFullscreen || toFullscreen) {
+                assertTrue(mAnimator.isPaused());
+                mController.onAllWindowsDrawn();
+            } else {
+                assertTrue(!mAnimator.isPaused());
+            }
+
+            // Started and running
+            assertTrue(!mTarget.mAwaitingAnimationStart);
+            assertTrue(mTarget.mAnimationStarted);
+
+            return this;
+        }
+
+        BoundsAnimationDriver restart(Rect to, boolean expectStartedAndPipModeChangedCallback) {
+            if (mAnimator == null) {
+                throw new IllegalArgumentException("Call start() to start a new animation");
+            }
+
+            BoundsAnimator oldAnimator = mAnimator;
+            boolean toSameBounds = mAnimator.isStarted() && to.equals(mTo);
+
+            // Reset the animation start state
+            mTarget.mAnimationStarted = false;
+
+            // Start animation
+            startImpl(mTarget.mStackBounds, to);
+
+            if (toSameBounds) {
+                // Same animator if same final bounds
+                assertSame(oldAnimator, mAnimator);
+            }
+
+            if (expectStartedAndPipModeChangedCallback) {
+                // Replacing animation with pending pip mode changed callback, ensure we update
+                assertTrue(mTarget.mAnimationStarted);
+                assertTrue(mTarget.mSchedulePipModeChangedOnStart);
+                assertTrue(mTarget.mForcePipModeChangedCallback);
+            } else {
+                // No animation start for replacing animation
+                assertTrue(!mTarget.mAnimationStarted);
+            }
+            mTarget.mAnimationStarted = true;
+            return this;
+        }
+
+        private BoundsAnimationDriver startImpl(Rect from, Rect to) {
+            boolean fromFullscreen = from.equals(BOUNDS_FULL);
+            boolean toFullscreen = to.equals(BOUNDS_FULL);
+            mFrom = new Rect(from);
+            mTo = new Rect(to);
+            mExpectedFinalBounds = new Rect(to);
+            mLargerBounds = getLargerBounds(mFrom, mTo);
+
+            // Start animation
+            final @SchedulePipModeChangedState int schedulePipModeChangedState = toFullscreen
+                    ? SCHEDULE_PIP_MODE_CHANGED_ON_START
+                    : fromFullscreen
+                            ? SCHEDULE_PIP_MODE_CHANGED_ON_END
+                            : NO_PIP_MODE_CHANGED_CALLBACKS;
+            mAnimator = mController.animateBoundsImpl(mTarget, from, to, DURATION,
+                    schedulePipModeChangedState, fromFullscreen, toFullscreen);
+
+            // Original stack bounds, frozen task bounds
+            assertEquals(mFrom, mTarget.mStackBounds);
+            assertEqualSizeAtOffset(mLargerBounds, mTarget.mTaskBounds);
+
+            // Animating to larger size
+            if (mFrom.equals(mLargerBounds)) {
+                assertTrue(!mAnimator.animatingToLargerSize());
+            } else if (mTo.equals(mLargerBounds)) {
+                assertTrue(mAnimator.animatingToLargerSize());
+            }
+
+            return this;
+        }
+
+        BoundsAnimationDriver expectStarted(boolean schedulePipModeChanged) {
+            // Callback made
+            assertTrue(mTarget.mAnimationStarted);
+
+            assertEquals(schedulePipModeChanged, mTarget.mSchedulePipModeChangedOnStart);
+            return this;
+        }
+
+        BoundsAnimationDriver update(float t) {
+            mAnimator.onAnimationUpdate(mMockAnimator.getWithValue(t));
+
+            // Temporary stack bounds, frozen task bounds
+            if (t == 0f) {
+                assertEquals(mFrom, mTarget.mStackBounds);
+            } else if (t == 1f) {
+                assertEquals(mTo, mTarget.mStackBounds);
+            } else {
+                assertNotEquals(mFrom, mTarget.mStackBounds);
+                assertNotEquals(mTo, mTarget.mStackBounds);
+            }
+            assertEqualSizeAtOffset(mLargerBounds, mTarget.mTaskBounds);
+            return this;
+        }
+
+        BoundsAnimationDriver cancel() {
+            // Cancel
+            mTarget.mCancelRequested = true;
+            mTarget.mBoundsUpdated = false;
+            mExpectedFinalBounds = null;
+
+            // Update
+            mAnimator.onAnimationUpdate(mMockAnimator.getWithValue(0.5f));
+
+            // Not started, not running, cancel reset
+            assertTrue(!mTarget.mCancelRequested);
+
+            // Stack/task bounds not updated
+            assertTrue(!mTarget.mBoundsUpdated);
+
+            // Callback made
+            assertTrue(mTarget.mAnimationEnded);
+            assertNull(mTarget.mAnimationEndFinalStackBounds);
+
+            return this;
+        }
+
+        BoundsAnimationDriver end() {
+            mAnimator.end();
+
+            // Final stack bounds
+            assertEquals(mTo, mTarget.mStackBounds);
+            assertEquals(mExpectedFinalBounds, mTarget.mAnimationEndFinalStackBounds);
+            assertNull(mTarget.mTaskBounds);
+
+            return this;
+        }
+
+        BoundsAnimationDriver expectEnded(boolean schedulePipModeChanged,
+                boolean moveToFullscreen) {
+            // Callback made
+            assertTrue(mTarget.mAnimationEnded);
+
+            assertEquals(schedulePipModeChanged, mTarget.mSchedulePipModeChangedOnEnd);
+            assertEquals(moveToFullscreen, mTarget.mMovedToFullscreen);
+            return this;
+        }
+
+        private Rect getLargerBounds(Rect r1, Rect r2) {
+            int r1Area = r1.width() * r1.height();
+            int r2Area = r2.width() * r2.height();
+            if (r1Area <= r2Area) {
+                return r2;
+            } else {
+                return r1;
+            }
+        }
+    }
+
+    // Constants
+    private static final boolean SCHEDULE_PIP_MODE_CHANGED = true;
+    private static final boolean MOVE_TO_FULLSCREEN = true;
+    private static final int DURATION = 100;
+
+    // Some dummy bounds to represent fullscreen and floating bounds
+    private static final Rect BOUNDS_FULL = new Rect(0, 0, 100, 100);
+    private static final Rect BOUNDS_FLOATING = new Rect(60, 60, 95, 95);
+    private static final Rect BOUNDS_SMALLER_FLOATING = new Rect(80, 80, 95, 95);
+
+    // Common
+    private MockAppTransition mMockAppTransition;
+    private MockValueAnimator mMockAnimator;
+    private TestBoundsAnimationTarget mTarget;
+    private BoundsAnimationController mController;
+    private BoundsAnimationDriver mDriver;
+
+    // Temp
+    private Rect mTmpRect = new Rect();
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        final Context context = InstrumentationRegistry.getTargetContext();
+        final Handler handler = new Handler(Looper.getMainLooper());
+        mMockAppTransition = new MockAppTransition(context);
+        mMockAnimator = new MockValueAnimator();
+        mTarget = new TestBoundsAnimationTarget();
+        mController = new BoundsAnimationController(context, mMockAppTransition, handler, null);
+        mDriver = new BoundsAnimationDriver(mController, mTarget);
+    }
+
+    /** BASE TRANSITIONS **/
+
+    @UiThreadTest
+    @Test
+    public void testFullscreenToFloatingTransition() throws Exception {
+        mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0f)
+                .update(0.5f)
+                .update(1f)
+                .end()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToFullscreenTransition() throws Exception {
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
+                .expectStarted(SCHEDULE_PIP_MODE_CHANGED)
+                .update(0f)
+                .update(0.5f)
+                .update(1f)
+                .end()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, MOVE_TO_FULLSCREEN);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToSmallerFloatingTransition() throws Exception {
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_SMALLER_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0f)
+                .update(0.5f)
+                .update(1f)
+                .end()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToLargerFloatingTransition() throws Exception {
+        mDriver.start(BOUNDS_SMALLER_FLOATING, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0f)
+                .update(0.5f)
+                .update(1f)
+                .end()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
+
+    /** F->!F w/ CANCEL **/
+
+    @UiThreadTest
+    @Test
+    public void testFullscreenToFloatingCancelFromTarget() throws Exception {
+        mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .cancel()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testFullscreenToFloatingCancelFromAnimationToSameBounds() throws Exception {
+        mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .restart(BOUNDS_FLOATING, false /* expectStartedAndPipModeChangedCallback */)
+                .end()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testFullscreenToFloatingCancelFromAnimationToFloatingBounds() throws Exception {
+        mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .restart(BOUNDS_SMALLER_FLOATING,
+                        false /* expectStartedAndPipModeChangedCallback */)
+                .end()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testFullscreenToFloatingCancelFromAnimationToFullscreenBounds() throws Exception {
+        // When animating from fullscreen and the animation is interruped, we expect the animation
+        // start callback to be made, with a forced pip mode change callback
+        mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .restart(BOUNDS_FULL, true /* expectStartedAndPipModeChangedCallback */)
+                .end()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, MOVE_TO_FULLSCREEN);
+    }
+
+    /** !F->F w/ CANCEL **/
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToFullscreenCancelFromTarget() throws Exception {
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
+                .expectStarted(SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .cancel()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToFullscreenCancelFromAnimationToSameBounds() throws Exception {
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
+                .expectStarted(SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .restart(BOUNDS_FULL, false /* expectStartedAndPipModeChangedCallback */)
+                .end()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, MOVE_TO_FULLSCREEN);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToFullscreenCancelFromAnimationToFloatingBounds() throws Exception {
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
+                .expectStarted(SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .restart(BOUNDS_SMALLER_FLOATING,
+                        false /* expectStartedAndPipModeChangedCallback */)
+                .end()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, MOVE_TO_FULLSCREEN);
+    }
+
+    /** !F->!F w/ CANCEL **/
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToSmallerFloatingCancelFromTarget() throws Exception {
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_SMALLER_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .cancel()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToLargerFloatingCancelFromTarget() throws Exception {
+        mDriver.start(BOUNDS_SMALLER_FLOATING, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .cancel()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
+
+    /** MISC **/
+
+    @UiThreadTest
+    @Test
+    public void testBoundsAreCopied() throws Exception {
+        Rect from = new Rect(0, 0, 100, 100);
+        Rect to = new Rect(25, 25, 75, 75);
+        mDriver.start(from, to)
+                .update(0.25f)
+                .end();
+        assertEquals(new Rect(0, 0, 100, 100), from);
+        assertEquals(new Rect(25, 25, 75, 75), to);
+    }
+
+    /**
+     * @return whether the task and stack bounds would be the same if they were at the same offset.
+     */
+    private boolean assertEqualSizeAtOffset(Rect stackBounds, Rect taskBounds) {
+        mTmpRect.set(taskBounds);
+        mTmpRect.offsetTo(stackBounds.left, stackBounds.top);
+        return stackBounds.equals(mTmpRect);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/ConfigurationContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/ConfigurationContainerTests.java
new file mode 100644
index 0000000..192e156
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/ConfigurationContainerTests.java
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
+import static android.content.res.Configuration.EMPTY;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.content.res.Configuration;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Test class for {@link ConfigurationContainer}.
+ *
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.wm.ConfigurationContainerTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class ConfigurationContainerTests {
+
+    @Test
+    public void testConfigurationInit() throws Exception {
+        // Check root container initial config.
+        final TestConfigurationContainer root = new TestConfigurationContainer();
+        assertEquals(EMPTY, root.getOverrideConfiguration());
+        assertEquals(EMPTY, root.getMergedOverrideConfiguration());
+        assertEquals(EMPTY, root.getConfiguration());
+
+        // Check child initial config.
+        final TestConfigurationContainer child1 = root.addChild();
+        assertEquals(EMPTY, child1.getOverrideConfiguration());
+        assertEquals(EMPTY, child1.getMergedOverrideConfiguration());
+        assertEquals(EMPTY, child1.getConfiguration());
+
+        // Check child initial config if root has overrides.
+        final Configuration rootOverrideConfig = new Configuration();
+        rootOverrideConfig.fontScale = 1.3f;
+        root.onOverrideConfigurationChanged(rootOverrideConfig);
+        final TestConfigurationContainer child2 = root.addChild();
+        assertEquals(EMPTY, child2.getOverrideConfiguration());
+        assertEquals(rootOverrideConfig, child2.getMergedOverrideConfiguration());
+        assertEquals(rootOverrideConfig, child2.getConfiguration());
+
+        // Check child initial config if root has parent config set.
+        final Configuration rootParentConfig = new Configuration();
+        rootParentConfig.fontScale = 0.8f;
+        rootParentConfig.orientation = SCREEN_ORIENTATION_LANDSCAPE;
+        root.onConfigurationChanged(rootParentConfig);
+        final Configuration rootFullConfig = new Configuration(rootParentConfig);
+        rootFullConfig.updateFrom(rootOverrideConfig);
+
+        final TestConfigurationContainer child3 = root.addChild();
+        assertEquals(EMPTY, child3.getOverrideConfiguration());
+        assertEquals(rootOverrideConfig, child3.getMergedOverrideConfiguration());
+        assertEquals(rootFullConfig, child3.getConfiguration());
+    }
+
+    @Test
+    public void testConfigurationChangeOnAddRemove() throws Exception {
+        // Init root's config.
+        final TestConfigurationContainer root = new TestConfigurationContainer();
+        final Configuration rootOverrideConfig = new Configuration();
+        rootOverrideConfig.fontScale = 1.3f;
+        root.onOverrideConfigurationChanged(rootOverrideConfig);
+
+        // Init child's config.
+        final TestConfigurationContainer child = root.addChild();
+        final Configuration childOverrideConfig = new Configuration();
+        childOverrideConfig.densityDpi = 320;
+        child.onOverrideConfigurationChanged(childOverrideConfig);
+        final Configuration mergedOverrideConfig = new Configuration(root.getConfiguration());
+        mergedOverrideConfig.updateFrom(childOverrideConfig);
+
+        // Check configuration update when child is removed from parent.
+        root.removeChild(child);
+        assertEquals(childOverrideConfig, child.getOverrideConfiguration());
+        assertEquals(mergedOverrideConfig, child.getMergedOverrideConfiguration());
+        assertEquals(mergedOverrideConfig, child.getConfiguration());
+
+        // It may be paranoia... but let's check if parent's config didn't change after removal.
+        assertEquals(rootOverrideConfig, root.getOverrideConfiguration());
+        assertEquals(rootOverrideConfig, root.getMergedOverrideConfiguration());
+        assertEquals(rootOverrideConfig, root.getConfiguration());
+
+        // Init different root
+        final TestConfigurationContainer root2 = new TestConfigurationContainer();
+        final Configuration rootOverrideConfig2 = new Configuration();
+        rootOverrideConfig2.fontScale = 1.1f;
+        root2.onOverrideConfigurationChanged(rootOverrideConfig2);
+
+        // Check configuration update when child is added to different parent.
+        mergedOverrideConfig.setTo(rootOverrideConfig2);
+        mergedOverrideConfig.updateFrom(childOverrideConfig);
+        root2.addChild(child);
+        assertEquals(childOverrideConfig, child.getOverrideConfiguration());
+        assertEquals(mergedOverrideConfig, child.getMergedOverrideConfiguration());
+        assertEquals(mergedOverrideConfig, child.getConfiguration());
+    }
+
+    @Test
+    public void testConfigurationChangePropagation() throws Exception {
+        // Builds 3-level vertical hierarchy with one configuration container on each level.
+        // In addition to different overrides on each level, everyone in hierarchy will have one
+        // common overridden value - orientation;
+
+        // Init root's config.
+        final TestConfigurationContainer root = new TestConfigurationContainer();
+        final Configuration rootOverrideConfig = new Configuration();
+        rootOverrideConfig.fontScale = 1.3f;
+        rootOverrideConfig.orientation = SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
+        root.onOverrideConfigurationChanged(rootOverrideConfig);
+
+        // Init children.
+        final TestConfigurationContainer child1 = root.addChild();
+        final Configuration childOverrideConfig1 = new Configuration();
+        childOverrideConfig1.densityDpi = 320;
+        childOverrideConfig1.orientation = SCREEN_ORIENTATION_LANDSCAPE;
+        child1.onOverrideConfigurationChanged(childOverrideConfig1);
+
+        final TestConfigurationContainer child2 = child1.addChild();
+        final Configuration childOverrideConfig2 = new Configuration();
+        childOverrideConfig2.screenWidthDp = 150;
+        childOverrideConfig2.orientation = SCREEN_ORIENTATION_PORTRAIT;
+        child2.onOverrideConfigurationChanged(childOverrideConfig2);
+
+        // Check configuration on all levels when root override is updated.
+        rootOverrideConfig.smallestScreenWidthDp = 200;
+        root.onOverrideConfigurationChanged(rootOverrideConfig);
+
+        final Configuration mergedOverrideConfig1 = new Configuration(rootOverrideConfig);
+        mergedOverrideConfig1.updateFrom(childOverrideConfig1);
+        final Configuration mergedConfig1 = new Configuration(mergedOverrideConfig1);
+
+        final Configuration mergedOverrideConfig2 = new Configuration(mergedOverrideConfig1);
+        mergedOverrideConfig2.updateFrom(childOverrideConfig2);
+        final Configuration mergedConfig2 = new Configuration(mergedOverrideConfig2);
+
+        assertEquals(rootOverrideConfig, root.getOverrideConfiguration());
+        assertEquals(rootOverrideConfig, root.getMergedOverrideConfiguration());
+        assertEquals(rootOverrideConfig, root.getConfiguration());
+
+        assertEquals(childOverrideConfig1, child1.getOverrideConfiguration());
+        assertEquals(mergedOverrideConfig1, child1.getMergedOverrideConfiguration());
+        assertEquals(mergedConfig1, child1.getConfiguration());
+
+        assertEquals(childOverrideConfig2, child2.getOverrideConfiguration());
+        assertEquals(mergedOverrideConfig2, child2.getMergedOverrideConfiguration());
+        assertEquals(mergedConfig2, child2.getConfiguration());
+
+        // Check configuration on all levels when root parent config is updated.
+        final Configuration rootParentConfig = new Configuration();
+        rootParentConfig.screenHeightDp = 100;
+        rootParentConfig.orientation = SCREEN_ORIENTATION_REVERSE_PORTRAIT;
+        root.onConfigurationChanged(rootParentConfig);
+        final Configuration mergedRootConfig = new Configuration(rootParentConfig);
+        mergedRootConfig.updateFrom(rootOverrideConfig);
+
+        mergedConfig1.setTo(mergedRootConfig);
+        mergedConfig1.updateFrom(mergedOverrideConfig1);
+
+        mergedConfig2.setTo(mergedConfig1);
+        mergedConfig2.updateFrom(mergedOverrideConfig2);
+
+        assertEquals(rootOverrideConfig, root.getOverrideConfiguration());
+        assertEquals(rootOverrideConfig, root.getMergedOverrideConfiguration());
+        assertEquals(mergedRootConfig, root.getConfiguration());
+
+        assertEquals(childOverrideConfig1, child1.getOverrideConfiguration());
+        assertEquals(mergedOverrideConfig1, child1.getMergedOverrideConfiguration());
+        assertEquals(mergedConfig1, child1.getConfiguration());
+
+        assertEquals(childOverrideConfig2, child2.getOverrideConfiguration());
+        assertEquals(mergedOverrideConfig2, child2.getMergedOverrideConfiguration());
+        assertEquals(mergedConfig2, child2.getConfiguration());
+    }
+
+    @Test
+    public void testSetWindowingMode() throws Exception {
+        final TestConfigurationContainer root = new TestConfigurationContainer();
+        root.setWindowingMode(WINDOWING_MODE_UNDEFINED);
+        final TestConfigurationContainer child = root.addChild();
+        child.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        assertEquals(WINDOWING_MODE_UNDEFINED, root.getWindowingMode());
+        assertEquals(WINDOWING_MODE_FREEFORM, child.getWindowingMode());
+
+        root.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        assertEquals(WINDOWING_MODE_FULLSCREEN, root.getWindowingMode());
+        assertEquals(WINDOWING_MODE_FREEFORM, child.getWindowingMode());
+    }
+
+    @Test
+    public void testSetActivityType() throws Exception {
+        final TestConfigurationContainer root = new TestConfigurationContainer();
+        root.setActivityType(ACTIVITY_TYPE_UNDEFINED);
+        final TestConfigurationContainer child = root.addChild();
+        child.setActivityType(ACTIVITY_TYPE_STANDARD);
+        assertEquals(ACTIVITY_TYPE_UNDEFINED, root.getActivityType());
+        assertEquals(ACTIVITY_TYPE_STANDARD, child.getActivityType());
+
+        boolean gotException = false;
+        try {
+            // Can't change activity type once set.
+            child.setActivityType(ACTIVITY_TYPE_HOME);
+        } catch (IllegalStateException e) {
+            gotException = true;
+        }
+        assertTrue("Can't change activity type once set.", gotException);
+
+        // TODO: Commenting out for now until we figure-out a good way to test these rules that
+        // should only apply to system process.
+        /*
+        gotException = false;
+        try {
+            // Parent can't change child's activity type once set.
+            root.setActivityType(ACTIVITY_TYPE_HOME);
+        } catch (IllegalStateException e) {
+            gotException = true;
+        }
+        assertTrue("Parent can't change activity type once set.", gotException);
+        assertEquals(ACTIVITY_TYPE_HOME, root.getActivityType());
+
+        final TestConfigurationContainer child2 = new TestConfigurationContainer();
+        child2.setActivityType(ACTIVITY_TYPE_RECENTS);
+
+        gotException = false;
+        try {
+            // Can't re-parent to a different activity type.
+            root.addChild(child2);
+        } catch (IllegalStateException e) {
+            gotException = true;
+        }
+        assertTrue("Can't re-parent to a different activity type.", gotException);
+        */
+
+    }
+
+    @Test
+    public void testRegisterConfigurationChangeListener() throws Exception {
+        final TestConfigurationContainer container = new TestConfigurationContainer();
+        final TestConfigurationChangeListener listener = new TestConfigurationChangeListener();
+        final Configuration config = new Configuration();
+        config.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        config.windowConfiguration.setAppBounds(10, 10, 10, 10);
+        container.onOverrideConfigurationChanged(config);
+        container.registerConfigurationChangeListener(listener);
+        // Assert listener got the current config. of the container after it was registered.
+        assertEquals(config, listener.mOverrideConfiguration);
+        // Assert listener gets changes to override configuration.
+        container.onOverrideConfigurationChanged(EMPTY);
+        assertEquals(EMPTY, listener.mOverrideConfiguration);
+    }
+
+    /**
+     * Contains minimal implementation of {@link ConfigurationContainer}'s abstract behavior needed
+     * for testing.
+     */
+    private class TestConfigurationContainer
+            extends ConfigurationContainer<TestConfigurationContainer> {
+        private List<TestConfigurationContainer> mChildren = new ArrayList<>();
+        private TestConfigurationContainer mParent;
+
+        TestConfigurationContainer addChild(TestConfigurationContainer childContainer) {
+            childContainer.mParent = this;
+            childContainer.onParentChanged();
+            mChildren.add(childContainer);
+            return childContainer;
+        }
+
+        TestConfigurationContainer addChild() {
+            return addChild(new TestConfigurationContainer());
+        }
+
+        void removeChild(TestConfigurationContainer child) {
+            child.mParent = null;
+            child.onParentChanged();
+        }
+
+        @Override
+        protected int getChildCount() {
+            return mChildren.size();
+        }
+
+        @Override
+        protected TestConfigurationContainer getChildAt(int index) {
+            return mChildren.get(index);
+        }
+
+        @Override
+        protected ConfigurationContainer getParent() {
+            return mParent;
+        }
+    }
+
+    private class TestConfigurationChangeListener implements ConfigurationContainerListener {
+
+        final Configuration mOverrideConfiguration = new Configuration();
+
+        public void onOverrideConfigurationChanged(Configuration overrideConfiguration) {
+            mOverrideConfiguration.setTo(overrideConfiguration);
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java b/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java
new file mode 100644
index 0000000..6769e40
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.SurfaceControl;
+import android.view.SurfaceSession;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:com.android.server.wm.DimmerTests;
+ */
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class DimmerTests extends WindowTestsBase {
+
+    private class TestWindowContainer extends WindowContainer<TestWindowContainer> {
+        final SurfaceControl mControl = mock(SurfaceControl.class);
+        final SurfaceControl.Transaction mTransaction = mock(SurfaceControl.Transaction.class);
+
+        TestWindowContainer() {
+            super(sWm);
+        }
+
+        @Override
+        public SurfaceControl getSurfaceControl() {
+            return mControl;
+        }
+
+        @Override
+        public SurfaceControl.Transaction getPendingTransaction() {
+            return mTransaction;
+        }
+    }
+
+    private class MockSurfaceBuildingContainer extends WindowContainer<TestWindowContainer> {
+        final SurfaceSession mSession = new SurfaceSession();
+        final SurfaceControl mHostControl = mock(SurfaceControl.class);
+        final SurfaceControl.Transaction mHostTransaction = mock(SurfaceControl.Transaction.class);
+
+        MockSurfaceBuildingContainer() {
+            super(sWm);
+        }
+
+        class MockSurfaceBuilder extends SurfaceControl.Builder {
+            MockSurfaceBuilder(SurfaceSession ss) {
+                super(ss);
+            }
+
+            @Override
+            public SurfaceControl build() {
+                return mock(SurfaceControl.class);
+            }
+        }
+
+        @Override
+        SurfaceControl.Builder makeChildSurface(WindowContainer child) {
+            return new MockSurfaceBuilder(mSession);
+        }
+
+        @Override
+        public SurfaceControl getSurfaceControl() {
+            return mHostControl;
+        }
+
+        @Override
+        public SurfaceControl.Transaction getPendingTransaction() {
+            return mHostTransaction;
+        }
+    }
+
+    private MockSurfaceBuildingContainer mHost;
+    private Dimmer mDimmer;
+    private SurfaceControl.Transaction mTransaction;
+    private Dimmer.SurfaceAnimatorStarter mSurfaceAnimatorStarter;
+
+    private static class SurfaceAnimatorStarterImpl implements Dimmer.SurfaceAnimatorStarter {
+        @Override
+        public void startAnimation(SurfaceAnimator surfaceAnimator, SurfaceControl.Transaction t,
+                AnimationAdapter anim, boolean hidden) {
+            surfaceAnimator.mAnimationFinishedCallback.run();
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        mHost = new MockSurfaceBuildingContainer();
+        mSurfaceAnimatorStarter = spy(new SurfaceAnimatorStarterImpl());
+        mTransaction = mock(SurfaceControl.Transaction.class);
+        mDimmer = new Dimmer(mHost, mSurfaceAnimatorStarter);
+    }
+
+    @Test
+    public void testDimAboveNoChildCreatesSurface() throws Exception {
+        final float alpha = 0.8f;
+        mDimmer.dimAbove(mTransaction, alpha);
+
+        SurfaceControl dimLayer = getDimLayer();
+
+        assertNotNull("Dimmer should have created a surface", dimLayer);
+
+        verify(mTransaction).setAlpha(dimLayer, alpha);
+        verify(mTransaction).setLayer(dimLayer, Integer.MAX_VALUE);
+    }
+
+    @Test
+    public void testDimAboveNoChildRedundantlyUpdatesAlphaOnExistingSurface() throws Exception {
+        float alpha = 0.8f;
+        mDimmer.dimAbove(mTransaction, alpha);
+        final SurfaceControl firstSurface = getDimLayer();
+
+        alpha = 0.9f;
+        mDimmer.dimAbove(mTransaction, alpha);
+
+        assertEquals(firstSurface, getDimLayer());
+        verify(mTransaction).setAlpha(firstSurface, 0.9f);
+    }
+
+    @Test
+    public void testUpdateDimsAppliesSize() throws Exception {
+        mDimmer.dimAbove(mTransaction, 0.8f);
+
+        int width = 100;
+        int height = 300;
+        Rect bounds = new Rect(0, 0, width, height);
+        mDimmer.updateDims(mTransaction, bounds);
+
+        verify(mTransaction).setSize(getDimLayer(), width, height);
+        verify(mTransaction).show(getDimLayer());
+    }
+
+    @Test
+    public void testDimAboveNoChildNotReset() throws Exception {
+        mDimmer.dimAbove(mTransaction, 0.8f);
+        SurfaceControl dimLayer = getDimLayer();
+        mDimmer.resetDimStates();
+
+        mDimmer.updateDims(mTransaction, new Rect());
+        verify(mTransaction).show(getDimLayer());
+        verify(dimLayer, never()).destroy();
+    }
+
+    @Test
+    public void testDimAboveWithChildCreatesSurfaceAboveChild() throws Exception {
+        TestWindowContainer child = new TestWindowContainer();
+        mHost.addChild(child, 0);
+
+        final float alpha = 0.8f;
+        mDimmer.dimAbove(mTransaction, child, alpha);
+        SurfaceControl dimLayer = getDimLayer();
+
+        assertNotNull("Dimmer should have created a surface", dimLayer);
+
+        verify(mTransaction).setAlpha(dimLayer, alpha);
+        verify(mTransaction).setRelativeLayer(dimLayer, child.mControl, 1);
+    }
+
+    @Test
+    public void testDimBelowWithChildSurfaceCreatesSurfaceBelowChild() throws Exception {
+        TestWindowContainer child = new TestWindowContainer();
+        mHost.addChild(child, 0);
+
+        final float alpha = 0.8f;
+        mDimmer.dimBelow(mTransaction, child, alpha);
+        SurfaceControl dimLayer = getDimLayer();
+
+        assertNotNull("Dimmer should have created a surface", dimLayer);
+
+        verify(mTransaction).setAlpha(dimLayer, alpha);
+        verify(mTransaction).setRelativeLayer(dimLayer, child.mControl, -1);
+    }
+
+    @Test
+    public void testDimBelowWithChildSurfaceDestroyedWhenReset() throws Exception {
+        TestWindowContainer child = new TestWindowContainer();
+        mHost.addChild(child, 0);
+
+        final float alpha = 0.8f;
+        mDimmer.dimAbove(mTransaction, child, alpha);
+        SurfaceControl dimLayer = getDimLayer();
+        mDimmer.resetDimStates();
+
+        mDimmer.updateDims(mTransaction, new Rect());
+        verify(mSurfaceAnimatorStarter).startAnimation(any(SurfaceAnimator.class), any(
+                SurfaceControl.Transaction.class), any(AnimationAdapter.class), anyBoolean());
+        verify(dimLayer).destroy();
+    }
+
+    @Test
+    public void testDimBelowWithChildSurfaceNotDestroyedWhenPersisted() throws Exception {
+        TestWindowContainer child = new TestWindowContainer();
+        mHost.addChild(child, 0);
+
+        final float alpha = 0.8f;
+        mDimmer.dimAbove(mTransaction, child, alpha);
+        SurfaceControl dimLayer = getDimLayer();
+        mDimmer.resetDimStates();
+        mDimmer.dimAbove(mTransaction, child, alpha);
+
+        mDimmer.updateDims(mTransaction, new Rect());
+        verify(mTransaction).show(dimLayer);
+        verify(dimLayer, never()).destroy();
+    }
+
+    @Test
+    public void testDimUpdateWhileDimming() throws Exception {
+        Rect bounds = new Rect();
+        TestWindowContainer child = new TestWindowContainer();
+        mHost.addChild(child, 0);
+
+        final float alpha = 0.8f;
+        mDimmer.dimAbove(mTransaction, child, alpha);
+
+        SurfaceControl dimLayer = getDimLayer();
+        bounds.set(0, 0, 10, 10);
+        mDimmer.updateDims(mTransaction, bounds);
+        verify(mTransaction, times(1)).show(dimLayer);
+        verify(mTransaction).setSize(dimLayer, bounds.width(), bounds.height());
+        verify(mTransaction).setPosition(dimLayer, 0, 0);
+
+        bounds.set(10, 10, 30, 30);
+        mDimmer.updateDims(mTransaction, bounds);
+        verify(mTransaction).setSize(dimLayer, bounds.width(), bounds.height());
+        verify(mTransaction).setPosition(dimLayer, 10, 10);
+    }
+
+    @Test
+    public void testRemoveDimImmediately() throws Exception {
+        TestWindowContainer child = new TestWindowContainer();
+        mHost.addChild(child, 0);
+
+        mDimmer.dimAbove(mTransaction, child, 1);
+        SurfaceControl dimLayer = getDimLayer();
+        mDimmer.updateDims(mTransaction, new Rect());
+        verify(mTransaction, times(1)).show(dimLayer);
+
+        reset(mSurfaceAnimatorStarter);
+        mDimmer.dontAnimateExit();
+        mDimmer.resetDimStates();
+        mDimmer.updateDims(mTransaction, new Rect());
+        verify(mSurfaceAnimatorStarter, never()).startAnimation(any(SurfaceAnimator.class), any(
+                SurfaceControl.Transaction.class), any(AnimationAdapter.class), anyBoolean());
+        verify(mTransaction).destroy(dimLayer);
+    }
+
+    private SurfaceControl getDimLayer() {
+        return mDimmer.mDimState.mDimLayer;
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
new file mode 100644
index 0000000..ac196f9
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -0,0 +1,550 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.DisplayCutout.fromBoundingRect;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
+import static com.android.server.wm.WindowContainer.POSITION_TOP;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.annotation.SuppressLint;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.DisplayMetrics;
+import android.util.SparseIntArray;
+import android.view.DisplayCutout;
+import android.view.MotionEvent;
+import android.view.Surface;
+
+import com.android.server.wm.utils.WmDisplayCutout;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Tests for the {@link DisplayContent} class.
+ *
+ * Build/Install/Run:
+ *  atest com.android.server.wm.DisplayContentTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class DisplayContentTests extends WindowTestsBase {
+
+    @Test
+    @FlakyTest(bugId = 77772044)
+    public void testForAllWindows() throws Exception {
+        final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION,
+                mDisplayContent, "exiting app");
+        final AppWindowToken exitingAppToken = exitingAppWindow.mAppToken;
+        exitingAppToken.mIsExiting = true;
+        exitingAppToken.getTask().mStack.mExitingAppTokens.add(exitingAppToken);
+
+        assertForAllWindowsOrder(Arrays.asList(
+                mWallpaperWindow,
+                exitingAppWindow,
+                mChildAppWindowBelow,
+                mAppWindow,
+                mChildAppWindowAbove,
+                mDockedDividerWindow,
+                mStatusBarWindow,
+                mNavBarWindow,
+                mImeWindow,
+                mImeDialogWindow));
+    }
+
+    @Test
+    public void testForAllWindows_WithAppImeTarget() throws Exception {
+        final WindowState imeAppTarget =
+                createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
+
+        sWm.mInputMethodTarget = imeAppTarget;
+
+        assertForAllWindowsOrder(Arrays.asList(
+                mWallpaperWindow,
+                mChildAppWindowBelow,
+                mAppWindow,
+                mChildAppWindowAbove,
+                imeAppTarget,
+                mImeWindow,
+                mImeDialogWindow,
+                mDockedDividerWindow,
+                mStatusBarWindow,
+                mNavBarWindow));
+    }
+
+    @Test
+    public void testForAllWindows_WithChildWindowImeTarget() throws Exception {
+        sWm.mInputMethodTarget = mChildAppWindowAbove;
+
+        assertForAllWindowsOrder(Arrays.asList(
+                mWallpaperWindow,
+                mChildAppWindowBelow,
+                mAppWindow,
+                mChildAppWindowAbove,
+                mImeWindow,
+                mImeDialogWindow,
+                mDockedDividerWindow,
+                mStatusBarWindow,
+                mNavBarWindow));
+    }
+
+    @Test
+    public void testForAllWindows_WithStatusBarImeTarget() throws Exception {
+        sWm.mInputMethodTarget = mStatusBarWindow;
+
+        assertForAllWindowsOrder(Arrays.asList(
+                mWallpaperWindow,
+                mChildAppWindowBelow,
+                mAppWindow,
+                mChildAppWindowAbove,
+                mDockedDividerWindow,
+                mStatusBarWindow,
+                mImeWindow,
+                mImeDialogWindow,
+                mNavBarWindow));
+    }
+
+    @Test
+    public void testForAllWindows_WithInBetweenWindowToken() throws Exception {
+        // This window is set-up to be z-ordered between some windows that go in the same token like
+        // the nav bar and status bar.
+        final WindowState voiceInteractionWindow = createWindow(null, TYPE_VOICE_INTERACTION,
+                mDisplayContent, "voiceInteractionWindow");
+
+        assertForAllWindowsOrder(Arrays.asList(
+                mWallpaperWindow,
+                mChildAppWindowBelow,
+                mAppWindow,
+                mChildAppWindowAbove,
+                mDockedDividerWindow,
+                voiceInteractionWindow,
+                mStatusBarWindow,
+                mNavBarWindow,
+                mImeWindow,
+                mImeDialogWindow));
+    }
+
+    @Test
+    public void testComputeImeTarget() throws Exception {
+        // Verify that an app window can be an ime target.
+        final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
+        appWin.setHasSurface(true);
+        assertTrue(appWin.canBeImeTarget());
+        WindowState imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
+        assertEquals(appWin, imeTarget);
+        appWin.mHidden = false;
+
+        // Verify that an child window can be an ime target.
+        final WindowState childWin = createWindow(appWin,
+                TYPE_APPLICATION_ATTACHED_DIALOG, "childWin");
+        childWin.setHasSurface(true);
+        assertTrue(childWin.canBeImeTarget());
+        imeTarget = mDisplayContent.computeImeTarget(false /* updateImeTarget */);
+        assertEquals(childWin, imeTarget);
+    }
+
+    /**
+     * This tests stack movement between displays and proper stack's, task's and app token's display
+     * container references updates.
+     */
+    @Test
+    public void testMoveStackBetweenDisplays() throws Exception {
+        // Create a second display.
+        final DisplayContent dc = createNewDisplay();
+
+        // Add stack with activity.
+        final TaskStack 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 */);
+        final WindowTestUtils.TestAppWindowToken token = WindowTestUtils.createTestAppWindowToken(
+                dc);
+        task.addChild(token, 0);
+        assertEquals(dc, task.getDisplayContent());
+        assertEquals(dc, token.getDisplayContent());
+
+        // 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, token.getDisplayContent());
+    }
+
+    /**
+     * This tests override configuration updates for display content.
+     */
+    @Test
+    public void testDisplayOverrideConfigUpdate() throws Exception {
+        final int displayId = mDisplayContent.getDisplayId();
+        final Configuration currentOverrideConfig = mDisplayContent.getOverrideConfiguration();
+
+        // Create new, slightly changed override configuration and apply it to the display.
+        final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
+        newOverrideConfig.densityDpi += 120;
+        newOverrideConfig.fontScale += 0.3;
+
+        sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, displayId);
+
+        // Check that override config is applied.
+        assertEquals(newOverrideConfig, mDisplayContent.getOverrideConfiguration());
+    }
+
+    /**
+     * This tests global configuration updates when default display config is updated.
+     */
+    @Test
+    public void testDefaultDisplayOverrideConfigUpdate() throws Exception {
+        final Configuration currentConfig = mDisplayContent.getConfiguration();
+
+        // Create new, slightly changed override configuration and apply it to the display.
+        final Configuration newOverrideConfig = new Configuration(currentConfig);
+        newOverrideConfig.densityDpi += 120;
+        newOverrideConfig.fontScale += 0.3;
+
+        sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, DEFAULT_DISPLAY);
+
+        // Check that global configuration is updated, as we've updated default display's config.
+        Configuration globalConfig = sWm.mRoot.getConfiguration();
+        assertEquals(newOverrideConfig.densityDpi, globalConfig.densityDpi);
+        assertEquals(newOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
+
+        // Return back to original values.
+        sWm.setNewDisplayOverrideConfiguration(currentConfig, DEFAULT_DISPLAY);
+        globalConfig = sWm.mRoot.getConfiguration();
+        assertEquals(currentConfig.densityDpi, globalConfig.densityDpi);
+        assertEquals(currentConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
+    }
+
+    /**
+     * Tests tapping on a stack in different display results in window gaining focus.
+     */
+    @Test
+    public void testInputEventBringsCorrectDisplayInFocus() throws Exception {
+        DisplayContent dc0 = sWm.getDefaultDisplayContentLocked();
+        // Create a second display
+        final DisplayContent dc1 = createNewDisplay();
+
+        // Add stack with activity.
+        final TaskStack stack0 = createTaskStackOnDisplay(dc0);
+        final Task task0 = createTaskInStack(stack0, 0 /* userId */);
+        final WindowTestUtils.TestAppWindowToken token =
+                WindowTestUtils.createTestAppWindowToken(dc0);
+        task0.addChild(token, 0);
+        dc0.mTapDetector = new TaskTapPointerEventListener(sWm, dc0);
+        sWm.registerPointerEventListener(dc0.mTapDetector);
+        final TaskStack stack1 = createTaskStackOnDisplay(dc1);
+        final Task task1 = createTaskInStack(stack1, 0 /* userId */);
+        final WindowTestUtils.TestAppWindowToken token1 =
+                WindowTestUtils.createTestAppWindowToken(dc0);
+        task1.addChild(token1, 0);
+        dc1.mTapDetector = new TaskTapPointerEventListener(sWm, dc0);
+        sWm.registerPointerEventListener(dc1.mTapDetector);
+
+        // tap on primary display (by sending ACTION_DOWN followed by ACTION_UP)
+        DisplayMetrics dm0 = dc0.getDisplayMetrics();
+        dc0.mTapDetector.onPointerEvent(
+                createTapEvent(dm0.widthPixels / 2, dm0.heightPixels / 2, true));
+        dc0.mTapDetector.onPointerEvent(
+                createTapEvent(dm0.widthPixels / 2, dm0.heightPixels / 2, false));
+
+        // Check focus is on primary display.
+        assertEquals(sWm.mCurrentFocus, dc0.findFocusedWindow());
+
+        // Tap on secondary display
+        DisplayMetrics dm1 = dc1.getDisplayMetrics();
+        dc1.mTapDetector.onPointerEvent(
+                createTapEvent(dm1.widthPixels / 2, dm1.heightPixels / 2, true));
+        dc1.mTapDetector.onPointerEvent(
+                createTapEvent(dm1.widthPixels / 2, dm1.heightPixels / 2, false));
+
+        // Check focus is on secondary.
+        assertEquals(sWm.mCurrentFocus, dc1.findFocusedWindow());
+    }
+
+    @Test
+    public void testFocusedWindowMultipleDisplays() throws Exception {
+        // Create a focusable window and check that focus is calculated correctly
+        final WindowState window1 =
+                createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "window1");
+        assertEquals(window1, sWm.mRoot.computeFocusedWindow());
+
+        // Check that a new display doesn't affect focus
+        final DisplayContent dc = createNewDisplay();
+        assertEquals(window1, sWm.mRoot.computeFocusedWindow());
+
+        // Add a window to the second display, and it should be focused
+        final WindowState window2 = createWindow(null, TYPE_BASE_APPLICATION, dc, "window2");
+        assertEquals(window2, sWm.mRoot.computeFocusedWindow());
+
+        // Move the first window to the to including parents, and make sure focus is updated
+        window1.getParent().positionChildAt(POSITION_TOP, window1, true);
+        assertEquals(window1, sWm.mRoot.computeFocusedWindow());
+    }
+
+    @Test
+    public void testKeyguard_preventsSecondaryDisplayFocus() throws Exception {
+        final WindowState keyguard = createWindow(null, TYPE_STATUS_BAR,
+                sWm.getDefaultDisplayContentLocked(), "keyguard");
+        assertEquals(keyguard, sWm.mRoot.computeFocusedWindow());
+
+        // Add a window to a second display, and it should be focused
+        final DisplayContent dc = createNewDisplay();
+        final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "win");
+        assertEquals(win, sWm.mRoot.computeFocusedWindow());
+
+        mWmRule.getWindowManagerPolicy().keyguardShowingAndNotOccluded = true;
+        assertEquals(keyguard, sWm.mRoot.computeFocusedWindow());
+    }
+
+    /**
+     * This tests setting the maximum ui width on a display.
+     */
+    @Test
+    public void testMaxUiWidth() throws Exception {
+        final int baseWidth = 1440;
+        final int baseHeight = 2560;
+        final int baseDensity = 300;
+
+        mDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
+
+        final int maxWidth = 300;
+        final int resultingHeight = (maxWidth * baseHeight) / baseWidth;
+        final int resultingDensity = (maxWidth * baseDensity) / baseWidth;
+
+        mDisplayContent.setMaxUiWidth(maxWidth);
+        verifySizes(mDisplayContent, maxWidth, resultingHeight, resultingDensity);
+
+        // Assert setting values again does not change;
+        mDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
+        verifySizes(mDisplayContent, maxWidth, resultingHeight, resultingDensity);
+
+        final int smallerWidth = 200;
+        final int smallerHeight = 400;
+        final int smallerDensity = 100;
+
+        // Specify smaller dimension, verify that it is honored
+        mDisplayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity);
+        verifySizes(mDisplayContent, smallerWidth, smallerHeight, smallerDensity);
+
+        // Verify that setting the max width to a greater value than the base width has no effect
+        mDisplayContent.setMaxUiWidth(maxWidth);
+        verifySizes(mDisplayContent, smallerWidth, smallerHeight, smallerDensity);
+    }
+
+    /**
+     * This test enforces that the pinned stack is always kept as the top stack.
+     */
+    @Test
+    public void testPinnedStackLocation() {
+        final TaskStack pinnedStack = createStackControllerOnStackOnDisplay(
+                WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mDisplayContent).mContainer;
+        // Ensure that the pinned stack is the top stack
+        assertEquals(pinnedStack, mDisplayContent.getPinnedStack());
+        assertEquals(pinnedStack, mDisplayContent.getTopStack());
+        // By default, this should try to create a new stack on top
+        final TaskStack otherStack = createTaskStackOnDisplay(mDisplayContent);
+        // Ensure that the other stack is on the display.
+        assertEquals(mDisplayContent, otherStack.getDisplayContent());
+        // Ensure that the pinned stack is still on top
+        assertEquals(pinnedStack, mDisplayContent.getTopStack());
+    }
+
+    /**
+     * Test that WM does not report displays to AM that are pending to be removed.
+     */
+    @Test
+    public void testDontReportDeferredRemoval() {
+        // Create a display and add an animating window to it.
+        final DisplayContent dc = createNewDisplay();
+        final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
+        window.mAnimatingExit = true;
+        // Request display removal, it should be deferred.
+        dc.removeIfPossible();
+        // Request ordered display ids from WM.
+        final SparseIntArray orderedDisplayIds = new SparseIntArray();
+        sWm.getDisplaysInFocusOrder(orderedDisplayIds);
+        // Make sure that display that is marked for removal is not reported.
+        assertEquals(-1, orderedDisplayIds.indexOfValue(dc.getDisplayId()));
+    }
+
+    @Test
+    public void testDisplayCutout_rot0() throws Exception {
+        synchronized (sWm.getWindowManagerLock()) {
+            final DisplayContent dc = createNewDisplay();
+            dc.mInitialDisplayWidth = 200;
+            dc.mInitialDisplayHeight = 400;
+            Rect r = new Rect(80, 0, 120, 10);
+            final DisplayCutout cutout = new WmDisplayCutout(
+                    fromBoundingRect(r.left, r.top, r.right, r.bottom), null)
+                    .computeSafeInsets(200, 400).getDisplayCutout();
+
+            dc.mInitialDisplayCutout = cutout;
+            dc.setRotation(Surface.ROTATION_0);
+            dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
+
+            assertEquals(cutout, dc.getDisplayInfo().displayCutout);
+        }
+    }
+
+    @Test
+    public void testDisplayCutout_rot90() throws Exception {
+        synchronized (sWm.getWindowManagerLock()) {
+            final DisplayContent dc = createNewDisplay();
+            dc.mInitialDisplayWidth = 200;
+            dc.mInitialDisplayHeight = 400;
+            Rect r1 = new Rect(80, 0, 120, 10);
+            final DisplayCutout cutout = new WmDisplayCutout(
+                    fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom), null)
+                    .computeSafeInsets(200, 400).getDisplayCutout();
+
+            dc.mInitialDisplayCutout = cutout;
+            dc.setRotation(Surface.ROTATION_90);
+            dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
+
+            final Rect r = new Rect(0, 80, 10, 120);
+            assertEquals(new WmDisplayCutout(
+                    fromBoundingRect(r.left, r.top, r.right, r.bottom), null)
+                    .computeSafeInsets(400, 200).getDisplayCutout(), dc.getDisplayInfo().displayCutout);
+        }
+    }
+
+    @Test
+    public void testLayoutSeq_assignedDuringLayout() throws Exception {
+        synchronized (sWm.getWindowManagerLock()) {
+
+            final DisplayContent dc = createNewDisplay();
+            final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
+
+            dc.setLayoutNeeded();
+            dc.performLayout(true /* initial */, false /* updateImeWindows */);
+
+            assertThat(win.mLayoutSeq, is(dc.mLayoutSeq));
+        }
+    }
+
+    @Test
+    @SuppressLint("InlinedApi")
+    public void testOrientationDefinedByKeyguard() {
+        final DisplayContent dc = createNewDisplay();
+        // Create a window that requests landscape orientation. It will define device orientation
+        // by default.
+        final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
+        window.mAppToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+
+        final WindowState keyguard = createWindow(null, TYPE_STATUS_BAR, dc, "keyguard");
+        keyguard.mHasSurface = true;
+        keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
+
+        assertEquals("Screen orientation must be defined by the app window by default",
+                SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
+
+        keyguard.mAttrs.screenOrientation = SCREEN_ORIENTATION_PORTRAIT;
+        assertEquals("Visible keyguard must influence device orientation",
+                SCREEN_ORIENTATION_PORTRAIT, dc.getOrientation());
+
+        sWm.setKeyguardGoingAway(true);
+        assertEquals("Keyguard that is going away must not influence device orientation",
+                SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
+    }
+
+    @Test
+    public void testDisableDisplayInfoOverrideFromWindowManager() {
+        final DisplayContent dc = createNewDisplay();
+
+        assertTrue(dc.mShouldOverrideDisplayConfiguration);
+        sWm.dontOverrideDisplayInfo(dc.getDisplayId());
+
+        assertFalse(dc.mShouldOverrideDisplayConfiguration);
+        verify(sWm.mDisplayManagerInternal, times(1))
+                .setDisplayInfoOverrideFromWindowManager(dc.getDisplayId(), null);
+    }
+
+    private static void verifySizes(DisplayContent displayContent, int expectedBaseWidth,
+                             int expectedBaseHeight, int expectedBaseDensity) {
+        assertEquals(displayContent.mBaseDisplayWidth, expectedBaseWidth);
+        assertEquals(displayContent.mBaseDisplayHeight, expectedBaseHeight);
+        assertEquals(displayContent.mBaseDisplayDensity, expectedBaseDensity);
+    }
+
+    private void assertForAllWindowsOrder(List<WindowState> expectedWindowsBottomToTop) {
+        final LinkedList<WindowState> actualWindows = new LinkedList<>();
+
+        // Test forward traversal.
+        mDisplayContent.forAllWindows(actualWindows::addLast, false /* traverseTopToBottom */);
+        assertThat("bottomToTop", actualWindows, is(expectedWindowsBottomToTop));
+
+        actualWindows.clear();
+
+        // Test backward traversal.
+        mDisplayContent.forAllWindows(actualWindows::addLast, true /* traverseTopToBottom */);
+        assertThat("topToBottom", actualWindows, is(reverseList(expectedWindowsBottomToTop)));
+    }
+
+    private static List<WindowState> reverseList(List<WindowState> list) {
+        final ArrayList<WindowState> result = new ArrayList<>(list);
+        Collections.reverse(result);
+        return result;
+    }
+
+    private MotionEvent createTapEvent(float x, float y, boolean isDownEvent) {
+        final long downTime = SystemClock.uptimeMillis();
+        final long eventTime = SystemClock.uptimeMillis() + 100;
+        final int metaState = 0;
+
+        return MotionEvent.obtain(
+                downTime,
+                eventTime,
+                isDownEvent ? MotionEvent.ACTION_DOWN : MotionEvent.ACTION_UP,
+                x,
+                y,
+                metaState);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java
new file mode 100644
index 0000000..a09656c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.ClipData;
+import android.graphics.PixelFormat;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.os.UserManagerInternal;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.InputChannel;
+import android.view.SurfaceControl;
+import android.view.SurfaceSession;
+import android.view.View;
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.LocalServices;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for the {@link DragDropController} class.
+ *
+ * atest com.android.server.wm.DragDropControllerTests
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+@Presubmit
+public class DragDropControllerTests extends WindowTestsBase {
+    private static final int TIMEOUT_MS = 3000;
+    private TestDragDropController mTarget;
+    private WindowState mWindow;
+    private IBinder mToken;
+
+    static class TestDragDropController extends DragDropController {
+        @GuardedBy("sWm.mWindowMap")
+        private Runnable mCloseCallback;
+
+        TestDragDropController(WindowManagerService service, Looper looper) {
+            super(service, looper);
+        }
+
+        void setOnClosedCallbackLocked(Runnable runnable) {
+            assertTrue(dragDropActiveLocked());
+            mCloseCallback = runnable;
+        }
+
+        @Override
+        void onDragStateClosedLocked(DragState dragState) {
+            super.onDragStateClosedLocked(dragState);
+            if (mCloseCallback != null) {
+                mCloseCallback.run();
+                mCloseCallback = null;
+            }
+        }
+    }
+
+    /**
+     * Creates a window state which can be used as a drop target.
+     */
+    private WindowState createDropTargetWindow(String name, int ownerId) {
+        final WindowTestUtils.TestAppWindowToken token = WindowTestUtils.createTestAppWindowToken(
+                mDisplayContent);
+        final TaskStack stack = createStackControllerOnStackOnDisplay(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent).mContainer;
+        final Task task = createTaskInStack(stack, ownerId);
+        task.addChild(token, 0);
+
+        final WindowState window = createWindow(
+                null, TYPE_BASE_APPLICATION, token, name, ownerId, false);
+        window.mInputChannel = new InputChannel();
+        window.mHasSurface = true;
+        return window;
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        final UserManagerInternal userManager = mock(UserManagerInternal.class);
+        LocalServices.addService(UserManagerInternal.class, userManager);
+
+        super.setUp();
+
+        mTarget = new TestDragDropController(sWm, sWm.mH.getLooper());
+        mDisplayContent = spy(mDisplayContent);
+        mWindow = createDropTargetWindow("Drag test window", 0);
+        when(mDisplayContent.getTouchableWinAtPointLocked(0, 0)).thenReturn(mWindow);
+        when(sWm.mInputManager.transferTouchFocus(any(), any())).thenReturn(true);
+
+        synchronized (sWm.mWindowMap) {
+            sWm.mWindowMap.put(mWindow.mClient.asBinder(), mWindow);
+        }
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        LocalServices.removeServiceForTest(UserManagerInternal.class);
+        final CountDownLatch latch;
+        synchronized (sWm.mWindowMap) {
+            if (!mTarget.dragDropActiveLocked()) {
+                return;
+            }
+            if (mToken != null) {
+                mTarget.cancelDragAndDrop(mToken);
+            }
+            latch = new CountDownLatch(1);
+            mTarget.setOnClosedCallbackLocked(() -> {
+                latch.countDown();
+            });
+        }
+        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+    }
+
+    @Test
+    public void testDragFlow() throws Exception {
+        dragFlow(0, ClipData.newPlainText("label", "Test"), 0, 0);
+    }
+
+    @Test
+    public void testPerformDrag_NullDataWithGrantUri() throws Exception {
+        dragFlow(View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ, null, 0, 0);
+    }
+
+    @Test
+    public void testPerformDrag_NullDataToOtherUser() throws Exception {
+        final WindowState otherUsersWindow =
+                createDropTargetWindow("Other user's window", 1 * UserHandle.PER_USER_RANGE);
+        when(mDisplayContent.getTouchableWinAtPointLocked(10, 10))
+                .thenReturn(otherUsersWindow);
+
+        dragFlow(0, null, 10, 10);
+    }
+
+    private void dragFlow(int flag, ClipData data, float dropX, float dropY) {
+        final SurfaceSession appSession = new SurfaceSession();
+        try {
+            final SurfaceControl surface = new SurfaceControl.Builder(appSession)
+                    .setName("drag surface")
+                    .setSize(100, 100)
+                    .setFormat(PixelFormat.TRANSLUCENT)
+                    .build();
+
+            assertTrue(sWm.mInputManager.transferTouchFocus(null, null));
+            mToken = mTarget.performDrag(
+                    new SurfaceSession(), 0, 0, mWindow.mClient, flag, surface, 0, 0, 0, 0, 0,
+                    data);
+            assertNotNull(mToken);
+
+            mTarget.handleMotionEvent(false, dropX, dropY);
+            mToken = mWindow.mClient.asBinder();
+        } finally {
+            appSession.kill();
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/PinnedStackControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/PinnedStackControllerTest.java
new file mode 100644
index 0000000..96745fa
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/PinnedStackControllerTest.java
@@ -0,0 +1,63 @@
+package com.android.server.wm;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.IPinnedStackListener;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class PinnedStackControllerTest extends WindowTestsBase {
+
+    @Mock private IPinnedStackListener mIPinnedStackListener;
+    @Mock private IPinnedStackListener.Stub mIPinnedStackListenerStub;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        MockitoAnnotations.initMocks(this);
+        when(mIPinnedStackListener.asBinder()).thenReturn(mIPinnedStackListenerStub);
+    }
+
+    @Test
+    public void setShelfHeight_shelfVisibilityChangedTriggered() throws RemoteException {
+        sWm.mSupportsPictureInPicture = true;
+        sWm.registerPinnedStackListener(DEFAULT_DISPLAY, mIPinnedStackListener);
+
+        verify(mIPinnedStackListener).onImeVisibilityChanged(false, 0);
+        verify(mIPinnedStackListener).onShelfVisibilityChanged(false, 0);
+        verify(mIPinnedStackListener).onMovementBoundsChanged(any(), any(), any(), eq(false),
+                eq(false), anyInt());
+        verify(mIPinnedStackListener).onActionsChanged(any());
+        verify(mIPinnedStackListener).onMinimizedStateChanged(anyBoolean());
+
+        reset(mIPinnedStackListener);
+
+        final int SHELF_HEIGHT = 300;
+
+        sWm.setShelfHeight(true, SHELF_HEIGHT);
+        verify(mIPinnedStackListener).onShelfVisibilityChanged(true, SHELF_HEIGHT);
+        verify(mIPinnedStackListener).onMovementBoundsChanged(any(), any(), any(), eq(false),
+                eq(true), anyInt());
+        verify(mIPinnedStackListener, never()).onImeVisibilityChanged(anyBoolean(), anyInt());
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
new file mode 100644
index 0000000..a2af9b8
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
+import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.os.Binder;
+import android.os.IInterface;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.IRecentsAnimationRunner;
+import android.view.SurfaceControl;
+import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * atest FrameworksServicesTests:com.android.server.wm.RecentsAnimationControllerTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class RecentsAnimationControllerTest extends WindowTestsBase {
+
+    @Mock SurfaceControl mMockLeash;
+    @Mock SurfaceControl.Transaction mMockTransaction;
+    @Mock OnAnimationFinishedCallback mFinishedCallback;
+    @Mock IRecentsAnimationRunner mMockRunner;
+    @Mock RecentsAnimationController.RecentsAnimationCallbacks mAnimationCallbacks;
+    private RecentsAnimationController mController;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        MockitoAnnotations.initMocks(this);
+        when(mMockRunner.asBinder()).thenReturn(new Binder());
+        mController = new RecentsAnimationController(sWm, mMockRunner, mAnimationCallbacks,
+                DEFAULT_DISPLAY);
+    }
+
+    @Test
+    public void testRemovedBeforeStarted_expectCanceled() throws Exception {
+        final AppWindowToken appWindow = createAppWindowToken(mDisplayContent,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        AnimationAdapter adapter = mController.addAnimation(appWindow.getTask(),
+                false /* isRecentTaskInvisible */);
+        adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+
+        // Remove the app window so that the animation target can not be created
+        appWindow.removeImmediately();
+        mController.startAnimation();
+
+        // Verify that the finish callback to reparent the leash is called
+        verify(mFinishedCallback).onAnimationFinished(eq(adapter));
+        // Verify the animation canceled callback to the app was made
+        verify(mMockRunner).onAnimationCanceled();
+        verifyNoMoreInteractionsExceptAsBinder(mMockRunner);
+    }
+
+    @Test
+    public void testCancelAfterRemove_expectIgnored() throws Exception {
+        final AppWindowToken appWindow = createAppWindowToken(mDisplayContent,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        AnimationAdapter adapter = mController.addAnimation(appWindow.getTask(),
+                false /* isRecentTaskInvisible */);
+        adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+
+        // Remove the app window so that the animation target can not be created
+        appWindow.removeImmediately();
+        mController.startAnimation();
+        mController.cleanupAnimation(REORDER_KEEP_IN_PLACE);
+        try {
+            mController.cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "test");
+        } catch (Exception e) {
+            fail("Unexpected failure when canceling animation after finishing it");
+        }
+    }
+
+    private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) {
+        verify(binder, atLeast(0)).asBinder();
+        verifyNoMoreInteractions(binder);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java
new file mode 100644
index 0000000..95361f0
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.Binder;
+import android.os.IInterface;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.IRemoteAnimationFinishedCallback;
+import android.view.IRemoteAnimationRunner;
+import android.view.RemoteAnimationAdapter;
+import android.view.RemoteAnimationTarget;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
+
+import com.android.server.testutils.OffsettableClock;
+import com.android.server.testutils.TestHandler;
+import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * atest FrameworksServicesTests:com.android.server.wm.RemoteAnimationControllerTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class RemoteAnimationControllerTest extends WindowTestsBase {
+
+    @Mock SurfaceControl mMockLeash;
+    @Mock Transaction mMockTransaction;
+    @Mock OnAnimationFinishedCallback mFinishedCallback;
+    @Mock IRemoteAnimationRunner mMockRunner;
+    private RemoteAnimationAdapter mAdapter;
+    private RemoteAnimationController mController;
+    private final OffsettableClock mClock = new OffsettableClock.Stopped();
+    private TestHandler mHandler;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        MockitoAnnotations.initMocks(this);
+        when(mMockRunner.asBinder()).thenReturn(new Binder());
+        mAdapter = new RemoteAnimationAdapter(mMockRunner, 100, 50);
+        mAdapter.setCallingPid(123);
+        sWm.mH.runWithScissors(() -> {
+            mHandler = new TestHandler(null, mClock);
+        }, 0);
+        mController = new RemoteAnimationController(sWm, mAdapter, mHandler);
+    }
+
+    @Test
+    public void testRun() throws Exception {
+        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        sWm.mOpeningApps.add(win.mAppToken);
+        try {
+            final AnimationAdapter adapter = mController.createAnimationAdapter(win.mAppToken,
+                    new Point(50, 100), new Rect(50, 100, 150, 150));
+            adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+            mController.goodToGo();
+            sWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+            final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
+                    ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
+            final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor =
+                    ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class);
+            verify(mMockRunner).onAnimationStart(appsCaptor.capture(), finishedCaptor.capture());
+            assertEquals(1, appsCaptor.getValue().length);
+            final RemoteAnimationTarget app = appsCaptor.getValue()[0];
+            assertEquals(new Point(50, 100), app.position);
+            assertEquals(new Rect(50, 100, 150, 150), app.sourceContainerBounds);
+            assertEquals(win.mAppToken.getPrefixOrderIndex(), app.prefixOrderIndex);
+            assertEquals(win.mAppToken.getTask().mTaskId, app.taskId);
+            assertEquals(mMockLeash, app.leash);
+            assertEquals(win.mWinAnimator.mLastClipRect, app.clipRect);
+            assertEquals(false, app.isTranslucent);
+            verify(mMockTransaction).setLayer(mMockLeash, app.prefixOrderIndex);
+            verify(mMockTransaction).setPosition(mMockLeash, app.position.x, app.position.y);
+            verify(mMockTransaction).setWindowCrop(mMockLeash, new Rect(0, 0, 100, 50));
+
+            finishedCaptor.getValue().onAnimationFinished();
+            verify(mFinishedCallback).onAnimationFinished(eq(adapter));
+        } finally {
+            sWm.mOpeningApps.clear();
+        }
+    }
+
+    @Test
+    public void testCancel() throws Exception {
+        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        final AnimationAdapter adapter = mController.createAnimationAdapter(win.mAppToken,
+                new Point(50, 100), new Rect(50, 100, 150, 150));
+        adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+        mController.goodToGo();
+
+        adapter.onAnimationCancelled(mMockLeash);
+        verify(mMockRunner).onAnimationCancelled();
+    }
+
+    @Test
+    public void testTimeout() throws Exception {
+        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        final AnimationAdapter adapter = mController.createAnimationAdapter(win.mAppToken,
+                new Point(50, 100), new Rect(50, 100, 150, 150));
+        adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+        mController.goodToGo();
+
+        mClock.fastForward(2500);
+        mHandler.timeAdvance();
+
+        verify(mMockRunner).onAnimationCancelled();
+        verify(mFinishedCallback).onAnimationFinished(eq(adapter));
+    }
+
+    @Test
+    public void testTimeout_scaled() throws Exception {
+        sWm.setAnimationScale(2, 5.0f);
+        try{
+            final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+            final AnimationAdapter adapter = mController.createAnimationAdapter(win.mAppToken,
+                    new Point(50, 100), new Rect(50, 100, 150, 150));
+            adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+            mController.goodToGo();
+
+            mClock.fastForward(2500);
+            mHandler.timeAdvance();
+
+            verify(mMockRunner, never()).onAnimationCancelled();
+
+            mClock.fastForward(10000);
+            mHandler.timeAdvance();
+
+            verify(mMockRunner).onAnimationCancelled();
+            verify(mFinishedCallback).onAnimationFinished(eq(adapter));
+        } finally {
+            sWm.setAnimationScale(2, 1.0f);
+        }
+
+    }
+
+    @Test
+    public void testZeroAnimations() throws Exception {
+        mController.goodToGo();
+        verifyNoMoreInteractionsExceptAsBinder(mMockRunner);
+    }
+
+    @Test
+    public void testNotReallyStarted() throws Exception {
+        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        mController.createAnimationAdapter(win.mAppToken,
+                new Point(50, 100), new Rect(50, 100, 150, 150));
+        mController.goodToGo();
+        verifyNoMoreInteractionsExceptAsBinder(mMockRunner);
+    }
+
+    @Test
+    public void testOneNotStarted() throws Exception {
+        final WindowState win1 = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin1");
+        final WindowState win2 = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin2");
+        mController.createAnimationAdapter(win1.mAppToken,
+                new Point(50, 100), new Rect(50, 100, 150, 150));
+        final AnimationAdapter adapter = mController.createAnimationAdapter(win2.mAppToken,
+                new Point(50, 100), new Rect(50, 100, 150, 150));
+        adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+        mController.goodToGo();
+        sWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+        final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
+                ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
+        final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor =
+                ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class);
+        verify(mMockRunner).onAnimationStart(appsCaptor.capture(), finishedCaptor.capture());
+        assertEquals(1, appsCaptor.getValue().length);
+        assertEquals(mMockLeash, appsCaptor.getValue()[0].leash);
+    }
+
+    @Test
+    public void testRemovedBeforeStarted() throws Exception {
+        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        final AnimationAdapter adapter = mController.createAnimationAdapter(win.mAppToken,
+                new Point(50, 100), new Rect(50, 100, 150, 150));
+        adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+        win.mAppToken.removeImmediately();
+        mController.goodToGo();
+        verifyNoMoreInteractionsExceptAsBinder(mMockRunner);
+        verify(mFinishedCallback).onAnimationFinished(eq(adapter));
+    }
+
+    private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) {
+        verify(binder, atLeast(0)).asBinder();
+        verifyNoMoreInteractions(binder);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java
new file mode 100644
index 0000000..204e26c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -0,0 +1,52 @@
+package com.android.server.wm;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for the {@link RootWindowContainer} class.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:com.android.server.wm.RootWindowContainerTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class RootWindowContainerTests extends WindowTestsBase {
+    @Test
+    public void testSetDisplayOverrideConfigurationIfNeeded() throws Exception {
+        synchronized (sWm.mWindowMap) {
+            // Add first stack we expect to be updated with configuration change.
+            final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
+            stack.getOverrideConfiguration().windowConfiguration.setBounds(new Rect(0, 0, 5, 5));
+
+            // Add second task that will be set for deferred removal that should not be returned
+            // with the configuration change.
+            final TaskStack deferredDeletedStack = createTaskStackOnDisplay(mDisplayContent);
+            deferredDeletedStack.getOverrideConfiguration().windowConfiguration.setBounds(
+                    new Rect(0, 0, 5, 5));
+            deferredDeletedStack.mDeferRemoval = true;
+
+            final Configuration override = new Configuration(
+                    mDisplayContent.getOverrideConfiguration());
+            override.windowConfiguration.setBounds(new Rect(0, 0, 10, 10));
+
+            // Set display override.
+            final int[] results = sWm.mRoot.setDisplayOverrideConfigurationIfNeeded(override,
+                    mDisplayContent.getDisplayId());
+
+            // Ensure only first stack is returned.
+            assertTrue(results.length == 1);
+            assertTrue(results[0] == stack.mStackId);
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java b/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java
new file mode 100644
index 0000000..a2ccee4
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.graphics.Color.RED;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Gravity.BOTTOM;
+import static android.view.Gravity.LEFT;
+import static android.view.Gravity.RIGHT;
+import static android.view.Gravity.TOP;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+import static org.junit.Assert.assertEquals;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.VirtualDisplay;
+import android.media.ImageReader;
+import android.os.Handler;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Pair;
+import android.view.Display;
+import android.view.DisplayInfo;
+import android.view.View;
+import android.view.WindowInsets;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.function.BooleanSupplier;
+
+/**
+ * Tests for the {@link android.view.WindowManager.LayoutParams#PRIVATE_FLAG_IS_SCREEN_DECOR} flag.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:com.android.server.wm.ScreenDecorWindowTests
+ */
+// TODO: Add test for FLAG_FULLSCREEN which hides the status bar and also other flags.
+// TODO: Test non-Activity windows.
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class ScreenDecorWindowTests {
+
+    private final Context mContext = InstrumentationRegistry.getTargetContext();
+    private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
+
+    private WindowManager mWm;
+    private ArrayList<View> mWindows = new ArrayList<>();
+
+    private Activity mTestActivity;
+    private VirtualDisplay mDisplay;
+    private ImageReader mImageReader;
+
+    private int mDecorThickness;
+    private int mHalfDecorThickness;
+
+    @Before
+    public void setUp() {
+        final Pair<VirtualDisplay, ImageReader> result = createDisplay();
+        mDisplay = result.first;
+        mImageReader = result.second;
+        final Display display = mDisplay.getDisplay();
+        final Context dContext = mContext.createDisplayContext(display);
+        mWm = dContext.getSystemService(WindowManager.class);
+        mTestActivity = startActivityOnDisplay(TestActivity.class, display.getDisplayId());
+        final Point size = new Point();
+        mDisplay.getDisplay().getRealSize(size);
+        mDecorThickness = Math.min(size.x, size.y) / 3;
+        mHalfDecorThickness = mDecorThickness / 2;
+    }
+
+    @After
+    public void tearDown() {
+        while (!mWindows.isEmpty()) {
+            removeWindow(mWindows.get(0));
+        }
+        finishActivity(mTestActivity);
+        mDisplay.release();
+        mImageReader.close();
+    }
+
+    @Test
+    public void testScreenSides() throws Exception {
+        // Decor on top
+        final View decorWindow = createDecorWindow(TOP, MATCH_PARENT, mDecorThickness);
+        assertInsetGreaterOrEqual(mTestActivity, TOP, mDecorThickness);
+
+        // Decor at the bottom
+        updateWindow(decorWindow, BOTTOM, MATCH_PARENT, mDecorThickness, 0, 0);
+        assertInsetGreaterOrEqual(mTestActivity, BOTTOM, mDecorThickness);
+
+        // Decor to the left
+        updateWindow(decorWindow, LEFT, mDecorThickness, MATCH_PARENT, 0, 0);
+        assertInsetGreaterOrEqual(mTestActivity, LEFT, mDecorThickness);
+
+        // Decor to the right
+        updateWindow(decorWindow, RIGHT, mDecorThickness, MATCH_PARENT, 0, 0);
+        assertInsetGreaterOrEqual(mTestActivity, RIGHT, mDecorThickness);
+    }
+
+    @Test
+    public void testMultipleDecors() throws Exception {
+        // Test 2 decor windows on-top.
+        createDecorWindow(TOP, MATCH_PARENT, mHalfDecorThickness);
+        assertInsetGreaterOrEqual(mTestActivity, TOP, mHalfDecorThickness);
+        createDecorWindow(TOP, MATCH_PARENT, mDecorThickness);
+        assertInsetGreaterOrEqual(mTestActivity, TOP, mDecorThickness);
+
+        // And one at the bottom.
+        createDecorWindow(BOTTOM, MATCH_PARENT, mHalfDecorThickness);
+        assertInsetGreaterOrEqual(mTestActivity, TOP, mDecorThickness);
+        assertInsetGreaterOrEqual(mTestActivity, BOTTOM, mHalfDecorThickness);
+    }
+
+    @Test
+    public void testFlagChange() throws Exception {
+        WindowInsets initialInsets = getInsets(mTestActivity);
+
+        final View decorWindow = createDecorWindow(TOP, MATCH_PARENT, mDecorThickness);
+        assertTopInsetEquals(mTestActivity, mDecorThickness);
+
+        updateWindow(decorWindow, TOP, MATCH_PARENT, mDecorThickness,
+                0, PRIVATE_FLAG_IS_SCREEN_DECOR);
+
+        // TODO: fix test and re-enable assertion.
+        // initialInsets was not actually immutable and just updated to the current insets,
+        // meaning this assertion never actually tested anything. Now that WindowInsets actually is
+        // immutable, it turns out the test was broken.
+        // assertTopInsetEquals(mTestActivity, initialInsets.getSystemWindowInsetTop());
+
+        updateWindow(decorWindow, TOP, MATCH_PARENT, mDecorThickness,
+                PRIVATE_FLAG_IS_SCREEN_DECOR, PRIVATE_FLAG_IS_SCREEN_DECOR);
+        assertTopInsetEquals(mTestActivity, mDecorThickness);
+    }
+
+    @Test
+    public void testRemoval() throws Exception {
+        WindowInsets initialInsets = getInsets(mTestActivity);
+
+        final View decorWindow = createDecorWindow(TOP, MATCH_PARENT, mDecorThickness);
+        assertInsetGreaterOrEqual(mTestActivity, TOP, mDecorThickness);
+
+        removeWindow(decorWindow);
+        assertTopInsetEquals(mTestActivity, initialInsets.getSystemWindowInsetTop());
+    }
+
+    private View createDecorWindow(int gravity, int width, int height) {
+        return createWindow("decorWindow", gravity, width, height, RED,
+                FLAG_LAYOUT_IN_SCREEN, PRIVATE_FLAG_IS_SCREEN_DECOR);
+    }
+
+    private View createWindow(String name, int gravity, int width, int height, int color, int flags,
+            int privateFlags) {
+
+        final View[] viewHolder = new View[1];
+        final int finalFlag = flags
+                | FLAG_NOT_FOCUSABLE | FLAG_WATCH_OUTSIDE_TOUCH | FLAG_NOT_TOUCHABLE;
+
+        // Needs to run on the UI thread.
+        Handler.getMain().runWithScissors(() -> {
+            final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                    width, height, TYPE_APPLICATION_OVERLAY, finalFlag, PixelFormat.OPAQUE);
+            lp.gravity = gravity;
+            lp.privateFlags |= privateFlags;
+
+            final TextView view = new TextView(mContext);
+            view.setText("ScreenDecorWindowTests - " + name);
+            view.setBackgroundColor(color);
+            mWm.addView(view, lp);
+            mWindows.add(view);
+            viewHolder[0] = view;
+        }, 0);
+
+        waitForIdle();
+        return viewHolder[0];
+    }
+
+    private void updateWindow(View v, int gravity, int width, int height,
+            int privateFlags, int privateFlagsMask) {
+        // Needs to run on the UI thread.
+        Handler.getMain().runWithScissors(() -> {
+            final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) v.getLayoutParams();
+            lp.gravity = gravity;
+            lp.width = width;
+            lp.height = height;
+            setPrivateFlags(lp, privateFlags, privateFlagsMask);
+
+            mWm.updateViewLayout(v, lp);
+        }, 0);
+
+        waitForIdle();
+    }
+
+    private void removeWindow(View v) {
+        Handler.getMain().runWithScissors(() -> mWm.removeView(v), 0);
+        mWindows.remove(v);
+        waitForIdle();
+    }
+
+    private WindowInsets getInsets(Activity a) {
+        return new WindowInsets(a.getWindow().getDecorView().getRootWindowInsets());
+    }
+
+    /**
+     * Set the flags of the window, as per the
+     * {@link WindowManager.LayoutParams WindowManager.LayoutParams}
+     * flags.
+     *
+     * @param flags The new window flags (see WindowManager.LayoutParams).
+     * @param mask Which of the window flag bits to modify.
+     */
+    public void setPrivateFlags(WindowManager.LayoutParams lp, int flags, int mask) {
+        lp.flags = (lp.flags & ~mask) | (flags & mask);
+    }
+
+    /**
+     * Asserts the top inset of {@param activity} is equal to {@param expected} waiting as needed.
+     */
+    private void assertTopInsetEquals(Activity activity, int expected) throws Exception {
+        waitFor(() -> getInsets(activity).getSystemWindowInsetTop() == expected);
+        assertEquals(expected, getInsets(activity).getSystemWindowInsetTop());
+    }
+
+    /**
+     * Asserts the inset at {@param side} of {@param activity} is equal to {@param expected}
+     * waiting as needed.
+     */
+    private void assertInsetGreaterOrEqual(Activity activity, int side, int expected)
+            throws Exception {
+        waitFor(() -> {
+            final WindowInsets insets = getInsets(activity);
+            switch (side) {
+                case TOP: return insets.getSystemWindowInsetTop() >= expected;
+                case BOTTOM: return insets.getSystemWindowInsetBottom() >= expected;
+                case LEFT: return insets.getSystemWindowInsetLeft() >= expected;
+                case RIGHT: return insets.getSystemWindowInsetRight() >= expected;
+                default: return true;
+            }
+        });
+
+        final WindowInsets insets = getInsets(activity);
+        switch (side) {
+            case TOP: assertGreaterOrEqual(insets.getSystemWindowInsetTop(), expected); break;
+            case BOTTOM: assertGreaterOrEqual(insets.getSystemWindowInsetBottom(), expected); break;
+            case LEFT: assertGreaterOrEqual(insets.getSystemWindowInsetLeft(), expected); break;
+            case RIGHT: assertGreaterOrEqual(insets.getSystemWindowInsetRight(), expected); break;
+        }
+    }
+
+    /** Asserts that the first entry is greater than or equal to the second entry. */
+    private void assertGreaterOrEqual(int first, int second) throws Exception {
+        Assert.assertTrue("Excepted " + first + " >= " + second, first >= second);
+    }
+
+    private void waitFor(BooleanSupplier waitCondition) {
+        int retriesLeft = 5;
+        do {
+            if (waitCondition.getAsBoolean()) {
+                break;
+            }
+            try {
+                Thread.sleep(500);
+            } catch (InterruptedException e) {
+                // Well I guess we are not waiting...
+            }
+        } while (retriesLeft-- > 0);
+    }
+
+    private void finishActivity(Activity a) {
+        if (a == null) {
+            return;
+        }
+        a.finish();
+        waitForIdle();
+    }
+
+    private void waitForIdle() {
+        mInstrumentation.waitForIdleSync();
+    }
+
+    private Activity startActivityOnDisplay(Class<?> cls, int displayId) {
+        final Intent intent = new Intent(mContext, cls);
+        intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(displayId);
+        final Activity activity = mInstrumentation.startActivitySync(intent, options.toBundle());
+        waitForIdle();
+
+        assertEquals(displayId, activity.getDisplay().getDisplayId());
+        return activity;
+    }
+
+    private Pair<VirtualDisplay, ImageReader> createDisplay() {
+        final DisplayManager dm = mContext.getSystemService(DisplayManager.class);
+        final DisplayInfo displayInfo = new DisplayInfo();
+        final Display defaultDisplay = dm.getDisplay(DEFAULT_DISPLAY);
+        defaultDisplay.getDisplayInfo(displayInfo);
+        final String name = "ScreenDecorWindowTests";
+        int flags = VIRTUAL_DISPLAY_FLAG_PRESENTATION | VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
+
+        final ImageReader imageReader = ImageReader.newInstance(
+                displayInfo.logicalWidth, displayInfo.logicalHeight, PixelFormat.RGBA_8888, 2);
+
+        final VirtualDisplay display = dm.createVirtualDisplay(name, displayInfo.logicalWidth,
+                displayInfo.logicalHeight, displayInfo.logicalDensityDpi, imageReader.getSurface(),
+                flags);
+
+        return Pair.create(display, imageReader);
+    }
+
+    public static class TestActivity extends Activity {
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/StackWindowControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/StackWindowControllerTests.java
new file mode 100644
index 0000000..ab0a2bd
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/StackWindowControllerTests.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import android.graphics.Rect;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test class for {@link StackWindowController}.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:StackWindowControllerTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class StackWindowControllerTests extends WindowTestsBase {
+    @Test
+    public void testRemoveContainer() throws Exception {
+        final StackWindowController stackController =
+                createStackControllerOnDisplay(mDisplayContent);
+        final WindowTestUtils.TestTaskWindowContainerController taskController =
+                new WindowTestUtils.TestTaskWindowContainerController(stackController);
+
+        final TaskStack stack = stackController.mContainer;
+        final Task task = taskController.mContainer;
+        assertNotNull(stack);
+        assertNotNull(task);
+        stackController.removeContainer();
+        // Assert that the container was removed.
+        assertNull(stackController.mContainer);
+        assertNull(taskController.mContainer);
+        assertNull(stack.getDisplayContent());
+        assertNull(task.getDisplayContent());
+        assertNull(task.mStack);
+    }
+
+    @Test
+    public void testRemoveContainer_deferRemoval() throws Exception {
+        final StackWindowController stackController =
+                createStackControllerOnDisplay(mDisplayContent);
+        final WindowTestUtils.TestTaskWindowContainerController taskController =
+                new WindowTestUtils.TestTaskWindowContainerController(stackController);
+
+        final TaskStack stack = stackController.mContainer;
+        final WindowTestUtils.TestTask task = (WindowTestUtils.TestTask) taskController.mContainer;
+        // Stack removal is deferred if one of its child is animating.
+        task.setLocalIsAnimating(true);
+
+        stackController.removeContainer();
+        // For the case of deferred removal the stack controller will no longer be connected to the
+        // container, but the task controller will still be connected to the its container until
+        // the stack window container is removed.
+        assertNull(stackController.mContainer);
+        assertNull(stack.getController());
+        assertNotNull(taskController.mContainer);
+        assertNotNull(task.getController());
+
+        stack.removeImmediately();
+        assertNull(taskController.mContainer);
+        assertNull(task.getController());
+    }
+
+    @Test
+    public void testReparent() throws Exception {
+        // Create first stack on primary display.
+        final StackWindowController stack1Controller =
+                createStackControllerOnDisplay(mDisplayContent);
+        final TaskStack stack1 = stack1Controller.mContainer;
+        final WindowTestUtils.TestTaskWindowContainerController taskController =
+                new WindowTestUtils.TestTaskWindowContainerController(stack1Controller);
+        final WindowTestUtils.TestTask task1 = (WindowTestUtils.TestTask) taskController.mContainer;
+        task1.mOnDisplayChangedCalled = false;
+
+        // Create second display and put second stack on it.
+        final DisplayContent dc = createNewDisplay();
+        final StackWindowController stack2Controller =
+                createStackControllerOnDisplay(dc);
+        final TaskStack stack2 = stack2Controller.mContainer;
+
+        // Reparent
+        stack1Controller.reparent(dc.getDisplayId(), new Rect(), true /* onTop */);
+        assertEquals(dc, stack1.getDisplayContent());
+        final int stack1PositionInParent = stack1.getParent().mChildren.indexOf(stack1);
+        final int stack2PositionInParent = stack1.getParent().mChildren.indexOf(stack2);
+        assertEquals(stack1PositionInParent, stack2PositionInParent + 1);
+        assertTrue(task1.mOnDisplayChangedCalled);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
new file mode 100644
index 0000000..edac8a5
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.animation.AnimationHandler;
+import android.animation.AnimationHandler.AnimationFrameCallbackProvider;
+import android.animation.ValueAnimator;
+import android.graphics.Matrix;
+import android.graphics.Point;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+import android.view.Choreographer;
+import android.view.Choreographer.FrameCallback;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
+import android.view.animation.Animation;
+import android.view.animation.TranslateAnimation;
+
+import com.android.server.wm.LocalAnimationAdapter.AnimationSpec;
+import com.android.server.wm.SurfaceAnimationRunner.AnimatorFactory;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Test class for {@link SurfaceAnimationRunner}.
+ *
+ * atest FrameworksServicesTests:com.android.server.wm.SurfaceAnimationRunnerTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class SurfaceAnimationRunnerTest extends WindowTestsBase {
+
+    @Mock SurfaceControl mMockSurface;
+    @Mock Transaction mMockTransaction;
+    @Mock AnimationSpec mMockAnimationSpec;
+    @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    private SurfaceAnimationRunner mSurfaceAnimationRunner;
+    private CountDownLatch mFinishCallbackLatch;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        mFinishCallbackLatch = new CountDownLatch(1);
+        mSurfaceAnimationRunner = new SurfaceAnimationRunner(null /* callbackProvider */, null,
+                mMockTransaction);
+    }
+
+    private void finishedCallback() {
+        mFinishCallbackLatch.countDown();
+    }
+
+    @Test
+    public void testAnimation() throws Exception {
+        mSurfaceAnimationRunner
+                .startAnimation(createTranslateAnimation(), mMockSurface, mMockTransaction,
+                this::finishedCallback);
+
+        // Ensure that the initial transformation has been applied.
+        final Matrix m = new Matrix();
+        m.setTranslate(-10, 0);
+        verify(mMockTransaction, atLeastOnce()).setMatrix(eq(mMockSurface), eq(m), any());
+        verify(mMockTransaction, atLeastOnce()).setAlpha(eq(mMockSurface), eq(1.0f));
+
+        mFinishCallbackLatch.await(1, SECONDS);
+        assertFinishCallbackCalled();
+
+        m.setTranslate(10, 0);
+        verify(mMockTransaction, atLeastOnce()).setMatrix(eq(mMockSurface), eq(m), any());
+
+        // At least 3 times: After initialization, first frame, last frame.
+        verify(mMockTransaction, atLeast(3)).setAlpha(eq(mMockSurface), eq(1.0f));
+    }
+
+    @Test
+    public void testCancel_notStarted() throws Exception {
+        mSurfaceAnimationRunner = new SurfaceAnimationRunner(new NoOpFrameCallbackProvider(), null,
+                mMockTransaction);
+        mSurfaceAnimationRunner
+                .startAnimation(createTranslateAnimation(), mMockSurface, mMockTransaction,
+                this::finishedCallback);
+        mSurfaceAnimationRunner.onAnimationCancelled(mMockSurface);
+        waitUntilHandlersIdle();
+        assertTrue(mSurfaceAnimationRunner.mPendingAnimations.isEmpty());
+        assertFinishCallbackNotCalled();
+    }
+
+    @Test
+    public void testCancel_running() throws Exception {
+        mSurfaceAnimationRunner = new SurfaceAnimationRunner(new NoOpFrameCallbackProvider(), null,
+                mMockTransaction);
+        mSurfaceAnimationRunner.startAnimation(createTranslateAnimation(), mMockSurface,
+                mMockTransaction, this::finishedCallback);
+        waitUntilNextFrame();
+        assertFalse(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
+        mSurfaceAnimationRunner.onAnimationCancelled(mMockSurface);
+        assertTrue(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
+        waitUntilHandlersIdle();
+        assertFinishCallbackNotCalled();
+    }
+
+    @FlakyTest(bugId = 71719744)
+    @Test
+    public void testCancel_sneakyCancelBeforeUpdate() throws Exception {
+        mSurfaceAnimationRunner = new SurfaceAnimationRunner(null, () -> new ValueAnimator() {
+            {
+                setFloatValues(0f, 1f);
+            }
+
+            @Override
+            public void addUpdateListener(AnimatorUpdateListener listener) {
+                super.addUpdateListener(animation -> {
+                    // Sneaky test cancels animation just before applying frame to simulate
+                    // interleaving of multiple threads. Muahahaha
+                    if (animation.getCurrentPlayTime() > 0) {
+                        mSurfaceAnimationRunner.onAnimationCancelled(mMockSurface);
+                    }
+                    listener.onAnimationUpdate(animation);
+                });
+            }
+        }, mMockTransaction);
+        when(mMockAnimationSpec.getDuration()).thenReturn(200L);
+        mSurfaceAnimationRunner.startAnimation(mMockAnimationSpec, mMockSurface, mMockTransaction,
+                this::finishedCallback);
+
+        // We need to wait for two frames: The first frame starts the animation, the second frame
+        // actually cancels the animation.
+        waitUntilNextFrame();
+        waitUntilNextFrame();
+        assertTrue(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
+        verify(mMockAnimationSpec, atLeastOnce()).apply(any(), any(), eq(0L));
+    }
+
+    @FlakyTest(bugId = 74780584)
+    @Test
+    public void testDeferStartingAnimations() throws Exception {
+        mSurfaceAnimationRunner.deferStartingAnimations();
+        mSurfaceAnimationRunner.startAnimation(createTranslateAnimation(), mMockSurface,
+                mMockTransaction, this::finishedCallback);
+        waitUntilNextFrame();
+        assertTrue(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
+        mSurfaceAnimationRunner.continueStartingAnimations();
+        waitUntilNextFrame();
+        assertFalse(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
+        mFinishCallbackLatch.await(1, SECONDS);
+        assertFinishCallbackCalled();
+    }
+
+    private void waitUntilNextFrame() throws Exception {
+        final CountDownLatch latch = new CountDownLatch(1);
+        mSurfaceAnimationRunner.mChoreographer.postCallback(Choreographer.CALLBACK_COMMIT,
+                latch::countDown, null /* token */);
+        latch.await();
+    }
+
+    private void assertFinishCallbackCalled() {
+        assertEquals(0, mFinishCallbackLatch.getCount());
+    }
+
+    private void assertFinishCallbackNotCalled() {
+        assertEquals(1, mFinishCallbackLatch.getCount());
+    }
+
+    private AnimationSpec createTranslateAnimation() {
+        final Animation a = new TranslateAnimation(-10, 10, 0, 0);
+        a.initialize(0, 0, 0, 0);
+        a.setDuration(50);
+        return new WindowAnimationSpec(a, new Point(0, 0), false /* canSkipFirstFrame */);
+    }
+
+    /**
+     * Callback provider that doesn't animate at all.
+     */
+    private static final class NoOpFrameCallbackProvider implements AnimationFrameCallbackProvider {
+
+        @Override
+        public void postFrameCallback(FrameCallback callback) {
+        }
+
+        @Override
+        public void postCommitCallback(Runnable runnable) {
+        }
+
+        @Override
+        public long getFrameTime() {
+            return 0;
+        }
+
+        @Override
+        public long getFrameDelay() {
+            return 0;
+        }
+
+        @Override
+        public void setFrameDelay(long delay) {
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java
new file mode 100644
index 0000000..16b8458
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.Builder;
+import android.view.SurfaceControl.Transaction;
+import android.view.SurfaceSession;
+
+import com.android.server.wm.SurfaceAnimator.Animatable;
+import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+
+/**
+ * Test class for {@link SurfaceAnimatorTest}.
+ *
+ * atest FrameworksServicesTests:com.android.server.wm.SurfaceAnimatorTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class SurfaceAnimatorTest extends WindowTestsBase {
+
+    @Mock AnimationAdapter mSpec;
+    @Mock AnimationAdapter mSpec2;
+    @Mock Transaction mTransaction;
+
+    private SurfaceSession mSession = new SurfaceSession();
+    private MyAnimatable mAnimatable;
+    private MyAnimatable mAnimatable2;
+    private DeferFinishAnimatable mDeferFinishAnimatable;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        MockitoAnnotations.initMocks(this);
+        mAnimatable = new MyAnimatable();
+        mAnimatable2 = new MyAnimatable();
+        mDeferFinishAnimatable = new DeferFinishAnimatable();
+    }
+
+    @Test
+    public void testRunAnimation() throws Exception {
+        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
+                OnAnimationFinishedCallback.class);
+        assertAnimating(mAnimatable);
+        verify(mTransaction).reparent(eq(mAnimatable.mSurface), eq(mAnimatable.mLeash.getHandle()));
+        verify(mSpec).startAnimation(any(), any(), callbackCaptor.capture());
+
+        callbackCaptor.getValue().onAnimationFinished(mSpec);
+        assertNotAnimating(mAnimatable);
+        assertTrue(mAnimatable.mFinishedCallbackCalled);
+        verify(mTransaction).destroy(eq(mAnimatable.mLeash));
+        // TODO: Verify reparenting once we use mPendingTransaction to reparent it back
+    }
+
+    @Test
+    public void testOverrideAnimation() throws Exception {
+        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        final SurfaceControl firstLeash = mAnimatable.mLeash;
+        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec2, true /* hidden */);
+
+        verify(mTransaction).destroy(eq(firstLeash));
+        assertFalse(mAnimatable.mFinishedCallbackCalled);
+
+        final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
+                OnAnimationFinishedCallback.class);
+        assertAnimating(mAnimatable);
+        verify(mSpec).startAnimation(any(), any(), callbackCaptor.capture());
+
+        // First animation was finished, but this shouldn't cancel the second animation
+        callbackCaptor.getValue().onAnimationFinished(mSpec);
+        assertTrue(mAnimatable.mSurfaceAnimator.isAnimating());
+
+        // Second animation was finished
+        verify(mSpec2).startAnimation(any(), any(), callbackCaptor.capture());
+        callbackCaptor.getValue().onAnimationFinished(mSpec2);
+        assertNotAnimating(mAnimatable);
+        assertTrue(mAnimatable.mFinishedCallbackCalled);
+    }
+
+    @Test
+    public void testCancelAnimation() throws Exception {
+        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        assertAnimating(mAnimatable);
+        mAnimatable.mSurfaceAnimator.cancelAnimation();
+        assertNotAnimating(mAnimatable);
+        verify(mSpec).onAnimationCancelled(any());
+        assertTrue(mAnimatable.mFinishedCallbackCalled);
+        verify(mTransaction).destroy(eq(mAnimatable.mLeash));
+    }
+
+    @Test
+    public void testDelayingAnimationStart() throws Exception {
+        mAnimatable.mSurfaceAnimator.startDelayingAnimationStart();
+        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        verifyZeroInteractions(mSpec);
+        assertAnimating(mAnimatable);
+        assertTrue(mAnimatable.mSurfaceAnimator.isAnimationStartDelayed());
+        mAnimatable.mSurfaceAnimator.endDelayingAnimationStart();
+        verify(mSpec).startAnimation(any(), any(), any());
+    }
+
+    @Test
+    public void testDelayingAnimationStartAndCancelled() throws Exception {
+        mAnimatable.mSurfaceAnimator.startDelayingAnimationStart();
+        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+        mAnimatable.mSurfaceAnimator.cancelAnimation();
+        verifyZeroInteractions(mSpec);
+        assertNotAnimating(mAnimatable);
+        assertTrue(mAnimatable.mFinishedCallbackCalled);
+        verify(mTransaction).destroy(eq(mAnimatable.mLeash));
+    }
+
+    @Test
+    public void testTransferAnimation() throws Exception {
+        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+
+        final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
+                OnAnimationFinishedCallback.class);
+        verify(mSpec).startAnimation(any(), any(), callbackCaptor.capture());
+        final SurfaceControl leash = mAnimatable.mLeash;
+
+        mAnimatable2.mSurfaceAnimator.transferAnimation(mAnimatable.mSurfaceAnimator);
+        assertNotAnimating(mAnimatable);
+        assertAnimating(mAnimatable2);
+        assertEquals(leash, mAnimatable2.mSurfaceAnimator.mLeash);
+        verify(mTransaction, never()).destroy(eq(leash));
+        callbackCaptor.getValue().onAnimationFinished(mSpec);
+        assertNotAnimating(mAnimatable2);
+        assertTrue(mAnimatable2.mFinishedCallbackCalled);
+        verify(mTransaction).destroy(eq(leash));
+    }
+
+    @Test
+    @FlakyTest(detail = "Promote once confirmed non-flaky")
+    public void testDeferFinish() throws Exception {
+
+        // Start animation
+        mDeferFinishAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec,
+                true /* hidden */);
+        final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
+                OnAnimationFinishedCallback.class);
+        assertAnimating(mDeferFinishAnimatable);
+        verify(mSpec).startAnimation(any(), any(), callbackCaptor.capture());
+
+        // Finish the animation but then make sure we are deferring.
+        callbackCaptor.getValue().onAnimationFinished(mSpec);
+        assertAnimating(mDeferFinishAnimatable);
+
+        // Now end defer finishing.
+        mDeferFinishAnimatable.endDeferFinishCallback.run();
+        assertNotAnimating(mAnimatable2);
+        assertTrue(mDeferFinishAnimatable.mFinishedCallbackCalled);
+        verify(mTransaction).destroy(eq(mDeferFinishAnimatable.mLeash));
+    }
+
+    private void assertAnimating(MyAnimatable animatable) {
+        assertTrue(animatable.mSurfaceAnimator.isAnimating());
+        assertNotNull(animatable.mSurfaceAnimator.getAnimation());
+    }
+
+    private void assertNotAnimating(MyAnimatable animatable) {
+        assertFalse(animatable.mSurfaceAnimator.isAnimating());
+        assertNull(animatable.mSurfaceAnimator.getAnimation());
+    }
+
+    private class MyAnimatable implements Animatable {
+
+        final SurfaceControl mParent;
+        final SurfaceControl mSurface;
+        final SurfaceAnimator mSurfaceAnimator;
+        SurfaceControl mLeash;
+        boolean mFinishedCallbackCalled;
+
+        MyAnimatable() {
+            mParent = sWm.makeSurfaceBuilder(mSession)
+                    .setName("test surface parent")
+                    .setSize(3000, 3000)
+                    .build();
+            mSurface = sWm.makeSurfaceBuilder(mSession)
+                    .setName("test surface")
+                    .setSize(1, 1)
+                    .build();
+            mFinishedCallbackCalled = false;
+            mLeash = null;
+            mSurfaceAnimator = new SurfaceAnimator(this, mFinishedCallback, sWm);
+        }
+
+        @Override
+        public Transaction getPendingTransaction() {
+            return mTransaction;
+        }
+
+        @Override
+        public void commitPendingTransaction() {
+        }
+
+        @Override
+        public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
+        }
+
+        @Override
+        public void onAnimationLeashDestroyed(Transaction t) {
+        }
+
+        @Override
+        public Builder makeAnimationLeash() {
+            return new SurfaceControl.Builder(mSession) {
+
+                @Override
+                public SurfaceControl build() {
+                    mLeash = super.build();
+                    return mLeash;
+                }
+            }.setParent(mParent);
+        }
+
+        @Override
+        public SurfaceControl getAnimationLeashParent() {
+            return mParent;
+        }
+
+        @Override
+        public SurfaceControl getSurfaceControl() {
+            return mSurface;
+        }
+
+        @Override
+        public SurfaceControl getParentSurfaceControl() {
+            return mParent;
+        }
+
+        @Override
+        public int getSurfaceWidth() {
+            return 1;
+        }
+
+        @Override
+        public int getSurfaceHeight() {
+            return 1;
+        }
+
+        private final Runnable mFinishedCallback = () -> mFinishedCallbackCalled = true;
+    }
+
+    private class DeferFinishAnimatable extends MyAnimatable {
+
+        Runnable endDeferFinishCallback;
+
+        @Override
+        public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
+            this.endDeferFinishCallback = endDeferFinishCallback;
+            return true;
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java
new file mode 100644
index 0000000..7bf7dd7
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java
@@ -0,0 +1,480 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.graphics.Rect;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Display;
+
+import static com.android.server.wm.TaskPositioner.MIN_ASPECT;
+import static com.android.server.wm.WindowManagerService.dipToPixel;
+import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP;
+import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for the {@link TaskPositioner} class.
+ *
+ * runtest frameworks-services -c com.android.server.wm.TaskPositionerTests
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TaskPositionerTests extends WindowTestsBase {
+
+    private final boolean DEBUGGING = false;
+    private final String TAG = "TaskPositionerTest";
+
+    private final static int MOUSE_DELTA_X = 5;
+    private final static int MOUSE_DELTA_Y = 5;
+
+    private int mMinVisibleWidth;
+    private int mMinVisibleHeight;
+    private TaskPositioner mPositioner;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        TaskPositioner.setFactory(null);
+
+        final Display display = mDisplayContent.getDisplay();
+        final DisplayMetrics dm = new DisplayMetrics();
+        display.getMetrics(dm);
+
+        // This should be the same calculation as the TaskPositioner uses.
+        mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, dm);
+        mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, dm);
+
+        mPositioner = TaskPositioner.create(sWm);
+        mPositioner.register(mDisplayContent);
+    }
+
+    @Test
+    public void testOverrideFactory() throws Exception {
+        final boolean[] created = new boolean[1];
+        created[0] = false;
+        TaskPositioner.setFactory(new TaskPositioner.Factory() {
+            @Override
+            public TaskPositioner create(WindowManagerService service) {
+                created[0] = true;
+                return null;
+            }
+        });
+
+        assertNull(TaskPositioner.create(sWm));
+        assertTrue(created[0]);
+    }
+
+    /**
+     * This tests that free resizing will allow to change the orientation as well
+     * as does some basic tests (e.g. dragging in Y only will keep X stable).
+     */
+    @Test
+    @Ignore
+    public void testBasicFreeWindowResizing() throws Exception {
+        final Rect r = new Rect(100, 220, 700, 520);
+        final int midY = (r.top + r.bottom) / 2;
+
+        // Start a drag resize starting upper left.
+        mPositioner.startDrag(true /*resizing*/,
+                false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y, r);
+        assertBoundsEquals(r, mPositioner.getWindowDragBounds());
+
+        // Drag to a good landscape size.
+        mPositioner.resizeDrag(0.0f, 0.0f);
+        assertBoundsEquals(new Rect(MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to a good portrait size.
+        mPositioner.resizeDrag(400.0f, 0.0f);
+        assertBoundsEquals(new Rect(400 + MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to a too small size for the width.
+        mPositioner.resizeDrag(2000.0f, r.top);
+        assertBoundsEquals(
+                new Rect(r.right - mMinVisibleWidth, r.top + MOUSE_DELTA_Y, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to a too small size for the height.
+        mPositioner.resizeDrag(r.left, 2000.0f);
+        assertBoundsEquals(
+                new Rect(r.left + MOUSE_DELTA_X, r.bottom - mMinVisibleHeight, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Start a drag resize left and see that only the left coord changes..
+        mPositioner.startDrag(true /*resizing*/,
+                false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, midY, r);
+
+        // Drag to the left.
+        mPositioner.resizeDrag(0.0f, midY);
+        assertBoundsEquals(new Rect(MOUSE_DELTA_X, r.top, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to the right.
+        mPositioner.resizeDrag(200.0f, midY);
+        assertBoundsEquals(new Rect(200 + MOUSE_DELTA_X, r.top, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to the top
+        mPositioner.resizeDrag(r.left, 0.0f);
+        assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to the bottom
+        mPositioner.resizeDrag(r.left, 1000.0f);
+        assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+    }
+
+    /**
+     * This tests that by dragging any edge, the fixed / opposite edge(s) remains anchored.
+     */
+    @Test
+    @Ignore
+    public void testFreeWindowResizingTestAllEdges() throws Exception {
+        final Rect r = new Rect(100, 220, 700, 520);
+        final int midX = (r.left + r.right) / 2;
+        final int midY = (r.top + r.bottom) / 2;
+
+        // Drag upper left.
+        mPositioner.startDrag(true /*resizing*/,
+                false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y, r);
+        mPositioner.resizeDrag(0.0f, 0.0f);
+        assertTrue(r.left != mPositioner.getWindowDragBounds().left);
+        assertEquals(r.right, mPositioner.getWindowDragBounds().right);
+        assertTrue(r.top != mPositioner.getWindowDragBounds().top);
+        assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
+
+        // Drag upper.
+        mPositioner.startDrag(true /*resizing*/,
+                false /*preserveOrientation*/, midX, r.top - MOUSE_DELTA_Y, r);
+        mPositioner.resizeDrag(0.0f, 0.0f);
+        assertEquals(r.left, mPositioner.getWindowDragBounds().left);
+        assertEquals(r.right, mPositioner.getWindowDragBounds().right);
+        assertTrue(r.top != mPositioner.getWindowDragBounds().top);
+        assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
+
+        // Drag upper right.
+        mPositioner.startDrag(true /*resizing*/,
+                false /*preserveOrientation*/, r.right + MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y, r);
+        mPositioner.resizeDrag(r.right + 100, 0.0f);
+        assertEquals(r.left, mPositioner.getWindowDragBounds().left);
+        assertTrue(r.right != mPositioner.getWindowDragBounds().right);
+        assertTrue(r.top != mPositioner.getWindowDragBounds().top);
+        assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
+
+        // Drag right.
+        mPositioner.startDrag(true /*resizing*/,
+                false /*preserveOrientation*/, r.right + MOUSE_DELTA_X, midY, r);
+        mPositioner.resizeDrag(r.right + 100, 0.0f);
+        assertEquals(r.left, mPositioner.getWindowDragBounds().left);
+        assertTrue(r.right != mPositioner.getWindowDragBounds().right);
+        assertEquals(r.top, mPositioner.getWindowDragBounds().top);
+        assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
+
+        // Drag bottom right.
+        mPositioner.startDrag(true /*resizing*/,
+                false /*preserveOrientation*/,
+                r.right + MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y, r);
+        mPositioner.resizeDrag(r.right + 100, r.bottom + 100);
+        assertEquals(r.left, mPositioner.getWindowDragBounds().left);
+        assertTrue(r.right != mPositioner.getWindowDragBounds().right);
+        assertEquals(r.top, mPositioner.getWindowDragBounds().top);
+        assertTrue(r.bottom != mPositioner.getWindowDragBounds().bottom);
+
+        // Drag bottom.
+        mPositioner.startDrag(true /*resizing*/,
+                false /*preserveOrientation*/, midX, r.bottom + MOUSE_DELTA_Y, r);
+        mPositioner.resizeDrag(r.right + 100, r.bottom + 100);
+        assertEquals(r.left, mPositioner.getWindowDragBounds().left);
+        assertEquals(r.right, mPositioner.getWindowDragBounds().right);
+        assertEquals(r.top, mPositioner.getWindowDragBounds().top);
+        assertTrue(r.bottom != mPositioner.getWindowDragBounds().bottom);
+
+        // Drag bottom left.
+        mPositioner.startDrag(true /*resizing*/,
+                false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y, r);
+        mPositioner.resizeDrag(0.0f, r.bottom + 100);
+        assertTrue(r.left != mPositioner.getWindowDragBounds().left);
+        assertEquals(r.right, mPositioner.getWindowDragBounds().right);
+        assertEquals(r.top, mPositioner.getWindowDragBounds().top);
+        assertTrue(r.bottom != mPositioner.getWindowDragBounds().bottom);
+
+        // Drag left.
+        mPositioner.startDrag(true /*resizing*/,
+                false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, midX, r);
+        mPositioner.resizeDrag(0.0f, r.bottom + 100);
+        assertTrue(r.left != mPositioner.getWindowDragBounds().left);
+        assertEquals(r.right, mPositioner.getWindowDragBounds().right);
+        assertEquals(r.top, mPositioner.getWindowDragBounds().top);
+        assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
+    }
+
+    /**
+     * This tests that a constrained landscape window will keep the aspect and do the
+     * right things upon resizing when dragged from the top left corner.
+     */
+    @Test
+    @Ignore
+    public void testLandscapePreservedWindowResizingDragTopLeft() throws Exception {
+        final Rect r = new Rect(100, 220, 700, 520);
+
+        mPositioner.startDrag(true /*resizing*/,
+                true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y, r);
+        assertBoundsEquals(r, mPositioner.getWindowDragBounds());
+
+        // Drag to a good landscape size.
+        mPositioner.resizeDrag(0.0f, 0.0f);
+        assertBoundsEquals(new Rect(MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to a good portrait size.
+        mPositioner.resizeDrag(400.0f, 0.0f);
+        int width = Math.round((float) (r.bottom - MOUSE_DELTA_Y) * MIN_ASPECT);
+        assertBoundsEquals(new Rect(r.right - width, MOUSE_DELTA_Y, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to a too small size for the width.
+        mPositioner.resizeDrag(2000.0f, r.top);
+        final int w = mMinVisibleWidth;
+        final int h = Math.round(w / MIN_ASPECT);
+        assertBoundsEquals(new Rect(r.right - w, r.bottom - h, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to a too small size for the height.
+        mPositioner.resizeDrag(r.left, 2000.0f);
+        assertBoundsEquals(
+                new Rect(r.left + MOUSE_DELTA_X, r.bottom - mMinVisibleHeight, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+    }
+
+    /**
+     * This tests that a constrained landscape window will keep the aspect and do the
+     * right things upon resizing when dragged from the left corner.
+     */
+    @Test
+    @Ignore
+    public void testLandscapePreservedWindowResizingDragLeft() throws Exception {
+        final Rect r = new Rect(100, 220, 700, 520);
+        final int midY = (r.top + r.bottom) / 2;
+
+        mPositioner.startDrag(true /*resizing*/,
+                true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, midY, r);
+
+        // Drag to the left.
+        mPositioner.resizeDrag(0.0f, midY);
+        assertBoundsEquals(new Rect(MOUSE_DELTA_X, r.top, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to the right.
+        mPositioner.resizeDrag(200.0f, midY);
+        assertBoundsEquals(new Rect(200 + MOUSE_DELTA_X, r.top, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag all the way to the right and see the height also shrinking.
+        mPositioner.resizeDrag(2000.0f, midY);
+        final int w = mMinVisibleWidth;
+        final int h = Math.round((float)w / MIN_ASPECT);
+        assertBoundsEquals(new Rect(r.right - w, r.top, r.right, r.top + h),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to the top.
+        mPositioner.resizeDrag(r.left, 0.0f);
+        assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to the bottom.
+        mPositioner.resizeDrag(r.left, 1000.0f);
+        assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+    }
+
+    /**
+     * This tests that a constrained landscape window will keep the aspect and do the
+     * right things upon resizing when dragged from the top corner.
+     */
+    @Test
+    @Ignore
+    public void testLandscapePreservedWindowResizingDragTop() throws Exception {
+        final Rect r = new Rect(100, 220, 700, 520);
+        final int midX = (r.left + r.right) / 2;
+
+        mPositioner.startDrag(true /*resizing*/,
+                true /*preserveOrientation*/, midX, r.top - MOUSE_DELTA_Y, r);
+
+        // Drag to the left (no change).
+        mPositioner.resizeDrag(0.0f, r.top);
+        assertBoundsEquals(new Rect(r.left, r.top + MOUSE_DELTA_Y, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to the right (no change).
+        mPositioner.resizeDrag(2000.0f, r.top);
+        assertBoundsEquals(new Rect(r.left , r.top + MOUSE_DELTA_Y, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to the top.
+        mPositioner.resizeDrag(300.0f, 0.0f);
+        int h = r.bottom - MOUSE_DELTA_Y;
+        int w = Math.max(r.right - r.left, Math.round(h * MIN_ASPECT));
+        assertBoundsEquals(new Rect(r.left, MOUSE_DELTA_Y, r.left + w, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to the bottom.
+        mPositioner.resizeDrag(r.left, 1000.0f);
+        h = mMinVisibleHeight;
+        assertBoundsEquals(new Rect(r.left, r.bottom - h, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+    }
+
+    /**
+     * This tests that a constrained portrait window will keep the aspect and do the
+     * right things upon resizing when dragged from the top left corner.
+     */
+    @Test
+    @Ignore
+    public void testPortraitPreservedWindowResizingDragTopLeft() throws Exception {
+        final Rect r = new Rect(330, 100, 630, 600);
+
+        mPositioner.startDrag(true /*resizing*/,
+                true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y, r);
+        assertBoundsEquals(r, mPositioner.getWindowDragBounds());
+
+        // Drag to a good landscape size.
+        mPositioner.resizeDrag(0.0f, 0.0f);
+        int height = Math.round((float) (r.right - MOUSE_DELTA_X) * MIN_ASPECT);
+        assertBoundsEquals(new Rect(MOUSE_DELTA_X, r.bottom - height, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to a good portrait size.
+        mPositioner.resizeDrag(500.0f, 0.0f);
+        assertBoundsEquals(new Rect(500 + MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to a too small size for the height and the the width shrinking.
+        mPositioner.resizeDrag(r.left + MOUSE_DELTA_X, 2000.0f);
+        final int w = Math.max(mMinVisibleWidth, Math.round(mMinVisibleHeight / MIN_ASPECT));
+        final int h = Math.max(mMinVisibleHeight, Math.round(w * MIN_ASPECT));
+        assertBoundsEquals(
+                new Rect(r.right - w, r.bottom - h, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+    }
+
+    /**
+     * This tests that a constrained portrait window will keep the aspect and do the
+     * right things upon resizing when dragged from the left corner.
+     */
+    @Test
+    @Ignore
+    public void testPortraitPreservedWindowResizingDragLeft() throws Exception {
+        final Rect r = new Rect(330, 100, 630, 600);
+        final int midY = (r.top + r.bottom) / 2;
+
+        mPositioner.startDrag(true /*resizing*/,
+                true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, midY, r);
+
+        // Drag to the left.
+        mPositioner.resizeDrag(0.0f, midY);
+        int w = r.right - MOUSE_DELTA_X;
+        int h = Math.round(w * MIN_ASPECT);
+        assertBoundsEquals(new Rect(MOUSE_DELTA_X, r.top, r.right, r.top + h),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to the right.
+        mPositioner.resizeDrag(450.0f, midY);
+        assertBoundsEquals(new Rect(450 + MOUSE_DELTA_X, r.top, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag all the way to the right.
+        mPositioner.resizeDrag(2000.0f, midY);
+        w = mMinVisibleWidth;
+        h = Math.max(Math.round((float)w * MIN_ASPECT), r.height());
+        assertBoundsEquals(new Rect(r.right - w, r.top, r.right, r.top + h),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to the top.
+        mPositioner.resizeDrag(r.left, 0.0f);
+        assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to the bottom.
+        mPositioner.resizeDrag(r.left, 1000.0f);
+        assertBoundsEquals(new Rect(r.left + MOUSE_DELTA_X, r.top, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+    }
+
+    /**
+     * This tests that a constrained portrait window will keep the aspect and do the
+     * right things upon resizing when dragged from the top corner.
+     */
+    @Test
+    @Ignore
+    public void testPortraitPreservedWindowResizingDragTop() throws Exception {
+        final Rect r = new Rect(330, 100, 630, 600);
+        final int midX = (r.left + r.right) / 2;
+
+        mPositioner.startDrag(true /*resizing*/,
+                true /*preserveOrientation*/, midX, r.top - MOUSE_DELTA_Y, r);
+
+        // Drag to the left (no change).
+        mPositioner.resizeDrag(0.0f, r.top);
+        assertBoundsEquals(new Rect(r.left, r.top + MOUSE_DELTA_Y, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to the right (no change).
+        mPositioner.resizeDrag(2000.0f, r.top);
+        assertBoundsEquals(new Rect(r.left , r.top + MOUSE_DELTA_Y, r.right, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to the top.
+        mPositioner.resizeDrag(300.0f, 0.0f);
+        int h = r.bottom - MOUSE_DELTA_Y;
+        int w = Math.min(r.width(), Math.round(h / MIN_ASPECT));
+        assertBoundsEquals(new Rect(r.left, MOUSE_DELTA_Y, r.left + w, r.bottom),
+                mPositioner.getWindowDragBounds());
+
+        // Drag to the bottom.
+        mPositioner.resizeDrag(r.left, 1000.0f);
+        h = Math.max(mMinVisibleHeight, Math.round(mMinVisibleWidth * MIN_ASPECT));
+        w = Math.round(h / MIN_ASPECT);
+        assertBoundsEquals(new Rect(r.left, r.bottom - h, r.left + w, r.bottom),
+                mPositioner.getWindowDragBounds());
+    }
+
+    private void assertBoundsEquals(Rect expected, Rect actual) {
+        if (DEBUGGING) {
+            if (!expected.equals(actual)) {
+                Log.e(TAG, "rect(" + actual.toString() + ") != isRect(" + actual.toString()
+                        + ") " + Log.getStackTraceString(new Throwable()));
+            }
+        }
+        assertEquals(expected.left, actual.left);
+        assertEquals(expected.right, actual.right);
+        assertEquals(expected.top, actual.top);
+        assertEquals(expected.bottom, actual.bottom);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java
new file mode 100644
index 0000000..6070516
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static org.junit.Assert.assertFalse;
+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 static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.InputChannel;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for the {@link TaskPositioningController} class.
+ *
+ * atest com.android.server.wm.TaskPositioningControllerTests
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+@Presubmit
+public class TaskPositioningControllerTests extends WindowTestsBase {
+    private static final int TIMEOUT_MS = 1000;
+    private TaskPositioningController mTarget;
+    private WindowState mWindow;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        assertNotNull(sWm.mTaskPositioningController);
+        mTarget = sWm.mTaskPositioningController;
+
+        when(sWm.mInputManager.transferTouchFocus(
+                any(InputChannel.class),
+                any(InputChannel.class))).thenReturn(true);
+
+        mWindow = createWindow(null, TYPE_BASE_APPLICATION, "window");
+        mWindow.mInputChannel = new InputChannel();
+        synchronized (sWm.mWindowMap) {
+            sWm.mWindowMap.put(mWindow.mClient.asBinder(), mWindow);
+        }
+    }
+
+    @Test
+    public void testStartAndFinishPositioning() throws Exception {
+        synchronized (sWm.mWindowMap) {
+            assertFalse(mTarget.isPositioningLocked());
+            assertNull(mTarget.getDragWindowHandleLocked());
+        }
+
+        assertTrue(mTarget.startMovingTask(mWindow.mClient, 0, 0));
+
+        synchronized (sWm.mWindowMap) {
+            assertTrue(mTarget.isPositioningLocked());
+            assertNotNull(mTarget.getDragWindowHandleLocked());
+        }
+
+        mTarget.finishTaskPositioning();
+        // Wait until the looper processes finishTaskPositioning.
+        assertTrue(sWm.mH.runWithScissors(() -> {}, TIMEOUT_MS));
+
+        assertFalse(mTarget.isPositioningLocked());
+        assertNull(mTarget.getDragWindowHandleLocked());
+    }
+
+    @Test
+    public void testHandleTapOutsideTask() throws Exception {
+        synchronized (sWm.mWindowMap) {
+
+            assertFalse(mTarget.isPositioningLocked());
+            assertNull(mTarget.getDragWindowHandleLocked());
+        }
+
+        final DisplayContent content = mock(DisplayContent.class);
+        when(content.findTaskForResizePoint(anyInt(), anyInt())).thenReturn(mWindow.getTask());
+        assertNotNull(mWindow.getTask().getTopVisibleAppMainWindow());
+
+        mTarget.handleTapOutsideTask(content, 0, 0);
+        // Wait until the looper processes finishTaskPositioning.
+        assertTrue(sWm.mH.runWithScissors(() -> {}, TIMEOUT_MS));
+
+        synchronized (sWm.mWindowMap) {
+            assertTrue(mTarget.isPositioningLocked());
+            assertNotNull(mTarget.getDragWindowHandleLocked());
+        }
+
+        mTarget.finishTaskPositioning();
+        // Wait until the looper processes finishTaskPositioning.
+        assertTrue(sWm.mH.runWithScissors(() -> {}, TIMEOUT_MS));
+
+        assertFalse(mTarget.isPositioningLocked());
+        assertNull(mTarget.getDragWindowHandleLocked());
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java
new file mode 100644
index 0000000..649de4a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for {@link TaskSnapshotCache}.
+ *
+ * runtest frameworks-services -c com.android.server.wm.TaskSnapshotCacheTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class TaskSnapshotCacheTest extends TaskSnapshotPersisterTestBase {
+
+    private TaskSnapshotCache mCache;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        mCache = new TaskSnapshotCache(sWm, mLoader);
+    }
+
+    @Test
+    public void testAppRemoved() throws Exception {
+        final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window");
+        mCache.putSnapshot(window.getTask(), createSnapshot());
+        assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */,
+                false /* restoreFromDisk */, false /* reducedResolution */));
+        mCache.onAppRemoved(window.mAppToken);
+        assertNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */,
+                false /* restoreFromDisk */, false /* reducedResolution */));
+    }
+
+    @Test
+    public void testAppDied() throws Exception {
+        final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window");
+        mCache.putSnapshot(window.getTask(), createSnapshot());
+        assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */,
+                false /* restoreFromDisk */, false /* reducedResolution */));
+        mCache.onAppDied(window.mAppToken);
+        assertNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */,
+                false /* restoreFromDisk */, false /* reducedResolution */));
+    }
+
+    @Test
+    public void testTaskRemoved() throws Exception {
+        final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window");
+        mCache.putSnapshot(window.getTask(), createSnapshot());
+        assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */,
+                false /* restoreFromDisk */, false /* reducedResolution */));
+        mCache.onTaskRemoved(window.getTask().mTaskId);
+        assertNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */,
+                false /* restoreFromDisk */, false /* reducedResolution */));
+    }
+
+    @Test
+    public void testReduced_notCached() throws Exception {
+        final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window");
+        mPersister.persistSnapshot(window.getTask().mTaskId, sWm.mCurrentUserId, createSnapshot());
+        mPersister.waitForQueueEmpty();
+        assertNull(mCache.getSnapshot(window.getTask().mTaskId, sWm.mCurrentUserId,
+                false /* restoreFromDisk */, false /* reducedResolution */));
+
+        // Load it from disk
+        assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, sWm.mCurrentUserId,
+                true /* restoreFromDisk */, true /* reducedResolution */));
+
+        // Make sure it's not in the cache now.
+        assertNull(mCache.getSnapshot(window.getTask().mTaskId, sWm.mCurrentUserId,
+                false /* restoreFromDisk */, false /* reducedResolution */));
+    }
+
+    @Test
+    public void testRestoreFromDisk() throws Exception {
+        final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window");
+        mPersister.persistSnapshot(window.getTask().mTaskId, sWm.mCurrentUserId, createSnapshot());
+        mPersister.waitForQueueEmpty();
+        assertNull(mCache.getSnapshot(window.getTask().mTaskId, sWm.mCurrentUserId,
+                false /* restoreFromDisk */, false /* reducedResolution */));
+
+        // Load it from disk
+        assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, sWm.mCurrentUserId,
+                true /* restoreFromDisk */, false /* reducedResolution */));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java
new file mode 100644
index 0000000..5650050
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
+import static android.view.WindowManager.TRANSIT_UNSET;
+import static com.android.server.wm.TaskSnapshotController.*;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.ArraySet;
+
+import com.google.android.collect.Sets;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for {@link TaskSnapshotController}.
+ *
+ * runtest frameworks-services -c com.android.server.wm.TaskSnapshotControllerTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class TaskSnapshotControllerTest extends WindowTestsBase {
+
+    @Test
+    public void testGetClosingApps_closing() throws Exception {
+        final WindowState closingWindow = createWindow(null, FIRST_APPLICATION_WINDOW,
+                "closingWindow");
+        closingWindow.mAppToken.setVisibility(null, false /* visible */, TRANSIT_UNSET,
+                true /* performLayout */, false /* isVoiceInteraction */);
+        final ArraySet<AppWindowToken> closingApps = new ArraySet<>();
+        closingApps.add(closingWindow.mAppToken);
+        final ArraySet<Task> closingTasks = new ArraySet<>();
+        sWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks);
+        assertEquals(1, closingTasks.size());
+        assertEquals(closingWindow.mAppToken.getTask(), closingTasks.valueAt(0));
+    }
+
+    @Test
+    public void testGetClosingApps_notClosing() throws Exception {
+        final WindowState closingWindow = createWindow(null, FIRST_APPLICATION_WINDOW,
+                "closingWindow");
+        final WindowState openingWindow = createAppWindow(closingWindow.getTask(),
+                FIRST_APPLICATION_WINDOW, "openingWindow");
+        closingWindow.mAppToken.setVisibility(null, false /* visible */, TRANSIT_UNSET,
+                true /* performLayout */, false /* isVoiceInteraction */);
+        openingWindow.mAppToken.setVisibility(null, true /* visible */, TRANSIT_UNSET,
+                true /* performLayout */, false /* isVoiceInteraction */);
+        final ArraySet<AppWindowToken> closingApps = new ArraySet<>();
+        closingApps.add(closingWindow.mAppToken);
+        final ArraySet<Task> closingTasks = new ArraySet<>();
+        sWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks);
+        assertEquals(0, closingTasks.size());
+    }
+
+    @Test
+    public void testGetClosingApps_skipClosingAppsSnapshotTasks() throws Exception {
+        final WindowState closingWindow = createWindow(null, FIRST_APPLICATION_WINDOW,
+                "closingWindow");
+        closingWindow.mAppToken.setVisibility(null, false /* visible */, TRANSIT_UNSET,
+                true /* performLayout */, false /* isVoiceInteraction */);
+        final ArraySet<AppWindowToken> closingApps = new ArraySet<>();
+        closingApps.add(closingWindow.mAppToken);
+        final ArraySet<Task> closingTasks = new ArraySet<>();
+        sWm.mTaskSnapshotController.addSkipClosingAppSnapshotTasks(
+                Sets.newArraySet(closingWindow.mAppToken.getTask()));
+        sWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks);
+        assertEquals(0, closingTasks.size());
+    }
+
+    @Test
+    public void testGetSnapshotMode() throws Exception {
+        final WindowState disabledWindow = createWindow(null,
+                FIRST_APPLICATION_WINDOW, mDisplayContent, "disabledWindow");
+        disabledWindow.mAppToken.setDisablePreviewScreenshots(true);
+        assertEquals(SNAPSHOT_MODE_APP_THEME,
+                sWm.mTaskSnapshotController.getSnapshotMode(disabledWindow.getTask()));
+
+        final WindowState normalWindow = createWindow(null,
+                FIRST_APPLICATION_WINDOW, mDisplayContent, "normalWindow");
+        assertEquals(SNAPSHOT_MODE_REAL,
+                sWm.mTaskSnapshotController.getSnapshotMode(normalWindow.getTask()));
+
+        final WindowState secureWindow = createWindow(null,
+                FIRST_APPLICATION_WINDOW, mDisplayContent, "secureWindow");
+        secureWindow.mAttrs.flags |= FLAG_SECURE;
+        assertEquals(SNAPSHOT_MODE_APP_THEME,
+                sWm.mTaskSnapshotController.getSnapshotMode(secureWindow.getTask()));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
new file mode 100644
index 0000000..325d42a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.app.ActivityManager.TaskSnapshot;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.ArraySet;
+
+import android.view.View;
+import com.android.server.wm.TaskSnapshotPersister.RemoveObsoleteFilesQueueItem;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+
+/**
+ * Test class for {@link TaskSnapshotPersister} and {@link TaskSnapshotLoader}
+ *
+ * atest FrameworksServicesTests:TaskSnapshotPersisterLoaderTest
+ */
+@MediumTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBase {
+
+    private static final Rect TEST_INSETS = new Rect(10, 20, 30, 40);
+
+    @Test
+    public void testPersistAndLoadSnapshot() {
+        mPersister.persistSnapshot(1 , mTestUserId, createSnapshot());
+        mPersister.waitForQueueEmpty();
+        final File[] files = new File[] { new File(sFilesDir.getPath() + "/snapshots/1.proto"),
+                new File(sFilesDir.getPath() + "/snapshots/1.jpg"),
+                new File(sFilesDir.getPath() + "/snapshots/1_reduced.jpg")};
+        assertTrueForFiles(files, File::exists, " must exist");
+        final TaskSnapshot snapshot = mLoader.loadTask(1, mTestUserId, false /* reduced */);
+        assertNotNull(snapshot);
+        assertEquals(TEST_INSETS, snapshot.getContentInsets());
+        assertNotNull(snapshot.getSnapshot());
+        assertEquals(Configuration.ORIENTATION_PORTRAIT, snapshot.getOrientation());
+    }
+
+    private void assertTrueForFiles(File[] files, Predicate<File> predicate, String message) {
+        for (File file : files) {
+            assertTrue(file.getName() + message, predicate.apply(file));
+        }
+    }
+
+    @Test
+    public void testTaskRemovedFromRecents() {
+        mPersister.persistSnapshot(1, mTestUserId, createSnapshot());
+        mPersister.onTaskRemovedFromRecents(1, mTestUserId);
+        mPersister.waitForQueueEmpty();
+        assertFalse(new File(sFilesDir.getPath() + "/snapshots/1.proto").exists());
+        assertFalse(new File(sFilesDir.getPath() + "/snapshots/1.jpg").exists());
+        assertFalse(new File(sFilesDir.getPath() + "/snapshots/1_reduced.jpg").exists());
+    }
+
+    /**
+     * Tests that persisting a couple of snapshots is being throttled.
+     */
+    @Test
+    public void testThrottling() {
+        long ms = SystemClock.elapsedRealtime();
+        mPersister.persistSnapshot(1, mTestUserId, createSnapshot());
+        mPersister.persistSnapshot(2, mTestUserId, createSnapshot());
+        mPersister.removeObsoleteFiles(new ArraySet<>(), new int[] { mTestUserId });
+        mPersister.removeObsoleteFiles(new ArraySet<>(), new int[] { mTestUserId });
+        mPersister.removeObsoleteFiles(new ArraySet<>(), new int[] { mTestUserId });
+        mPersister.removeObsoleteFiles(new ArraySet<>(), new int[] { mTestUserId });
+        mPersister.waitForQueueEmpty();
+        assertTrue(SystemClock.elapsedRealtime() - ms > 500);
+    }
+
+    /**
+     * Tests that too many store write queue items are being purged.
+     */
+    @Test
+    public void testPurging() {
+        mPersister.persistSnapshot(100, mTestUserId, createSnapshot());
+        mPersister.waitForQueueEmpty();
+        mPersister.setPaused(true);
+        mPersister.persistSnapshot(1, mTestUserId, createSnapshot());
+        mPersister.removeObsoleteFiles(new ArraySet<>(), new int[] { mTestUserId });
+        mPersister.persistSnapshot(2, mTestUserId, createSnapshot());
+        mPersister.persistSnapshot(3, mTestUserId, createSnapshot());
+        mPersister.persistSnapshot(4, mTestUserId, createSnapshot());
+        mPersister.setPaused(false);
+        mPersister.waitForQueueEmpty();
+
+        // Make sure 1,2 were purged but removeObsoleteFiles wasn't.
+        final File[] existsFiles = new File[] {
+                new File(sFilesDir.getPath() + "/snapshots/3.proto"),
+                new File(sFilesDir.getPath() + "/snapshots/4.proto")};
+        final File[] nonExistsFiles = new File[] {
+                new File(sFilesDir.getPath() + "/snapshots/100.proto"),
+                new File(sFilesDir.getPath() + "/snapshots/1.proto"),
+                new File(sFilesDir.getPath() + "/snapshots/1.proto")};
+        assertTrueForFiles(existsFiles, File::exists, " must exist");
+        assertTrueForFiles(nonExistsFiles, file -> !file.exists(), " must not exist");
+    }
+
+    @Test
+    public void testGetTaskId() {
+        RemoveObsoleteFilesQueueItem removeObsoleteFilesQueueItem =
+                mPersister.new RemoveObsoleteFilesQueueItem(new ArraySet<>(), new int[] {});
+        assertEquals(-1, removeObsoleteFilesQueueItem.getTaskId("blablablulp"));
+        assertEquals(-1, removeObsoleteFilesQueueItem.getTaskId("nothing.err"));
+        assertEquals(-1, removeObsoleteFilesQueueItem.getTaskId("/invalid/"));
+        assertEquals(12, removeObsoleteFilesQueueItem.getTaskId("12.jpg"));
+        assertEquals(12, removeObsoleteFilesQueueItem.getTaskId("12.proto"));
+        assertEquals(1, removeObsoleteFilesQueueItem.getTaskId("1.jpg"));
+        assertEquals(1, removeObsoleteFilesQueueItem.getTaskId("1_reduced.jpg"));
+    }
+
+    @Test
+    public void testLowResolutionPersistAndLoadSnapshot() {
+        TaskSnapshot a = createSnapshot(0.5f /* reducedResolution */);
+        assertTrue(a.isReducedResolution());
+        mPersister.persistSnapshot(1 , mTestUserId, a);
+        mPersister.waitForQueueEmpty();
+        final File[] files = new File[] { new File(sFilesDir.getPath() + "/snapshots/1.proto"),
+                new File(sFilesDir.getPath() + "/snapshots/1_reduced.jpg")};
+        final File[] nonExistsFiles = new File[] {
+                new File(sFilesDir.getPath() + "/snapshots/1.jpg"),
+        };
+        assertTrueForFiles(files, File::exists, " must exist");
+        assertTrueForFiles(nonExistsFiles, file -> !file.exists(), " must not exist");
+        final TaskSnapshot snapshot = mLoader.loadTask(1, mTestUserId, true /* reduced */);
+        assertNotNull(snapshot);
+        assertEquals(TEST_INSETS, snapshot.getContentInsets());
+        assertNotNull(snapshot.getSnapshot());
+        assertEquals(Configuration.ORIENTATION_PORTRAIT, snapshot.getOrientation());
+
+        final TaskSnapshot snapshotNotExist = mLoader.loadTask(1, mTestUserId, false /* reduced */);
+        assertNull(snapshotNotExist);
+    }
+
+    @Test
+    public void testIsRealSnapshotPersistAndLoadSnapshot() {
+        TaskSnapshot a = new TaskSnapshotBuilder()
+                .setIsRealSnapshot(true)
+                .build();
+        TaskSnapshot b = new TaskSnapshotBuilder()
+                .setIsRealSnapshot(false)
+                .build();
+        assertTrue(a.isRealSnapshot());
+        assertFalse(b.isRealSnapshot());
+        mPersister.persistSnapshot(1, mTestUserId, a);
+        mPersister.persistSnapshot(2, mTestUserId, b);
+        mPersister.waitForQueueEmpty();
+        final TaskSnapshot snapshotA = mLoader.loadTask(1, mTestUserId, false /* reduced */);
+        final TaskSnapshot snapshotB = mLoader.loadTask(2, mTestUserId, false /* reduced */);
+        assertNotNull(snapshotA);
+        assertNotNull(snapshotB);
+        assertTrue(snapshotA.isRealSnapshot());
+        assertFalse(snapshotB.isRealSnapshot());
+    }
+
+    @Test
+    public void testWindowingModePersistAndLoadSnapshot() {
+        TaskSnapshot a = new TaskSnapshotBuilder()
+                .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
+                .build();
+        TaskSnapshot b = new TaskSnapshotBuilder()
+                .setWindowingMode(WINDOWING_MODE_PINNED)
+                .build();
+        assertTrue(a.getWindowingMode() == WINDOWING_MODE_FULLSCREEN);
+        assertTrue(b.getWindowingMode() == WINDOWING_MODE_PINNED);
+        mPersister.persistSnapshot(1, mTestUserId, a);
+        mPersister.persistSnapshot(2, mTestUserId, b);
+        mPersister.waitForQueueEmpty();
+        final TaskSnapshot snapshotA = mLoader.loadTask(1, mTestUserId, false /* reduced */);
+        final TaskSnapshot snapshotB = mLoader.loadTask(2, mTestUserId, false /* reduced */);
+        assertNotNull(snapshotA);
+        assertNotNull(snapshotB);
+        assertTrue(snapshotA.getWindowingMode() == WINDOWING_MODE_FULLSCREEN);
+        assertTrue(snapshotB.getWindowingMode() == WINDOWING_MODE_PINNED);
+    }
+
+    @Test
+    public void testIsTranslucentPersistAndLoadSnapshot() {
+        TaskSnapshot a = new TaskSnapshotBuilder()
+                .setIsTranslucent(true)
+                .build();
+        TaskSnapshot b = new TaskSnapshotBuilder()
+                .setIsTranslucent(false)
+                .build();
+        assertTrue(a.isTranslucent());
+        assertFalse(b.isTranslucent());
+        mPersister.persistSnapshot(1, mTestUserId, a);
+        mPersister.persistSnapshot(2, mTestUserId, b);
+        mPersister.waitForQueueEmpty();
+        final TaskSnapshot snapshotA = mLoader.loadTask(1, mTestUserId, false /* reduced */);
+        final TaskSnapshot snapshotB = mLoader.loadTask(2, mTestUserId, false /* reduced */);
+        assertNotNull(snapshotA);
+        assertNotNull(snapshotB);
+        assertTrue(snapshotA.isTranslucent());
+        assertFalse(snapshotB.isTranslucent());
+    }
+
+    @Test
+    public void testSystemUiVisibilityPersistAndLoadSnapshot() {
+        final int lightBarFlags = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
+                | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+        TaskSnapshot a = new TaskSnapshotBuilder()
+                .setSystemUiVisibility(0)
+                .build();
+        TaskSnapshot b = new TaskSnapshotBuilder()
+                .setSystemUiVisibility(lightBarFlags)
+                .build();
+        assertTrue(a.getSystemUiVisibility() == 0);
+        assertTrue(b.getSystemUiVisibility() == lightBarFlags);
+        mPersister.persistSnapshot(1, mTestUserId, a);
+        mPersister.persistSnapshot(2, mTestUserId, b);
+        mPersister.waitForQueueEmpty();
+        final TaskSnapshot snapshotA = mLoader.loadTask(1, mTestUserId, false /* reduced */);
+        final TaskSnapshot snapshotB = mLoader.loadTask(2, mTestUserId, false /* reduced */);
+        assertNotNull(snapshotA);
+        assertNotNull(snapshotB);
+        assertTrue(snapshotA.getSystemUiVisibility() == 0);
+        assertTrue(snapshotB.getSystemUiVisibility() == lightBarFlags);
+    }
+
+    @Test
+    public void testRemoveObsoleteFiles() {
+        mPersister.persistSnapshot(1, mTestUserId, createSnapshot());
+        mPersister.persistSnapshot(2, mTestUserId, createSnapshot());
+        final ArraySet<Integer> taskIds = new ArraySet<>();
+        taskIds.add(1);
+        mPersister.removeObsoleteFiles(taskIds, new int[] { mTestUserId });
+        mPersister.waitForQueueEmpty();
+        final File[] existsFiles = new File[] {
+                new File(sFilesDir.getPath() + "/snapshots/1.proto"),
+                new File(sFilesDir.getPath() + "/snapshots/1.jpg"),
+                new File(sFilesDir.getPath() + "/snapshots/1_reduced.jpg") };
+        final File[] nonExistsFiles = new File[] {
+                new File(sFilesDir.getPath() + "/snapshots/2.proto"),
+                new File(sFilesDir.getPath() + "/snapshots/2.jpg"),
+                new File(sFilesDir.getPath() + "/snapshots/2_reduced.jpg")};
+        assertTrueForFiles(existsFiles, File::exists, " must exist");
+        assertTrueForFiles(nonExistsFiles, file -> !file.exists(), " must not exist");
+    }
+
+    @Test
+    public void testRemoveObsoleteFiles_addedOneInTheMeantime() {
+        mPersister.persistSnapshot(1, mTestUserId, createSnapshot());
+        final ArraySet<Integer> taskIds = new ArraySet<>();
+        taskIds.add(1);
+        mPersister.removeObsoleteFiles(taskIds, new int[] { mTestUserId });
+        mPersister.persistSnapshot(2, mTestUserId, createSnapshot());
+        mPersister.waitForQueueEmpty();
+        final File[] existsFiles = new File[] {
+                new File(sFilesDir.getPath() + "/snapshots/1.proto"),
+                new File(sFilesDir.getPath() + "/snapshots/1.jpg"),
+                new File(sFilesDir.getPath() + "/snapshots/1_reduced.jpg"),
+                new File(sFilesDir.getPath() + "/snapshots/2.proto"),
+                new File(sFilesDir.getPath() + "/snapshots/2.jpg"),
+                new File(sFilesDir.getPath() + "/snapshots/2_reduced.jpg")};
+        assertTrueForFiles(existsFiles, File::exists, " must exist");
+    }
+
+    /**
+     * Private predicate definition.
+     *
+     * This is needed because com.android.internal.util.Predicate is deprecated
+     * and can only be used with classes fron android.test.runner. This cannot
+     * use java.util.function.Predicate because that is not present on all API
+     * versions that this test must run on.
+     */
+    private interface Predicate<T> {
+        boolean apply(T t);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
new file mode 100644
index 0000000..8b86043
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.graphics.GraphicBuffer.USAGE_HW_TEXTURE;
+import static android.graphics.GraphicBuffer.USAGE_SW_READ_RARELY;
+
+import android.app.ActivityManager.TaskSnapshot;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.GraphicBuffer;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.os.UserManager;
+import android.support.test.InstrumentationRegistry;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import java.io.File;
+
+/**
+ * Base class for tests that use a {@link TaskSnapshotPersister}.
+ */
+class TaskSnapshotPersisterTestBase extends WindowTestsBase {
+
+    private static final Rect TEST_INSETS = new Rect(10, 20, 30, 40);
+
+    TaskSnapshotPersister mPersister;
+    TaskSnapshotLoader mLoader;
+    int mTestUserId;
+    static File sFilesDir;
+
+    @BeforeClass
+    public static void setUpUser() {
+        sFilesDir = InstrumentationRegistry.getContext().getFilesDir();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        final UserManager um = UserManager.get(InstrumentationRegistry.getContext());
+        mTestUserId = um.getUserHandle();
+        mPersister = new TaskSnapshotPersister(userId -> sFilesDir);
+        mLoader = new TaskSnapshotLoader(mPersister);
+        mPersister.start();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        cleanDirectory();
+    }
+
+    private void cleanDirectory() {
+        final File[] files = new File(sFilesDir, "snapshots").listFiles();
+        if (files == null) {
+            return;
+        }
+        for (File file : files) {
+            if (!file.isDirectory()) {
+                file.delete();
+            }
+        }
+    }
+
+    TaskSnapshot createSnapshot() {
+        return createSnapshot(1f /* scale */);
+    }
+
+    TaskSnapshot createSnapshot(float scale) {
+        return new TaskSnapshotBuilder()
+                .setScale(scale)
+                .build();
+    }
+
+    /**
+     * Builds a TaskSnapshot.
+     */
+    class TaskSnapshotBuilder {
+
+        private float mScale = 1f;
+        private boolean mIsRealSnapshot = true;
+        private boolean mIsTranslucent = false;
+        private int mWindowingMode = WINDOWING_MODE_FULLSCREEN;
+        private int mSystemUiVisibility = 0;
+
+        public TaskSnapshotBuilder setScale(float scale) {
+            mScale = scale;
+            return this;
+        }
+
+        public TaskSnapshotBuilder setIsRealSnapshot(boolean isRealSnapshot) {
+            mIsRealSnapshot = isRealSnapshot;
+            return this;
+        }
+
+        public TaskSnapshotBuilder setIsTranslucent(boolean isTranslucent) {
+            mIsTranslucent = isTranslucent;
+            return this;
+        }
+
+        public TaskSnapshotBuilder setWindowingMode(int windowingMode) {
+            mWindowingMode = windowingMode;
+            return this;
+        }
+
+        public TaskSnapshotBuilder setSystemUiVisibility(int systemUiVisibility) {
+            mSystemUiVisibility = systemUiVisibility;
+            return this;
+        }
+
+        public TaskSnapshot build() {
+            final GraphicBuffer buffer = GraphicBuffer.create(100, 100, PixelFormat.RGBA_8888,
+                    USAGE_HW_TEXTURE | USAGE_SW_READ_RARELY | USAGE_SW_READ_RARELY);
+            Canvas c = buffer.lockCanvas();
+            c.drawColor(Color.RED);
+            buffer.unlockCanvasAndPost(c);
+            return new TaskSnapshot(buffer, ORIENTATION_PORTRAIT, TEST_INSETS,
+                    mScale < 1f /* reducedResolution */, mScale, mIsRealSnapshot, mWindowingMode,
+                    mSystemUiVisibility, mIsTranslucent);
+        }
+
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
new file mode 100644
index 0000000..b19373e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager.TaskSnapshot;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.GraphicBuffer;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.Surface;
+
+import com.android.server.wm.TaskSnapshotSurface.Window;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for {@link TaskSnapshotSurface}.
+ *
+ * runtest frameworks-services -c com.android.server.wm.TaskSnapshotSurfaceTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class TaskSnapshotSurfaceTest extends WindowTestsBase {
+
+    private TaskSnapshotSurface mSurface;
+
+    private void setupSurface(int width, int height, Rect contentInsets, int sysuiVis,
+            int windowFlags, Rect taskBounds) {
+        final GraphicBuffer buffer = GraphicBuffer.create(width, height, PixelFormat.RGBA_8888,
+                GraphicBuffer.USAGE_SW_READ_NEVER | GraphicBuffer.USAGE_SW_WRITE_NEVER);
+        final TaskSnapshot snapshot = new TaskSnapshot(buffer,
+                ORIENTATION_PORTRAIT, contentInsets, false, 1.0f, true /* isRealSnapshot */,
+                WINDOWING_MODE_FULLSCREEN, 0 /* systemUiVisibility */, false /* isTranslucent */);
+        mSurface = new TaskSnapshotSurface(sWm, new Window(), new Surface(), snapshot, "Test",
+                Color.WHITE, Color.RED, Color.BLUE, sysuiVis, windowFlags, 0, taskBounds,
+                ORIENTATION_PORTRAIT);
+    }
+
+    private void setupSurface(int width, int height) {
+        setupSurface(width, height, new Rect(), 0, FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
+                new Rect(0, 0, width, height));
+    }
+
+    @Test
+    public void fillEmptyBackground_fillHorizontally() throws Exception {
+        setupSurface(200, 100);
+        final Canvas mockCanvas = mock(Canvas.class);
+        when(mockCanvas.getWidth()).thenReturn(200);
+        when(mockCanvas.getHeight()).thenReturn(100);
+        mSurface.drawBackgroundAndBars(mockCanvas, new Rect(0, 0, 100, 200));
+        verify(mockCanvas).drawRect(eq(100.0f), eq(0.0f), eq(200.0f), eq(100.0f), any());
+    }
+
+    @Test
+    public void fillEmptyBackground_fillVertically() throws Exception {
+        setupSurface(100, 200);
+        final Canvas mockCanvas = mock(Canvas.class);
+        when(mockCanvas.getWidth()).thenReturn(100);
+        when(mockCanvas.getHeight()).thenReturn(200);
+        mSurface.drawBackgroundAndBars(mockCanvas, new Rect(0, 0, 200, 100));
+        verify(mockCanvas).drawRect(eq(0.0f), eq(100.0f), eq(100.0f), eq(200.0f), any());
+    }
+
+    @Test
+    public void fillEmptyBackground_fillBoth() throws Exception {
+        setupSurface(200, 200);
+        final Canvas mockCanvas = mock(Canvas.class);
+        when(mockCanvas.getWidth()).thenReturn(200);
+        when(mockCanvas.getHeight()).thenReturn(200);
+        mSurface.drawBackgroundAndBars(mockCanvas, new Rect(0, 0, 100, 100));
+        verify(mockCanvas).drawRect(eq(100.0f), eq(0.0f), eq(200.0f), eq(100.0f), any());
+        verify(mockCanvas).drawRect(eq(0.0f), eq(100.0f), eq(200.0f), eq(200.0f), any());
+    }
+
+    @Test
+    public void fillEmptyBackground_dontFill_sameSize() throws Exception {
+        setupSurface(100, 100);
+        final Canvas mockCanvas = mock(Canvas.class);
+        when(mockCanvas.getWidth()).thenReturn(100);
+        when(mockCanvas.getHeight()).thenReturn(100);
+        mSurface.drawBackgroundAndBars(mockCanvas, new Rect(0, 0, 100, 100));
+        verify(mockCanvas, never()).drawRect(anyInt(), anyInt(), anyInt(), anyInt(), any());
+    }
+
+    @Test
+    public void fillEmptyBackground_dontFill_bitmapLarger() throws Exception {
+        setupSurface(100, 100);
+        final Canvas mockCanvas = mock(Canvas.class);
+        when(mockCanvas.getWidth()).thenReturn(100);
+        when(mockCanvas.getHeight()).thenReturn(100);
+        mSurface.drawBackgroundAndBars(mockCanvas, new Rect(0, 0, 200, 200));
+        verify(mockCanvas, never()).drawRect(anyInt(), anyInt(), anyInt(), anyInt(), any());
+    }
+
+    @Test
+    public void testCalculateSnapshotCrop() {
+        setupSurface(100, 100, new Rect(0, 10, 0, 10), 0, 0, new Rect(0, 0, 100, 100));
+        assertEquals(new Rect(0, 0, 100, 90), mSurface.calculateSnapshotCrop());
+    }
+
+    @Test
+    public void testCalculateSnapshotCrop_taskNotOnTop() {
+        setupSurface(100, 100, new Rect(0, 10, 0, 10), 0, 0, new Rect(0, 50, 100, 100));
+        assertEquals(new Rect(0, 10, 100, 90), mSurface.calculateSnapshotCrop());
+    }
+
+    @Test
+    public void testCalculateSnapshotCrop_navBarLeft() {
+        setupSurface(100, 100, new Rect(10, 10, 0, 0), 0, 0, new Rect(0, 0, 100, 100));
+        assertEquals(new Rect(10, 0, 100, 100), mSurface.calculateSnapshotCrop());
+    }
+
+    @Test
+    public void testCalculateSnapshotCrop_navBarRight() {
+        setupSurface(100, 100, new Rect(0, 10, 10, 0), 0, 0, new Rect(0, 0, 100, 100));
+        assertEquals(new Rect(0, 0, 90, 100), mSurface.calculateSnapshotCrop());
+    }
+
+    @Test
+    public void testCalculateSnapshotFrame() {
+        setupSurface(100, 100);
+        final Rect insets = new Rect(0, 10, 0, 10);
+        mSurface.setFrames(new Rect(0, 0, 100, 100), insets, insets);
+        assertEquals(new Rect(0, -10, 100, 70),
+                mSurface.calculateSnapshotFrame(new Rect(0, 10, 100, 90)));
+    }
+
+    @Test
+    public void testCalculateSnapshotFrame_navBarLeft() {
+        setupSurface(100, 100);
+        final Rect insets = new Rect(10, 10, 0, 0);
+        mSurface.setFrames(new Rect(0, 0, 100, 100), insets, insets);
+        assertEquals(new Rect(0, -10, 90, 80),
+                mSurface.calculateSnapshotFrame(new Rect(10, 10, 100, 100)));
+    }
+
+    @Test
+    public void testDrawStatusBarBackground() {
+        setupSurface(100, 100);
+        final Rect insets = new Rect(0, 10, 10, 0);
+        mSurface.setFrames(new Rect(0, 0, 100, 100), insets, insets);
+        final Canvas mockCanvas = mock(Canvas.class);
+        when(mockCanvas.getWidth()).thenReturn(100);
+        when(mockCanvas.getHeight()).thenReturn(100);
+        mSurface.mSystemBarBackgroundPainter.drawStatusBarBackground(
+                mockCanvas, new Rect(0, 0, 50, 100), 10);
+        verify(mockCanvas).drawRect(eq(50.0f), eq(0.0f), eq(90.0f), eq(10.0f), any());
+    }
+
+    @Test
+    public void testDrawStatusBarBackground_nullFrame() {
+        setupSurface(100, 100);
+        final Rect insets = new Rect(0, 10, 10, 0);
+        mSurface.setFrames(new Rect(0, 0, 100, 100), insets, insets);
+        final Canvas mockCanvas = mock(Canvas.class);
+        when(mockCanvas.getWidth()).thenReturn(100);
+        when(mockCanvas.getHeight()).thenReturn(100);
+        mSurface.mSystemBarBackgroundPainter.drawStatusBarBackground(
+                mockCanvas, null, 10);
+        verify(mockCanvas).drawRect(eq(0.0f), eq(0.0f), eq(90.0f), eq(10.0f), any());
+    }
+
+    @Test
+    public void testDrawStatusBarBackground_nope() {
+        setupSurface(100, 100);
+        final Rect insets = new Rect(0, 10, 10, 0);
+        mSurface.setFrames(new Rect(0, 0, 100, 100), insets, insets);
+        final Canvas mockCanvas = mock(Canvas.class);
+        when(mockCanvas.getWidth()).thenReturn(100);
+        when(mockCanvas.getHeight()).thenReturn(100);
+        mSurface.mSystemBarBackgroundPainter.drawStatusBarBackground(
+                mockCanvas, new Rect(0, 0, 100, 100), 10);
+        verify(mockCanvas, never()).drawRect(anyInt(), anyInt(), anyInt(), anyInt(), any());
+    }
+
+    @Test
+    public void testDrawNavigationBarBackground() {
+        final Rect insets = new Rect(0, 10, 0, 10);
+        setupSurface(100, 100, insets, 0, FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
+                new Rect(0, 0, 100, 100));
+        mSurface.setFrames(new Rect(0, 0, 100, 100), insets, insets);
+        final Canvas mockCanvas = mock(Canvas.class);
+        when(mockCanvas.getWidth()).thenReturn(100);
+        when(mockCanvas.getHeight()).thenReturn(100);
+        mSurface.mSystemBarBackgroundPainter.drawNavigationBarBackground(mockCanvas);
+        verify(mockCanvas).drawRect(eq(new Rect(0, 90, 100, 100)), any());
+    }
+
+    @Test
+    public void testDrawNavigationBarBackground_left() {
+        final Rect insets = new Rect(10, 10, 0, 0);
+        setupSurface(100, 100, insets, 0, FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
+                new Rect(0, 0, 100, 100));
+        mSurface.setFrames(new Rect(0, 0, 100, 100), insets, insets);
+        final Canvas mockCanvas = mock(Canvas.class);
+        when(mockCanvas.getWidth()).thenReturn(100);
+        when(mockCanvas.getHeight()).thenReturn(100);
+        mSurface.mSystemBarBackgroundPainter.drawNavigationBarBackground(mockCanvas);
+        verify(mockCanvas).drawRect(eq(new Rect(0, 0, 10, 100)), any());
+    }
+
+    @Test
+    public void testDrawNavigationBarBackground_right() {
+        final Rect insets = new Rect(0, 10, 10, 0);
+        setupSurface(100, 100, insets, 0, FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
+                new Rect(0, 0, 100, 100));
+        mSurface.setFrames(new Rect(0, 0, 100, 100), insets, insets);
+        final Canvas mockCanvas = mock(Canvas.class);
+        when(mockCanvas.getWidth()).thenReturn(100);
+        when(mockCanvas.getHeight()).thenReturn(100);
+        mSurface.mSystemBarBackgroundPainter.drawNavigationBarBackground(mockCanvas);
+        verify(mockCanvas).drawRect(eq(new Rect(90, 0, 100, 100)), any());
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java
new file mode 100644
index 0000000..ca1994f
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.After;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+/**
+ * Tests for the {@link DisplayContent.TaskStackContainers} container in {@link DisplayContent}.
+ *
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.wm.TaskStackContainersTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class TaskStackContainersTests extends WindowTestsBase {
+
+    private TaskStack mPinnedStack;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        mPinnedStack = createStackControllerOnStackOnDisplay(
+                WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mDisplayContent).mContainer;
+        // Stack should contain visible app window to be considered visible.
+        final Task pinnedTask = createTaskInStack(mPinnedStack, 0 /* userId */);
+        assertFalse(mPinnedStack.isVisible());
+        final WindowTestUtils.TestAppWindowToken pinnedApp =
+                WindowTestUtils.createTestAppWindowToken(mDisplayContent);
+        pinnedTask.addChild(pinnedApp, 0 /* addPos */);
+        assertTrue(mPinnedStack.isVisible());
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mPinnedStack.removeImmediately();
+    }
+
+    @Test
+    public void testStackPositionChildAt() throws Exception {
+        // Test that always-on-top stack can't be moved to position other than top.
+        final TaskStack stack1 = createTaskStackOnDisplay(mDisplayContent);
+        final TaskStack stack2 = createTaskStackOnDisplay(mDisplayContent);
+
+        final WindowContainer taskStackContainer = stack1.getParent();
+
+        final int stack1Pos = taskStackContainer.mChildren.indexOf(stack1);
+        final int stack2Pos = taskStackContainer.mChildren.indexOf(stack2);
+        final int pinnedStackPos = taskStackContainer.mChildren.indexOf(mPinnedStack);
+        assertGreaterThan(pinnedStackPos, stack2Pos);
+        assertGreaterThan(stack2Pos, stack1Pos);
+
+        taskStackContainer.positionChildAt(WindowContainer.POSITION_BOTTOM, mPinnedStack, false);
+        assertEquals(taskStackContainer.mChildren.get(stack1Pos), stack1);
+        assertEquals(taskStackContainer.mChildren.get(stack2Pos), stack2);
+        assertEquals(taskStackContainer.mChildren.get(pinnedStackPos), mPinnedStack);
+
+        taskStackContainer.positionChildAt(1, mPinnedStack, false);
+        assertEquals(taskStackContainer.mChildren.get(stack1Pos), stack1);
+        assertEquals(taskStackContainer.mChildren.get(stack2Pos), stack2);
+        assertEquals(taskStackContainer.mChildren.get(pinnedStackPos), mPinnedStack);
+    }
+
+    @Test
+    public void testStackPositionBelowPinnedStack() throws Exception {
+        // Test that no stack can be above pinned stack.
+        final TaskStack stack1 = createTaskStackOnDisplay(mDisplayContent);
+
+        final WindowContainer taskStackContainer = stack1.getParent();
+
+        final int stackPos = taskStackContainer.mChildren.indexOf(stack1);
+        final int pinnedStackPos = taskStackContainer.mChildren.indexOf(mPinnedStack);
+        assertGreaterThan(pinnedStackPos, stackPos);
+
+        taskStackContainer.positionChildAt(WindowContainer.POSITION_TOP, stack1, false);
+        assertEquals(taskStackContainer.mChildren.get(stackPos), stack1);
+        assertEquals(taskStackContainer.mChildren.get(pinnedStackPos), mPinnedStack);
+
+        taskStackContainer.positionChildAt(taskStackContainer.mChildren.size() - 1, stack1, false);
+        assertEquals(taskStackContainer.mChildren.get(stackPos), stack1);
+        assertEquals(taskStackContainer.mChildren.get(pinnedStackPos), mPinnedStack);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java
new file mode 100644
index 0000000..eaf71f0
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for the {@link TaskStack} class.
+ *
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.wm.TaskStackTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class TaskStackTests extends WindowTestsBase {
+
+    @Test
+    public void testStackPositionChildAt() throws Exception {
+        final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
+        final Task task1 = createTaskInStack(stack, 0 /* userId */);
+        final Task task2 = createTaskInStack(stack, 1 /* userId */);
+
+        // Current user task should be moved to top.
+        stack.positionChildAt(WindowContainer.POSITION_TOP, task1, false /* includingParents */);
+        assertEquals(stack.mChildren.get(0), task2);
+        assertEquals(stack.mChildren.get(1), task1);
+
+        // Non-current user won't be moved to top.
+        stack.positionChildAt(WindowContainer.POSITION_TOP, task2, false /* includingParents */);
+        assertEquals(stack.mChildren.get(0), task2);
+        assertEquals(stack.mChildren.get(1), task1);
+    }
+
+    @Test
+    public void testClosingAppDifferentStackOrientation() throws Exception {
+        final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
+        final Task task1 = createTaskInStack(stack, 0 /* userId */);
+        WindowTestUtils.TestAppWindowToken appWindowToken1 =
+                WindowTestUtils.createTestAppWindowToken(mDisplayContent);
+        task1.addChild(appWindowToken1, 0);
+        appWindowToken1.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+
+        final Task task2 = createTaskInStack(stack, 1 /* userId */);
+        WindowTestUtils.TestAppWindowToken appWindowToken2 =
+                WindowTestUtils.createTestAppWindowToken(mDisplayContent);
+        task2.addChild(appWindowToken2, 0);
+        appWindowToken2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
+
+        assertEquals(SCREEN_ORIENTATION_PORTRAIT, stack.getOrientation());
+        sWm.mClosingApps.add(appWindowToken2);
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, stack.getOrientation());
+    }
+
+    @Test
+    public void testMoveTaskToBackDifferentStackOrientation() throws Exception {
+        final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
+        final Task task1 = createTaskInStack(stack, 0 /* userId */);
+        WindowTestUtils.TestAppWindowToken appWindowToken1 =
+                WindowTestUtils.createTestAppWindowToken(mDisplayContent);
+        task1.addChild(appWindowToken1, 0);
+        appWindowToken1.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+
+        final Task task2 = createTaskInStack(stack, 1 /* userId */);
+        WindowTestUtils.TestAppWindowToken appWindowToken2 =
+                WindowTestUtils.createTestAppWindowToken(mDisplayContent);
+        task2.addChild(appWindowToken2, 0);
+        appWindowToken2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
+
+        assertEquals(SCREEN_ORIENTATION_PORTRAIT, stack.getOrientation());
+        task2.setSendingToBottom(true);
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, stack.getOrientation());
+    }
+
+    @Test
+    public void testStackRemoveImmediately() throws Exception {
+        final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
+        final Task task = createTaskInStack(stack, 0 /* userId */);
+        assertEquals(stack, task.mStack);
+
+        // Remove stack and check if its child is also removed.
+        stack.removeImmediately();
+        assertNull(stack.getDisplayContent());
+        assertNull(task.mStack);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java
new file mode 100644
index 0000000..1dd9365
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test class for {@link TaskWindowContainerController}.
+ *
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.wm.TaskWindowContainerControllerTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class TaskWindowContainerControllerTests extends WindowTestsBase {
+
+    @Test
+    public void testRemoveContainer() throws Exception {
+        final WindowTestUtils.TestTaskWindowContainerController taskController =
+                new WindowTestUtils.TestTaskWindowContainerController(this);
+        final WindowTestUtils.TestAppWindowContainerController appController =
+                new WindowTestUtils.TestAppWindowContainerController(taskController);
+
+        taskController.removeContainer();
+        // Assert that the container was removed.
+        assertNull(taskController.mContainer);
+        assertNull(appController.mContainer);
+    }
+
+    @Test
+    public void testRemoveContainer_deferRemoval() throws Exception {
+        final WindowTestUtils.TestTaskWindowContainerController taskController =
+                new WindowTestUtils.TestTaskWindowContainerController(this);
+        final WindowTestUtils.TestAppWindowContainerController appController =
+                new WindowTestUtils.TestAppWindowContainerController(taskController);
+
+        final WindowTestUtils.TestTask task = (WindowTestUtils.TestTask) taskController.mContainer;
+        final AppWindowToken app = appController.mContainer;
+        task.mShouldDeferRemoval = true;
+
+        taskController.removeContainer();
+        // For the case of deferred removal the task controller will no longer be connected to the
+        // container, but the app controller will still be connected to the its container until
+        // the task window container is removed.
+        assertNull(taskController.mContainer);
+        assertNull(task.getController());
+        assertNotNull(appController.mContainer);
+        assertNotNull(app.getController());
+
+        task.removeImmediately();
+        assertNull(appController.mContainer);
+        assertNull(app.getController());
+    }
+
+    @Test
+    public void testReparent() throws Exception {
+        final StackWindowController stackController1 =
+                createStackControllerOnDisplay(mDisplayContent);
+        final WindowTestUtils.TestTaskWindowContainerController taskController =
+                new WindowTestUtils.TestTaskWindowContainerController(stackController1);
+        final StackWindowController stackController2 =
+                createStackControllerOnDisplay(mDisplayContent);
+        final WindowTestUtils.TestTaskWindowContainerController taskController2 =
+                new WindowTestUtils.TestTaskWindowContainerController(stackController2);
+
+        boolean gotException = false;
+        try {
+            taskController.reparent(stackController1, 0, false/* moveParents */);
+        } catch (IllegalArgumentException e) {
+            gotException = true;
+        }
+        assertTrue("Should not be able to reparent to the same parent", gotException);
+
+        final StackWindowController stackController3 =
+                createStackControllerOnDisplay(mDisplayContent);
+        stackController3.setContainer(null);
+        gotException = false;
+        try {
+            taskController.reparent(stackController3, 0, false/* moveParents */);
+        } catch (IllegalArgumentException e) {
+            gotException = true;
+        }
+        assertTrue("Should not be able to reparent to a stack that doesn't have a container",
+                gotException);
+
+        taskController.reparent(stackController2, 0, false/* moveParents */);
+        assertEquals(stackController2.mContainer, taskController.mContainer.getParent());
+        assertEquals(0, ((WindowTestUtils.TestTask) taskController.mContainer).positionInParent());
+        assertEquals(1, ((WindowTestUtils.TestTask) taskController2.mContainer).positionInParent());
+    }
+
+    @Test
+    public void testReparent_BetweenDisplays() throws Exception {
+        // Create first stack on primary display.
+        final StackWindowController stack1Controller =
+                createStackControllerOnDisplay(mDisplayContent);
+        final TaskStack stack1 = stack1Controller.mContainer;
+        final WindowTestUtils.TestTaskWindowContainerController taskController =
+                new WindowTestUtils.TestTaskWindowContainerController(stack1Controller);
+        final WindowTestUtils.TestTask task1 = (WindowTestUtils.TestTask) taskController.mContainer;
+        task1.mOnDisplayChangedCalled = false;
+        assertEquals(mDisplayContent, stack1.getDisplayContent());
+
+        // Create second display and put second stack on it.
+        final DisplayContent dc = createNewDisplay();
+        final StackWindowController stack2Controller = createStackControllerOnDisplay(dc);
+        final TaskStack stack2 = stack2Controller.mContainer;
+        final WindowTestUtils.TestTaskWindowContainerController taskController2 =
+                new WindowTestUtils.TestTaskWindowContainerController(stack2Controller);
+        final WindowTestUtils.TestTask task2 =
+                (WindowTestUtils.TestTask) taskController2.mContainer;
+
+        // Reparent and check state
+        taskController.reparent(stack2Controller, 0, false /* moveParents */);
+        assertEquals(stack2, task1.getParent());
+        assertEquals(0, task1.positionInParent());
+        assertEquals(1, task2.positionInParent());
+        assertTrue(task1.mOnDisplayChangedCalled);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java b/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java
new file mode 100644
index 0000000..353aa7d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import com.android.internal.os.IResultReceiver;
+
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.util.MergedConfiguration;
+import android.view.DisplayCutout;
+import android.view.DragEvent;
+import android.view.IWindow;
+
+public class TestIWindow extends IWindow.Stub {
+    @Override
+    public void executeCommand(String command, String parameters,
+            ParcelFileDescriptor descriptor)
+            throws RemoteException {
+
+    }
+
+    @Override
+    public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets,
+            Rect stableInsets, Rect outsets, boolean reportDraw, MergedConfiguration mergedConfig,
+            Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar, int displayId,
+            DisplayCutout.ParcelableWrapper displayCutout)
+            throws RemoteException {
+
+    }
+
+    @Override
+    public void moved(int newX, int newY) throws RemoteException {
+
+    }
+
+    @Override
+    public void dispatchAppVisibility(boolean visible) throws RemoteException {
+
+    }
+
+    @Override
+    public void dispatchGetNewSurface() throws RemoteException {
+
+    }
+
+    @Override
+    public void windowFocusChanged(boolean hasFocus, boolean inTouchMode)
+            throws RemoteException {
+
+    }
+
+    @Override
+    public void closeSystemDialogs(String reason) throws RemoteException {
+
+    }
+
+    @Override
+    public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
+            boolean sync)
+            throws RemoteException {
+
+    }
+
+    @Override
+    public void dispatchWallpaperCommand(String action, int x, int y, int z, Bundle extras,
+            boolean sync) throws RemoteException {
+
+    }
+
+    @Override
+    public void dispatchDragEvent(DragEvent event) throws RemoteException {
+
+    }
+
+    @Override
+    public void updatePointerIcon(float x, float y) throws RemoteException {
+
+    }
+
+    @Override
+    public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility, int localValue,
+            int localChanges) throws RemoteException {
+
+    }
+
+    @Override
+    public void dispatchWindowShown() throws RemoteException {
+
+    }
+
+    @Override
+    public void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId)
+            throws RemoteException {
+
+    }
+
+    @Override
+    public void dispatchPointerCaptureChanged(boolean hasCapture) {
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
new file mode 100644
index 0000000..ee028ba
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -0,0 +1,606 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+
+import static org.mockito.Mockito.mock;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.CompatibilityInfo;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.proto.ProtoOutputStream;
+import android.view.Display;
+import android.view.DisplayCutout;
+import android.view.IWindow;
+import android.view.IWindowManager;
+import android.view.KeyEvent;
+import android.view.WindowManager;
+import android.view.animation.Animation;
+
+import com.android.internal.policy.IKeyguardDismissCallback;
+import com.android.internal.policy.IShortcutService;
+import com.android.server.policy.WindowManagerPolicy;
+
+import java.io.PrintWriter;
+import java.util.function.Supplier;
+
+class TestWindowManagerPolicy implements WindowManagerPolicy {
+    private static final String TAG = "TestWindowManagerPolicy";
+
+    private final Supplier<WindowManagerService> mWmSupplier;
+
+    int rotationToReport = 0;
+    boolean keyguardShowingAndNotOccluded = false;
+
+    private Runnable mRunnableWhenAddingSplashScreen;
+
+    public TestWindowManagerPolicy(Supplier<WindowManagerService> wmSupplier) {
+
+        mWmSupplier = wmSupplier;
+    }
+
+    @Override
+    public void registerShortcutKey(long shortcutCode, IShortcutService shortcutKeyReceiver)
+            throws RemoteException {
+
+    }
+
+    @Override
+    public void init(Context context, IWindowManager windowManager,
+            WindowManagerFuncs windowManagerFuncs) {
+
+    }
+
+    @Override
+    public boolean isDefaultOrientationForced() {
+        return false;
+    }
+
+    @Override
+    public void setInitialDisplaySize(Display display, int width, int height, int density) {
+
+    }
+
+    @Override
+    public int checkAddPermission(WindowManager.LayoutParams attrs, int[] outAppOp) {
+        return 0;
+    }
+
+    @Override
+    public boolean checkShowToOwnerOnly(WindowManager.LayoutParams attrs) {
+        return false;
+    }
+
+    @Override
+    public void adjustWindowParamsLw(WindowState win, WindowManager.LayoutParams attrs,
+            boolean hasStatusBarServicePermission) {
+    }
+
+    @Override
+    public void adjustConfigurationLw(Configuration config, int keyboardPresence,
+            int navigationPresence) {
+
+    }
+
+    @Override
+    public int getMaxWallpaperLayer() {
+        return 0;
+    }
+
+    @Override
+    public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId, DisplayCutout displayCutout) {
+        return 0;
+    }
+
+    @Override
+    public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId, DisplayCutout displayCutout) {
+        return 0;
+    }
+
+    @Override
+    public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId, DisplayCutout displayCutout) {
+        return 0;
+    }
+
+    @Override
+    public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode,
+            int displayId, DisplayCutout displayCutout) {
+        return 0;
+    }
+
+    @Override
+    public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) {
+        return attrs.type == TYPE_STATUS_BAR;
+    }
+
+    @Override
+    public boolean canBeHiddenByKeyguardLw(WindowState win) {
+        return false;
+    }
+
+    /**
+     * Sets a runnable to run when adding a splash screen which gets executed after the window has
+     * been added but before returning the surface.
+     */
+    void setRunnableWhenAddingSplashScreen(Runnable r) {
+        mRunnableWhenAddingSplashScreen = r;
+    }
+
+    @Override
+    public StartingSurface addSplashScreen(IBinder appToken, String packageName, int theme,
+            CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, int icon,
+            int logo, int windowFlags, Configuration overrideConfig, int displayId) {
+        final com.android.server.wm.WindowState window;
+        final AppWindowToken atoken;
+        final WindowManagerService wm = mWmSupplier.get();
+        synchronized (wm.mWindowMap) {
+            atoken = wm.mRoot.getAppWindowToken(appToken);
+            window = WindowTestsBase.createWindow(null, TYPE_APPLICATION_STARTING, atoken,
+                    "Starting window", 0 /* ownerId */, false /* internalWindows */, wm,
+                    mock(Session.class), mock(IWindow.class));
+            atoken.startingWindow = window;
+        }
+        if (mRunnableWhenAddingSplashScreen != null) {
+            mRunnableWhenAddingSplashScreen.run();
+            mRunnableWhenAddingSplashScreen = null;
+        }
+        return () -> {
+            synchronized (wm.mWindowMap) {
+                atoken.removeChild(window);
+                atoken.startingWindow = null;
+            }
+        };
+    }
+
+    @Override
+    public int prepareAddWindowLw(WindowState win,
+            WindowManager.LayoutParams attrs) {
+        return 0;
+    }
+
+    @Override
+    public void removeWindowLw(WindowState win) {
+
+    }
+
+    @Override
+    public int selectAnimationLw(WindowState win, int transit) {
+        return 0;
+    }
+
+    @Override
+    public void selectRotationAnimationLw(int[] anim) {
+
+    }
+
+    @Override
+    public boolean validateRotationAnimationLw(int exitAnimId, int enterAnimId,
+            boolean forceDefault) {
+        return false;
+    }
+
+    @Override
+    public Animation createHiddenByKeyguardExit(boolean onWallpaper,
+            boolean goingToNotificationShade) {
+        return null;
+    }
+
+    @Override
+    public Animation createKeyguardWallpaperExit(boolean goingToNotificationShade) {
+        return null;
+    }
+
+    @Override
+    public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
+        return 0;
+    }
+
+    @Override
+    public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) {
+        return 0;
+    }
+
+    @Override
+    public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event,
+            int policyFlags) {
+        return 0;
+    }
+
+    @Override
+    public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event,
+            int policyFlags) {
+        return null;
+    }
+
+    @Override
+    public int getSystemDecorLayerLw() {
+        return 0;
+    }
+
+    @Override
+    public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) {
+
+    }
+
+    @Override
+    public void applyPostLayoutPolicyLw(WindowState win,
+            WindowManager.LayoutParams attrs, WindowState attached, WindowState imeTarget) {
+    }
+
+    @Override
+    public int finishPostLayoutPolicyLw() {
+        return 0;
+    }
+
+    @Override
+    public boolean allowAppAnimationsLw() {
+        return false;
+    }
+
+    @Override
+    public int focusChangedLw(WindowState lastFocus,
+            WindowState newFocus) {
+        return 0;
+    }
+
+    @Override
+    public void startedWakingUp() {
+
+    }
+
+    @Override
+    public void finishedWakingUp() {
+
+    }
+
+    @Override
+    public void startedGoingToSleep(int why) {
+
+    }
+
+    @Override
+    public void finishedGoingToSleep(int why) {
+
+    }
+
+    @Override
+    public void screenTurningOn(ScreenOnListener screenOnListener) {
+
+    }
+
+    @Override
+    public void screenTurnedOn() {
+
+    }
+
+    @Override
+    public void screenTurningOff(ScreenOffListener screenOffListener) {
+
+    }
+
+    @Override
+    public void screenTurnedOff() {
+
+    }
+
+    @Override
+    public boolean isScreenOn() {
+        return true;
+    }
+
+    @Override
+    public boolean okToAnimate() {
+        return true;
+    }
+
+    @Override
+    public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
+
+    }
+
+    @Override
+    public void notifyCameraLensCoverSwitchChanged(long whenNanos, boolean lensCovered) {
+
+    }
+
+    @Override
+    public void enableKeyguard(boolean enabled) {
+
+    }
+
+    @Override
+    public void exitKeyguardSecurely(OnKeyguardExitResult callback) {
+
+    }
+
+    @Override
+    public boolean isKeyguardLocked() {
+        return keyguardShowingAndNotOccluded;
+    }
+
+    @Override
+    public boolean isKeyguardSecure(int userId) {
+        return false;
+    }
+
+    @Override
+    public boolean isKeyguardOccluded() {
+        return false;
+    }
+
+    @Override
+    public boolean isKeyguardTrustedLw() {
+        return false;
+    }
+
+    @Override
+    public boolean isKeyguardShowingAndNotOccluded() {
+        return keyguardShowingAndNotOccluded;
+    }
+
+    @Override
+    public boolean inKeyguardRestrictedKeyInputMode() {
+        return false;
+    }
+
+    @Override
+    public void dismissKeyguardLw(@Nullable IKeyguardDismissCallback callback,
+            CharSequence message) {
+    }
+
+    @Override
+    public boolean isKeyguardDrawnLw() {
+        return false;
+    }
+
+    @Override
+    public boolean isShowingDreamLw() {
+        return false;
+    }
+
+    @Override
+    public void onKeyguardOccludedChangedLw(boolean occluded) {
+    }
+
+    @Override
+    public int rotationForOrientationLw(int orientation, int lastRotation, boolean defaultDisplay) {
+        return rotationToReport;
+    }
+
+    @Override
+    public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation) {
+        return true;
+    }
+
+    @Override
+    public void setRotationLw(int rotation) {
+
+    }
+
+    @Override
+    public void setSafeMode(boolean safeMode) {
+
+    }
+
+    @Override
+    public void systemReady() {
+
+    }
+
+    @Override
+    public void systemBooted() {
+
+    }
+
+    @Override
+    public void showBootMessage(CharSequence msg, boolean always) {
+
+    }
+
+    @Override
+    public void hideBootMessages() {
+
+    }
+
+    @Override
+    public void userActivity() {
+
+    }
+
+    @Override
+    public void enableScreenAfterBoot() {
+
+    }
+
+    @Override
+    public void setCurrentOrientationLw(int newOrientation) {
+
+    }
+
+    @Override
+    public boolean performHapticFeedbackLw(WindowState win, int effectId,
+            boolean always) {
+        return false;
+    }
+
+    @Override
+    public void keepScreenOnStartedLw() {
+
+    }
+
+    @Override
+    public void keepScreenOnStoppedLw() {
+
+    }
+
+    @Override
+    public int getUserRotationMode() {
+        return 0;
+    }
+
+    @Override
+    public void setUserRotationMode(int mode,
+            int rotation) {
+
+    }
+
+    @Override
+    public int adjustSystemUiVisibilityLw(int visibility) {
+        return 0;
+    }
+
+    @Override
+    public boolean hasNavigationBar() {
+        return false;
+    }
+
+    @Override
+    public void lockNow(Bundle options) {
+
+    }
+
+    @Override
+    public void setLastInputMethodWindowLw(WindowState ime,
+            WindowState target) {
+
+    }
+
+    @Override
+    public void showRecentApps() {
+
+    }
+
+    @Override
+    public void showGlobalActions() {
+
+    }
+
+    @Override
+    public void setCurrentUserLw(int newUserId) {
+
+    }
+
+    @Override
+    public void setSwitchingUser(boolean switching) {
+
+    }
+
+    @Override
+    public void writeToProto(ProtoOutputStream proto, long fieldId) {
+
+    }
+
+    @Override
+    public void dump(String prefix, PrintWriter writer, String[] args) {
+
+    }
+
+    @Override
+    public boolean isTopLevelWindow(int windowType) {
+        return false;
+    }
+
+    @Override
+    public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
+
+    }
+
+    @Override
+    public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight,
+            DisplayCutout cutout, Rect outInsets) {
+
+    }
+
+    @Override
+    public boolean isNavBarForcedShownLw(WindowState win) {
+        return false;
+    }
+
+    @NavigationBarPosition
+    @Override
+    public int getNavBarPosition() {
+        return NAV_BAR_BOTTOM;
+    }
+
+    @Override
+    public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight,
+            DisplayCutout cutout, Rect outInsets) {
+
+    }
+
+    @Override
+    public boolean isDockSideAllowed(int dockSide, int originalDockSide, int displayWidth,
+            int displayHeight, int displayRotation) {
+        return false;
+    }
+
+    @Override
+    public void onConfigurationChanged() {
+
+    }
+
+    @Override
+    public boolean shouldRotateSeamlessly(int oldRotation, int newRotation) {
+        return false;
+    }
+
+    @Override
+    public void setPipVisibilityLw(boolean visible) {
+
+    }
+
+    @Override
+    public void setRecentsVisibilityLw(boolean visible) {
+
+    }
+
+    @Override
+    public void setNavBarVirtualKeyHapticFeedbackEnabledLw(boolean enabled) {
+    }
+
+    @Override
+    public void onSystemUiStarted() {
+    }
+
+    @Override
+    public boolean canDismissBootAnimation() {
+        return true;
+    }
+
+    @Override
+    public void requestUserActivityNotification() {
+    }
+
+    @Override
+    public void onLockTaskStateChangedLw(int lockTaskState) {
+    }
+
+    @Override
+    public boolean setAodShowing(boolean aodShowing) {
+        return false;
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
new file mode 100644
index 0000000..a5c47de
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static junit.framework.Assert.assertTrue;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for {@link AppTransition}.
+ *
+ * runtest frameworks-services -c com.android.server.wm.UnknownAppVisibilityControllerTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class UnknownAppVisibilityControllerTest extends WindowTestsBase {
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        sWm.mUnknownAppVisibilityController.clear();
+    }
+
+    @Test
+    public void testFlow() throws Exception {
+        final AppWindowToken token = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
+        sWm.mUnknownAppVisibilityController.notifyLaunched(token);
+        sWm.mUnknownAppVisibilityController.notifyAppResumedFinished(token);
+        sWm.mUnknownAppVisibilityController.notifyRelayouted(token);
+
+        // Make sure our handler processed the message.
+        Thread.sleep(100);
+        assertTrue(sWm.mUnknownAppVisibilityController.allResolved());
+    }
+
+    @Test
+    public void testMultiple() throws Exception {
+        final AppWindowToken token1 = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
+        final AppWindowToken token2 = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
+        sWm.mUnknownAppVisibilityController.notifyLaunched(token1);
+        sWm.mUnknownAppVisibilityController.notifyAppResumedFinished(token1);
+        sWm.mUnknownAppVisibilityController.notifyLaunched(token2);
+        sWm.mUnknownAppVisibilityController.notifyRelayouted(token1);
+        sWm.mUnknownAppVisibilityController.notifyAppResumedFinished(token2);
+        sWm.mUnknownAppVisibilityController.notifyRelayouted(token2);
+
+        // Make sure our handler processed the message.
+        Thread.sleep(100);
+        assertTrue(sWm.mUnknownAppVisibilityController.allResolved());
+    }
+
+    @Test
+    public void testClear() throws Exception {
+        final AppWindowToken token = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
+        sWm.mUnknownAppVisibilityController.notifyLaunched(token);
+        sWm.mUnknownAppVisibilityController.clear();;
+        assertTrue(sWm.mUnknownAppVisibilityController.allResolved());
+    }
+
+    @Test
+    public void testAppRemoved() throws Exception {
+        final AppWindowToken token = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
+        sWm.mUnknownAppVisibilityController.notifyLaunched(token);
+        sWm.mUnknownAppVisibilityController.appRemovedOrHidden(token);
+        assertTrue(sWm.mUnknownAppVisibilityController.allResolved());
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/WallpaperControllerTests.java
new file mode 100644
index 0000000..71ead20
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -0,0 +1,67 @@
+package com.android.server.wm;
+
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+
+import static junit.framework.TestCase.assertNotNull;
+
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.graphics.Bitmap;
+import android.os.IBinder;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for the {@link WallpaperController} class.
+ *
+ * Build/Install/Run:
+ *  atest com.android.server.wm.WallpaperControllerTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class WallpaperControllerTests extends WindowTestsBase {
+    @Test
+    public void testWallpaperScreenshot() {
+        WindowSurfaceController windowSurfaceController = mock(WindowSurfaceController.class);
+
+        synchronized (sWm.mWindowMap) {
+            // No wallpaper
+            final DisplayContent dc = createNewDisplay();
+            Bitmap wallpaperBitmap = sWm.mRoot.mWallpaperController.screenshotWallpaperLocked();
+            assertNull(wallpaperBitmap);
+
+            // No wallpaper WSA Surface
+            WindowToken wallpaperWindowToken = new WallpaperWindowToken(sWm, mock(IBinder.class),
+                    true, dc, true /* ownerCanManageAppTokens */);
+            WindowState wallpaperWindow = createWindow(null /* parent */, TYPE_WALLPAPER,
+                    wallpaperWindowToken, "wallpaperWindow");
+            wallpaperBitmap = mWallpaperController.screenshotWallpaperLocked();
+            assertNull(wallpaperBitmap);
+
+            // Wallpaper with not visible WSA surface.
+            wallpaperWindow.mWinAnimator.mSurfaceController = windowSurfaceController;
+            wallpaperWindow.mWinAnimator.mLastAlpha = 1;
+            wallpaperBitmap = mWallpaperController.screenshotWallpaperLocked();
+            assertNull(wallpaperBitmap);
+
+            when(windowSurfaceController.getShown()).thenReturn(true);
+
+            // Wallpaper with WSA alpha set to 0.
+            wallpaperWindow.mWinAnimator.mLastAlpha = 0;
+            wallpaperBitmap = mWallpaperController.screenshotWallpaperLocked();
+            assertNull(wallpaperBitmap);
+
+            // Wallpaper window with WSA Surface
+            wallpaperWindow.mWinAnimator.mLastAlpha = 1;
+            wallpaperBitmap = mWallpaperController.screenshotWallpaperLocked();
+            assertNotNull(wallpaperBitmap);
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java b/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java
new file mode 100644
index 0000000..ca520ed
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
+import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
+import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;
+
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.SurfaceControl;
+import android.view.animation.Animation;
+import android.view.animation.ClipRectAnimation;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for the {@link WindowAnimationSpec} class.
+ *
+ *  atest FrameworksServicesTests:com.android.server.wm.WindowAnimationSpecTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class WindowAnimationSpecTest {
+    private final SurfaceControl mSurfaceControl = mock(SurfaceControl.class);
+    private final SurfaceControl.Transaction mTransaction = mock(SurfaceControl.Transaction.class);
+    private final Animation mAnimation = mock(Animation.class);
+    private final Rect mStackBounds = new Rect(0, 0, 10, 10);
+
+    @Test
+    public void testApply_clipNone() {
+        Rect windowCrop = new Rect(0, 0, 20, 20);
+        Animation a = createClipRectAnimation(windowCrop, windowCrop);
+        WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(a, null,
+                mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_NONE,
+                true /* isAppAnimation */);
+        windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0);
+        verify(mTransaction).setWindowCrop(eq(mSurfaceControl),
+                argThat(rect -> rect.equals(windowCrop)));
+    }
+
+    @Test
+    public void testApply_clipAfter() {
+        WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(mAnimation, null,
+                mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_AFTER_ANIM,
+                true /* isAppAnimation */);
+        windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0);
+        verify(mTransaction).setWindowCrop(eq(mSurfaceControl), argThat(Rect::isEmpty));
+        verify(mTransaction).setFinalCrop(eq(mSurfaceControl),
+                argThat(rect -> rect.equals(mStackBounds)));
+    }
+
+    @Test
+    public void testApply_clipAfterOffsetPosition() {
+        // Stack bounds is (0, 0, 10, 10) position is (20, 40)
+        WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(mAnimation,
+                new Point(20, 40), mStackBounds, false /* canSkipFirstFrame */,
+                STACK_CLIP_AFTER_ANIM,
+                true /* isAppAnimation */);
+        windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0);
+        verify(mTransaction).setWindowCrop(eq(mSurfaceControl), argThat(Rect::isEmpty));
+        verify(mTransaction).setFinalCrop(eq(mSurfaceControl),
+                argThat(rect -> rect.left == 20 && rect.top == 40 && rect.right == 30
+                        && rect.bottom == 50));
+    }
+
+    @Test
+    public void testApply_clipBeforeNoAnimationBounds() {
+        // Stack bounds is (0, 0, 10, 10) animation clip is (0, 0, 0, 0)
+        WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(mAnimation, null,
+                mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_BEFORE_ANIM,
+                true /* isAppAnimation */);
+        windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0);
+        verify(mTransaction).setWindowCrop(eq(mSurfaceControl),
+                argThat(rect -> rect.equals(mStackBounds)));
+    }
+
+    @Test
+    public void testApply_clipBeforeNoStackBounds() {
+        // Stack bounds is (0, 0, 0, 0) animation clip is (0, 0, 20, 20)
+        Rect windowCrop = new Rect(0, 0, 20, 20);
+        Animation a = createClipRectAnimation(windowCrop, windowCrop);
+        a.initialize(0, 0, 0, 0);
+        WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(a, null,
+                null, false /* canSkipFirstFrame */, STACK_CLIP_BEFORE_ANIM,
+                true /* isAppAnimation */);
+        windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0);
+        verify(mTransaction).setWindowCrop(eq(mSurfaceControl), argThat(Rect::isEmpty));
+    }
+
+    @Test
+    public void testApply_clipBeforeSmallerAnimationClip() {
+        // Stack bounds is (0, 0, 10, 10) animation clip is (0, 0, 5, 5)
+        Rect windowCrop = new Rect(0, 0, 5, 5);
+        Animation a = createClipRectAnimation(windowCrop, windowCrop);
+        WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(a, null,
+                mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_BEFORE_ANIM,
+                true /* isAppAnimation */);
+        windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0);
+        verify(mTransaction).setWindowCrop(eq(mSurfaceControl),
+                argThat(rect -> rect.equals(windowCrop)));
+    }
+
+    @Test
+    public void testApply_clipBeforeSmallerStackClip() {
+        // Stack bounds is (0, 0, 10, 10) animation clip is (0, 0, 20, 20)
+        Rect windowCrop = new Rect(0, 0, 20, 20);
+        Animation a = createClipRectAnimation(windowCrop, windowCrop);
+        WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(a, null,
+                mStackBounds, false /* canSkipFirstFrame */, STACK_CLIP_BEFORE_ANIM,
+                true /* isAppAnimation */);
+        windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0);
+        verify(mTransaction).setWindowCrop(eq(mSurfaceControl),
+                argThat(rect -> rect.equals(mStackBounds)));
+    }
+
+    private Animation createClipRectAnimation(Rect fromClip, Rect toClip) {
+        Animation a = new ClipRectAnimation(fromClip, toClip);
+        a.initialize(0, 0, 0, 0);
+        return a;
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java
new file mode 100644
index 0000000..513c1ec
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import org.junit.Test;
+
+import android.app.WindowConfiguration;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.DisplayInfo;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOW_CONFIG_APP_BOUNDS;
+import static android.app.WindowConfiguration.WINDOW_CONFIG_WINDOWING_MODE;
+import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test class to for {@link android.app.WindowConfiguration}.
+ *
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.wm.WindowConfigurationTests
+ */
+@SmallTest
+@FlakyTest(bugId = 74078662)
+@Presubmit
+@org.junit.runner.RunWith(AndroidJUnit4.class)
+public class WindowConfigurationTests extends WindowTestsBase {
+    private Rect mParentBounds;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mParentBounds = new Rect(10 /*left*/, 30 /*top*/, 80 /*right*/, 60 /*bottom*/);
+    }
+
+    /** Tests {@link android.app.WindowConfiguration#diff(WindowConfiguration, boolean)}. */
+    @Test
+    public void testDiff() {
+        final Configuration config1 = new Configuration();
+        final WindowConfiguration winConfig1 = config1.windowConfiguration;
+        final Configuration config2 = new Configuration();
+        final WindowConfiguration winConfig2 = config2.windowConfiguration;
+        final Configuration config3 = new Configuration();
+        final WindowConfiguration winConfig3 = config3.windowConfiguration;
+
+        winConfig1.setAppBounds(0, 1, 1, 0);
+        winConfig2.setAppBounds(1, 2, 2, 1);
+        winConfig3.setAppBounds(winConfig1.getAppBounds());
+
+
+        assertEquals(CONFIG_WINDOW_CONFIGURATION, config1.diff(config2));
+        assertEquals(0, config1.diffPublicOnly(config2));
+        assertEquals(WINDOW_CONFIG_APP_BOUNDS,
+                winConfig1.diff(winConfig2, false /* compareUndefined */));
+
+        winConfig2.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        assertEquals(WINDOW_CONFIG_APP_BOUNDS | WINDOW_CONFIG_WINDOWING_MODE,
+                winConfig1.diff(winConfig2, false /* compareUndefined */));
+
+        assertEquals(0, config1.diff(config3));
+        assertEquals(0, config1.diffPublicOnly(config3));
+        assertEquals(0, winConfig1.diff(winConfig3, false /* compareUndefined */));
+    }
+
+    /** Tests {@link android.app.WindowConfiguration#compareTo(WindowConfiguration)}. */
+    @Test
+    public void testConfigurationCompareTo() throws Exception {
+        final Configuration blankConfig = new Configuration();
+        final WindowConfiguration blankWinConfig = new WindowConfiguration();
+
+        final Configuration config1 = new Configuration();
+        final WindowConfiguration winConfig1 = config1.windowConfiguration;
+        winConfig1.setAppBounds(1, 2, 3, 4);
+
+        final Configuration config2 = new Configuration(config1);
+        final WindowConfiguration winConfig2 = config2.windowConfiguration;
+
+        assertEquals(config1.compareTo(config2), 0);
+        assertEquals(winConfig1.compareTo(winConfig2), 0);
+
+        // Different windowing mode
+        winConfig2.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        assertNotEquals(config1.compareTo(config2), 0);
+        assertNotEquals(winConfig1.compareTo(winConfig2), 0);
+        winConfig2.setWindowingMode(winConfig1.getWindowingMode());
+
+        // Different bounds
+        winConfig2.setAppBounds(0, 2, 3, 4);
+        assertNotEquals(config1.compareTo(config2), 0);
+        assertNotEquals(winConfig1.compareTo(winConfig2), 0);
+
+        // No bounds
+        assertEquals(config1.compareTo(blankConfig), -1);
+        assertEquals(winConfig1.compareTo(blankWinConfig), -1);
+
+        assertEquals(blankConfig.compareTo(config1), 1);
+        assertEquals(blankWinConfig.compareTo(winConfig1), 1);
+    }
+
+    @Test
+    public void testSetActivityType() throws Exception {
+        final WindowConfiguration config = new WindowConfiguration();
+        config.setActivityType(ACTIVITY_TYPE_HOME);
+        assertEquals(ACTIVITY_TYPE_HOME, config.getActivityType());
+
+        // Allowed to change from app process.
+        config.setActivityType(ACTIVITY_TYPE_STANDARD);
+        assertEquals(ACTIVITY_TYPE_STANDARD, config.getActivityType());
+    }
+
+    /** Ensures the configuration app bounds at the root level match the app dimensions. */
+    @Test
+    public void testAppBounds_RootConfigurationBounds() throws Exception {
+        final DisplayInfo info = mDisplayContent.getDisplayInfo();
+        info.appWidth = 1024;
+        info.appHeight = 768;
+
+        final Rect appBounds = sWm.computeNewConfiguration(
+                mDisplayContent.getDisplayId()).windowConfiguration.getAppBounds();
+        // The bounds should always be positioned in the top left.
+        assertEquals(appBounds.left, 0);
+        assertEquals(appBounds.top, 0);
+
+        // The bounds should equal the defined app width and height
+        assertEquals(appBounds.width(), info.appWidth);
+        assertEquals(appBounds.height(), info.appHeight);
+    }
+
+    /** Ensures that bounds are clipped to their parent. */
+    @Test
+    public void testAppBounds_BoundsClipping() throws Exception {
+        final Rect shiftedBounds = new Rect(mParentBounds);
+        shiftedBounds.offset(10, 10);
+        final Rect expectedBounds = new Rect(mParentBounds);
+        expectedBounds.intersect(shiftedBounds);
+        testStackBoundsConfiguration(WINDOWING_MODE_FULLSCREEN, mParentBounds, shiftedBounds,
+                expectedBounds);
+    }
+
+    /** Ensures that empty bounds are not propagated to the configuration. */
+    @Test
+    public void testAppBounds_EmptyBounds() throws Exception {
+        final Rect emptyBounds = new Rect();
+        testStackBoundsConfiguration(WINDOWING_MODE_FULLSCREEN, mParentBounds, emptyBounds,
+                null /*ExpectedBounds*/);
+    }
+
+    /** Ensures that bounds on freeform stacks are not clipped. */
+    @Test
+    public void testAppBounds_FreeFormBounds() throws Exception {
+        final Rect freeFormBounds = new Rect(mParentBounds);
+        freeFormBounds.offset(10, 10);
+        testStackBoundsConfiguration(WINDOWING_MODE_FREEFORM, mParentBounds, freeFormBounds,
+                freeFormBounds);
+    }
+
+    /** Ensures that fully contained bounds are not clipped. */
+    @Test
+    public void testAppBounds_ContainedBounds() throws Exception {
+        final Rect insetBounds = new Rect(mParentBounds);
+        insetBounds.inset(5, 5, 5, 5);
+        testStackBoundsConfiguration(
+                WINDOWING_MODE_FULLSCREEN, mParentBounds, insetBounds, insetBounds);
+    }
+
+    /** Ensures that full screen free form bounds are clipped */
+    @Test
+    public void testAppBounds_FullScreenFreeFormBounds() throws Exception {
+        final Rect fullScreenBounds = new Rect(0, 0, mDisplayInfo.logicalWidth,
+                mDisplayInfo.logicalHeight);
+        testStackBoundsConfiguration(WINDOWING_MODE_FULLSCREEN, mParentBounds, fullScreenBounds,
+                mParentBounds);
+    }
+
+    private void testStackBoundsConfiguration(int windowingMode, Rect parentBounds, Rect bounds,
+            Rect expectedConfigBounds) {
+        final StackWindowController stackController = createStackControllerOnStackOnDisplay(
+                        windowingMode, ACTIVITY_TYPE_STANDARD, mDisplayContent);
+
+        final Configuration parentConfig = mDisplayContent.getConfiguration();
+        parentConfig.windowConfiguration.setAppBounds(parentBounds);
+
+        final Configuration config = new Configuration();
+        final WindowConfiguration winConfig = config.windowConfiguration;
+        stackController.adjustConfigurationForBounds(bounds, null /*insetBounds*/,
+                new Rect() /*nonDecorBounds*/, new Rect() /*stableBounds*/, false /*overrideWidth*/,
+                false /*overrideHeight*/, mDisplayInfo.logicalDensityDpi, config, parentConfig,
+                windowingMode);
+        // Assert that both expected and actual are null or are equal to each other
+
+        assertEquals(expectedConfigBounds, winConfig.getAppBounds());
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java
new file mode 100644
index 0000000..502cb6e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import android.app.WindowConfiguration;
+import android.content.res.Configuration;
+import android.support.test.filters.FlakyTest;
+import org.junit.Test;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.content.res.Configuration.EMPTY;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test class for {@link WindowContainerController}.
+ *
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.wm.WindowContainerControllerTests
+ */
+@SmallTest
+@Presubmit
+@FlakyTest(bugId = 74078662)
+@org.junit.runner.RunWith(AndroidJUnit4.class)
+public class WindowContainerControllerTests extends WindowTestsBase {
+
+    @Test
+    public void testCreation() throws Exception {
+        final WindowContainerController controller = new WindowContainerController(null, sWm);
+        final WindowContainer container = new WindowContainer(sWm);
+
+        container.setController(controller);
+        assertEquals(controller, container.getController());
+        assertEquals(controller.mContainer, container);
+    }
+
+    @Test
+    public void testSetContainer() throws Exception {
+        final WindowContainerController controller = new WindowContainerController(null, sWm);
+        final WindowContainer container = new WindowContainer(sWm);
+
+        controller.setContainer(container);
+        assertEquals(controller.mContainer, container);
+
+        // Assert we can't change the container to another one once set
+        boolean gotException = false;
+        try {
+            controller.setContainer(new WindowContainer(sWm));
+        } catch (IllegalArgumentException e) {
+            gotException = true;
+        }
+        assertTrue(gotException);
+
+        // Assert that we can set the container to null.
+        controller.setContainer(null);
+        assertNull(controller.mContainer);
+    }
+
+    @Test
+    public void testRemoveContainer() throws Exception {
+        final WindowContainerController controller = new WindowContainerController(null, sWm);
+        final WindowContainer container = new WindowContainer(sWm);
+
+        controller.setContainer(container);
+        assertEquals(controller.mContainer, container);
+
+        controller.removeContainer();
+        assertNull(controller.mContainer);
+    }
+
+    @Test
+    public void testOnOverrideConfigurationChanged() throws Exception {
+        final WindowContainerController controller = new WindowContainerController(null, sWm);
+        final WindowContainer container = new WindowContainer(sWm);
+
+        controller.setContainer(container);
+        assertEquals(controller.mContainer, container);
+        assertEquals(EMPTY, container.getOverrideConfiguration());
+
+        final Configuration config = new Configuration();
+        config.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        config.windowConfiguration.setAppBounds(10, 10, 10, 10);
+
+        // Assert that the config change through the controller is propagated to the container.
+        controller.onOverrideConfigurationChanged(config);
+        assertEquals(config, container.getOverrideConfiguration());
+
+        // Assert the container configuration isn't changed after removal from the controller.
+        controller.removeContainer();
+        controller.onOverrideConfigurationChanged(EMPTY);
+        assertEquals(config, container.getOverrideConfiguration());
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
new file mode 100644
index 0000000..6c7830e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
@@ -0,0 +1,872 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import android.support.test.filters.FlakyTest;
+import android.view.SurfaceControl;
+import android.view.SurfaceSession;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import java.util.Comparator;
+
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+
+import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
+import static com.android.server.wm.WindowContainer.POSITION_TOP;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyFloat;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+/**
+ * Test class for {@link WindowContainer}.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:com.android.server.wm.WindowContainerTests
+ */
+@SmallTest
+@Presubmit
+@FlakyTest(bugId = 74078662)
+@RunWith(AndroidJUnit4.class)
+public class WindowContainerTests extends WindowTestsBase {
+
+    @Test
+    public void testCreation() throws Exception {
+        final TestWindowContainer w = new TestWindowContainerBuilder().setLayer(0).build();
+        assertNull("window must have no parent", w.getParentWindow());
+        assertEquals("window must have no children", 0, w.getChildrenCount());
+    }
+
+    @Test
+    public void testAdd() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.setLayer(0).build();
+
+        final TestWindowContainer layer1 = root.addChildWindow(builder.setLayer(1));
+        final TestWindowContainer secondLayer1 = root.addChildWindow(builder.setLayer(1));
+        final TestWindowContainer layer2 = root.addChildWindow(builder.setLayer(2));
+        final TestWindowContainer layerNeg1 = root.addChildWindow(builder.setLayer(-1));
+        final TestWindowContainer layerNeg2 = root.addChildWindow(builder.setLayer(-2));
+        final TestWindowContainer secondLayerNeg1 = root.addChildWindow(builder.setLayer(-1));
+        final TestWindowContainer layer0 = root.addChildWindow(builder.setLayer(0));
+
+        assertEquals(7, root.getChildrenCount());
+
+        assertEquals(root, layer1.getParentWindow());
+        assertEquals(root, secondLayer1.getParentWindow());
+        assertEquals(root, layer2.getParentWindow());
+        assertEquals(root, layerNeg1.getParentWindow());
+        assertEquals(root, layerNeg2.getParentWindow());
+        assertEquals(root, secondLayerNeg1.getParentWindow());
+        assertEquals(root, layer0.getParentWindow());
+
+        assertEquals(layerNeg2, root.getChildAt(0));
+        assertEquals(secondLayerNeg1, root.getChildAt(1));
+        assertEquals(layerNeg1, root.getChildAt(2));
+        assertEquals(layer0, root.getChildAt(3));
+        assertEquals(layer1, root.getChildAt(4));
+        assertEquals(secondLayer1, root.getChildAt(5));
+        assertEquals(layer2, root.getChildAt(6));
+
+        assertTrue(layer1.mOnParentSetCalled);
+        assertTrue(secondLayer1.mOnParentSetCalled);
+        assertTrue(layer2.mOnParentSetCalled);
+        assertTrue(layerNeg1.mOnParentSetCalled);
+        assertTrue(layerNeg2.mOnParentSetCalled);
+        assertTrue(secondLayerNeg1.mOnParentSetCalled);
+        assertTrue(layer0.mOnParentSetCalled);
+    }
+
+    @Test
+    public void testAddChildSetsSurfacePosition() throws Exception {
+        MockSurfaceBuildingContainer top = new MockSurfaceBuildingContainer();
+
+        final SurfaceControl.Transaction transaction = mock(SurfaceControl.Transaction.class);
+        sWm.mTransactionFactory = () -> transaction;
+
+        WindowContainer child = new WindowContainer(sWm);
+        child.setBounds(1, 1, 10, 10);
+
+        verify(transaction, never()).setPosition(any(), anyFloat(), anyFloat());
+        top.addChild(child, 0);
+        verify(transaction, times(1)).setPosition(any(), eq(1.f), eq(1.f));
+    }
+
+    @Test
+    public void testAdd_AlreadyHasParent() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.setLayer(0).build();
+
+        final TestWindowContainer child1 = root.addChildWindow();
+        final TestWindowContainer child2 = root.addChildWindow();
+
+        boolean gotException = false;
+        try {
+            child1.addChildWindow(child2);
+        } catch (IllegalArgumentException e) {
+            gotException = true;
+        }
+        assertTrue(gotException);
+
+        gotException = false;
+        try {
+            root.addChildWindow(child2);
+        } catch (IllegalArgumentException e) {
+            gotException = true;
+        }
+        assertTrue(gotException);
+    }
+
+    @Test
+    public void testHasChild() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.setLayer(0).build();
+
+        final TestWindowContainer child1 = root.addChildWindow();
+        final TestWindowContainer child2 = root.addChildWindow();
+        final TestWindowContainer child11 = child1.addChildWindow();
+        final TestWindowContainer child12 = child1.addChildWindow();
+        final TestWindowContainer child21 = child2.addChildWindow();
+
+        assertEquals(2, root.getChildrenCount());
+        assertEquals(2, child1.getChildrenCount());
+        assertEquals(1, child2.getChildrenCount());
+
+        assertTrue(root.hasChild(child1));
+        assertTrue(root.hasChild(child2));
+        assertTrue(root.hasChild(child11));
+        assertTrue(root.hasChild(child12));
+        assertTrue(root.hasChild(child21));
+
+        assertTrue(child1.hasChild(child11));
+        assertTrue(child1.hasChild(child12));
+        assertFalse(child1.hasChild(child21));
+
+        assertTrue(child2.hasChild(child21));
+        assertFalse(child2.hasChild(child11));
+        assertFalse(child2.hasChild(child12));
+    }
+
+    @Test
+    public void testRemoveImmediately() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.setLayer(0).build();
+
+        final TestWindowContainer child1 = root.addChildWindow();
+        final TestWindowContainer child2 = root.addChildWindow();
+        final TestWindowContainer child11 = child1.addChildWindow();
+        final TestWindowContainer child12 = child1.addChildWindow();
+        final TestWindowContainer child21 = child2.addChildWindow();
+
+        assertNotNull(child12.getParentWindow());
+        child12.removeImmediately();
+        assertNull(child12.getParentWindow());
+        assertEquals(1, child1.getChildrenCount());
+        assertFalse(child1.hasChild(child12));
+        assertFalse(root.hasChild(child12));
+
+        assertTrue(root.hasChild(child2));
+        assertNotNull(child2.getParentWindow());
+        child2.removeImmediately();
+        assertNull(child2.getParentWindow());
+        assertNull(child21.getParentWindow());
+        assertEquals(0, child2.getChildrenCount());
+        assertEquals(1, root.getChildrenCount());
+        assertFalse(root.hasChild(child2));
+        assertFalse(root.hasChild(child21));
+
+        assertTrue(root.hasChild(child1));
+        assertTrue(root.hasChild(child11));
+
+        root.removeImmediately();
+        assertEquals(0, root.getChildrenCount());
+    }
+
+    @Test
+    public void testRemoveImmediately_WithController() throws Exception {
+        final WindowContainer container = new WindowContainer(sWm);
+        final WindowContainerController controller = new WindowContainerController(null, sWm);
+
+        container.setController(controller);
+        assertEquals(controller, container.getController());
+        assertEquals(container, controller.mContainer);
+
+        container.removeImmediately();
+        assertNull(container.getController());
+        assertNull(controller.mContainer);
+    }
+
+    @Test
+    public void testSetController() throws Exception {
+        final WindowContainerController controller = new WindowContainerController(null, sWm);
+        final WindowContainer container = new WindowContainer(sWm);
+
+        container.setController(controller);
+        assertEquals(controller, container.getController());
+        assertEquals(container, controller.mContainer);
+
+        // Assert we can't change the controller to another one once set
+        boolean gotException = false;
+        try {
+            container.setController(new WindowContainerController(null, sWm));
+        } catch (IllegalArgumentException e) {
+            gotException = true;
+        }
+        assertTrue(gotException);
+
+        // Assert that we can set the controller to null.
+        container.setController(null);
+        assertNull(container.getController());
+        assertNull(controller.mContainer);
+    }
+
+    @Test
+    public void testPositionChildAt() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.setLayer(0).build();
+
+        final TestWindowContainer child1 = root.addChildWindow();
+        final TestWindowContainer child2 = root.addChildWindow();
+        final TestWindowContainer child3 = root.addChildWindow();
+
+        // Test position at top.
+        root.positionChildAt(POSITION_TOP, child1, false /* includingParents */);
+        assertEquals(child1, root.getChildAt(root.getChildrenCount() - 1));
+
+        // Test position at bottom.
+        root.positionChildAt(POSITION_BOTTOM, child1, false /* includingParents */);
+        assertEquals(child1, root.getChildAt(0));
+
+        // Test position in the middle.
+        root.positionChildAt(1, child3, false /* includingParents */);
+        assertEquals(child1, root.getChildAt(0));
+        assertEquals(child3, root.getChildAt(1));
+        assertEquals(child2, root.getChildAt(2));
+    }
+
+    @Test
+    public void testPositionChildAtIncludeParents() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.setLayer(0).build();
+
+        final TestWindowContainer child1 = root.addChildWindow();
+        final TestWindowContainer child2 = root.addChildWindow();
+        final TestWindowContainer child11 = child1.addChildWindow();
+        final TestWindowContainer child12 = child1.addChildWindow();
+        final TestWindowContainer child13 = child1.addChildWindow();
+        final TestWindowContainer child21 = child2.addChildWindow();
+        final TestWindowContainer child22 = child2.addChildWindow();
+        final TestWindowContainer child23 = child2.addChildWindow();
+
+        // Test moving to top.
+        child1.positionChildAt(POSITION_TOP, child11, true /* includingParents */);
+        assertEquals(child12, child1.getChildAt(0));
+        assertEquals(child13, child1.getChildAt(1));
+        assertEquals(child11, child1.getChildAt(2));
+        assertEquals(child2, root.getChildAt(0));
+        assertEquals(child1, root.getChildAt(1));
+
+        // Test moving to bottom.
+        child1.positionChildAt(POSITION_BOTTOM, child11, true /* includingParents */);
+        assertEquals(child11, child1.getChildAt(0));
+        assertEquals(child12, child1.getChildAt(1));
+        assertEquals(child13, child1.getChildAt(2));
+        assertEquals(child1, root.getChildAt(0));
+        assertEquals(child2, root.getChildAt(1));
+
+        // Test moving to middle, includeParents shouldn't do anything.
+        child2.positionChildAt(1, child21, true /* includingParents */);
+        assertEquals(child11, child1.getChildAt(0));
+        assertEquals(child12, child1.getChildAt(1));
+        assertEquals(child13, child1.getChildAt(2));
+        assertEquals(child22, child2.getChildAt(0));
+        assertEquals(child21, child2.getChildAt(1));
+        assertEquals(child23, child2.getChildAt(2));
+        assertEquals(child1, root.getChildAt(0));
+        assertEquals(child2, root.getChildAt(1));
+    }
+
+    @Test
+    public void testPositionChildAtInvalid() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.setLayer(0).build();
+
+        final TestWindowContainer child1 = root.addChildWindow();
+        final TestWindowContainer child2 = root.addChildWindow();
+
+        boolean gotException = false;
+        try {
+            // Check response to negative position.
+            root.positionChildAt(-1, child1, false /* includingParents */);
+        } catch (IllegalArgumentException e) {
+            gotException = true;
+        }
+        assertTrue(gotException);
+
+        gotException = false;
+        try {
+            // Check response to position that's bigger than child number.
+            root.positionChildAt(3, child1, false /* includingParents */);
+        } catch (IllegalArgumentException e) {
+            gotException = true;
+        }
+        assertTrue(gotException);
+    }
+
+    @Test
+    public void testIsAnimating() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.setLayer(0).build();
+
+        final TestWindowContainer child1 = root.addChildWindow(builder.setIsAnimating(true));
+        final TestWindowContainer child2 = root.addChildWindow();
+        final TestWindowContainer child11 = child1.addChildWindow();
+        final TestWindowContainer child12 = child1.addChildWindow(builder.setIsAnimating(true));
+        final TestWindowContainer child21 = child2.addChildWindow();
+
+        assertFalse(root.isAnimating());
+        assertTrue(child1.isAnimating());
+        assertTrue(child11.isAnimating());
+        assertTrue(child12.isAnimating());
+        assertFalse(child2.isAnimating());
+        assertFalse(child21.isAnimating());
+
+        assertTrue(root.isSelfOrChildAnimating());
+        assertTrue(child1.isSelfOrChildAnimating());
+        assertFalse(child11.isSelfOrChildAnimating());
+        assertTrue(child12.isSelfOrChildAnimating());
+        assertFalse(child2.isSelfOrChildAnimating());
+        assertFalse(child21.isSelfOrChildAnimating());
+    }
+
+    @Test
+    public void testIsVisible() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.setLayer(0).build();
+
+        final TestWindowContainer child1 = root.addChildWindow(builder.setIsVisible(true));
+        final TestWindowContainer child2 = root.addChildWindow();
+        final TestWindowContainer child11 = child1.addChildWindow();
+        final TestWindowContainer child12 = child1.addChildWindow(builder.setIsVisible(true));
+        final TestWindowContainer child21 = child2.addChildWindow();
+
+        assertFalse(root.isVisible());
+        assertTrue(child1.isVisible());
+        assertFalse(child11.isVisible());
+        assertTrue(child12.isVisible());
+        assertFalse(child2.isVisible());
+        assertFalse(child21.isVisible());
+    }
+
+    @Test
+    public void testOverrideConfigurationAncestorNotification() {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer grandparent = builder.setLayer(0).build();
+
+        final TestWindowContainer parent = grandparent.addChildWindow();
+        final TestWindowContainer child = parent.addChildWindow();
+        child.onOverrideConfigurationChanged(new Configuration());
+
+        assertTrue(grandparent.mOnDescendantOverrideCalled);
+    }
+
+    @Test
+    public void testRemoveChild() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.setLayer(0).build();
+        final TestWindowContainer child1 = root.addChildWindow();
+        final TestWindowContainer child2 = root.addChildWindow();
+        final TestWindowContainer child11 = child1.addChildWindow();
+        final TestWindowContainer child21 = child2.addChildWindow();
+
+        assertTrue(root.hasChild(child2));
+        assertTrue(root.hasChild(child21));
+        root.removeChild(child2);
+        assertFalse(root.hasChild(child2));
+        assertFalse(root.hasChild(child21));
+        assertNull(child2.getParentWindow());
+
+        boolean gotException = false;
+        assertTrue(root.hasChild(child11));
+        try {
+            // Can only detach our direct children.
+            root.removeChild(child11);
+        } catch (IllegalArgumentException e) {
+            gotException = true;
+        }
+        assertTrue(gotException);
+    }
+
+    @Test
+    public void testGetOrientation_childSpecified() throws Exception {
+        testGetOrientation_childSpecifiedConfig(false, SCREEN_ORIENTATION_LANDSCAPE,
+            SCREEN_ORIENTATION_LANDSCAPE);
+        testGetOrientation_childSpecifiedConfig(false, SCREEN_ORIENTATION_UNSET,
+            SCREEN_ORIENTATION_UNSPECIFIED);
+    }
+
+    private void testGetOrientation_childSpecifiedConfig(boolean childVisible, int childOrientation,
+        int expectedOrientation) {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.setLayer(0).build();
+        root.setFillsParent(true);
+
+        builder.setIsVisible(childVisible);
+
+        if (childOrientation != SCREEN_ORIENTATION_UNSET) {
+            builder.setOrientation(childOrientation);
+        }
+
+        final TestWindowContainer child1 = root.addChildWindow(builder);
+        child1.setFillsParent(true);
+
+        assertEquals(expectedOrientation, root.getOrientation());
+    }
+
+    @Test
+    public void testGetOrientation_Unset() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.setLayer(0).setIsVisible(true).build();
+        // Unspecified well because we didn't specify anything...
+        assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, root.getOrientation());
+    }
+
+    @Test
+    public void testGetOrientation_InvisibleParentUnsetVisibleChildren() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.setLayer(0).setIsVisible(true).build();
+
+        builder.setIsVisible(false).setLayer(-1);
+        final TestWindowContainer invisible = root.addChildWindow(builder);
+        builder.setIsVisible(true).setLayer(-2);
+        final TestWindowContainer invisibleChild1VisibleAndSet = invisible.addChildWindow(builder);
+        invisibleChild1VisibleAndSet.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+        // Landscape well because the container is visible and that is what we set on it above.
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, invisibleChild1VisibleAndSet.getOrientation());
+        // Landscape because even though the container isn't visible it has a child that is
+        // specifying it can influence the orientation by being visible.
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, invisible.getOrientation());
+        // Landscape because the grandchild is visible and therefore can participate.
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, root.getOrientation());
+
+        builder.setIsVisible(true).setLayer(-3);
+        final TestWindowContainer visibleUnset = root.addChildWindow(builder);
+        visibleUnset.setOrientation(SCREEN_ORIENTATION_UNSET);
+        assertEquals(SCREEN_ORIENTATION_UNSET, visibleUnset.getOrientation());
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, root.getOrientation());
+
+    }
+
+    @Test
+    public void testGetOrientation_setBehind() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.setLayer(0).setIsVisible(true).build();
+
+        builder.setIsVisible(true).setLayer(-1);
+        final TestWindowContainer visibleUnset = root.addChildWindow(builder);
+        visibleUnset.setOrientation(SCREEN_ORIENTATION_UNSET);
+
+        builder.setIsVisible(true).setLayer(-2);
+        final TestWindowContainer visibleUnsetChild1VisibleSetBehind =
+                visibleUnset.addChildWindow(builder);
+        visibleUnsetChild1VisibleSetBehind.setOrientation(SCREEN_ORIENTATION_BEHIND);
+        // Setting to visible behind will be used by the parents if there isn't another other
+        // container behind this one that has an orientation set.
+        assertEquals(SCREEN_ORIENTATION_BEHIND,
+                visibleUnsetChild1VisibleSetBehind.getOrientation());
+        assertEquals(SCREEN_ORIENTATION_BEHIND, visibleUnset.getOrientation());
+        assertEquals(SCREEN_ORIENTATION_BEHIND, root.getOrientation());
+    }
+
+    @Test
+    public void testGetOrientation_fillsParent() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.setLayer(0).setIsVisible(true).build();
+
+        builder.setIsVisible(true).setLayer(-1);
+        final TestWindowContainer visibleUnset = root.addChildWindow(builder);
+        visibleUnset.setOrientation(SCREEN_ORIENTATION_BEHIND);
+
+        builder.setLayer(1).setIsVisible(true);
+        final TestWindowContainer visibleUnspecifiedRootChild = root.addChildWindow(builder);
+        visibleUnspecifiedRootChild.setFillsParent(false);
+        visibleUnspecifiedRootChild.setOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
+        // Unset because the child doesn't fill the parent. May as well be invisible...
+        assertEquals(SCREEN_ORIENTATION_UNSET, visibleUnspecifiedRootChild.getOrientation());
+        // The parent uses whatever orientation is set behind this container since it doesn't fill
+        // the parent.
+        assertEquals(SCREEN_ORIENTATION_BEHIND, root.getOrientation());
+
+        // Test case of child filling its parent, but its parent isn't filling its own parent.
+        builder.setLayer(2).setIsVisible(true);
+        final TestWindowContainer visibleUnspecifiedRootChildChildFillsParent =
+                visibleUnspecifiedRootChild.addChildWindow(builder);
+        visibleUnspecifiedRootChildChildFillsParent.setOrientation(
+                SCREEN_ORIENTATION_PORTRAIT);
+        assertEquals(SCREEN_ORIENTATION_PORTRAIT,
+                visibleUnspecifiedRootChildChildFillsParent.getOrientation());
+        assertEquals(SCREEN_ORIENTATION_UNSET, visibleUnspecifiedRootChild.getOrientation());
+        assertEquals(SCREEN_ORIENTATION_BEHIND, root.getOrientation());
+
+
+        visibleUnspecifiedRootChild.setFillsParent(true);
+        assertEquals(SCREEN_ORIENTATION_PORTRAIT, visibleUnspecifiedRootChild.getOrientation());
+        assertEquals(SCREEN_ORIENTATION_PORTRAIT, root.getOrientation());
+    }
+
+    @Test
+    public void testCompareTo() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.setLayer(0).build();
+
+        final TestWindowContainer child1 = root.addChildWindow();
+        final TestWindowContainer child11 = child1.addChildWindow();
+        final TestWindowContainer child12 = child1.addChildWindow();
+
+        final TestWindowContainer child2 = root.addChildWindow();
+        final TestWindowContainer child21 = child2.addChildWindow();
+        final TestWindowContainer child22 = child2.addChildWindow();
+        final TestWindowContainer child23 = child2.addChildWindow();
+        final TestWindowContainer child221 = child22.addChildWindow();
+        final TestWindowContainer child222 = child22.addChildWindow();
+        final TestWindowContainer child223 = child22.addChildWindow();
+        final TestWindowContainer child2221 = child222.addChildWindow();
+        final TestWindowContainer child2222 = child222.addChildWindow();
+        final TestWindowContainer child2223 = child222.addChildWindow();
+
+        final TestWindowContainer root2 = builder.setLayer(0).build();
+
+        assertEquals(0, root.compareTo(root));
+        assertEquals(-1, child1.compareTo(child2));
+        assertEquals(1, child2.compareTo(child1));
+
+        boolean inTheSameTree = true;
+        try {
+            root.compareTo(root2);
+        } catch (IllegalArgumentException e) {
+            inTheSameTree = false;
+        }
+        assertFalse(inTheSameTree);
+
+        assertEquals(-1, child1.compareTo(child11));
+        assertEquals(1, child21.compareTo(root));
+        assertEquals(1, child21.compareTo(child12));
+        assertEquals(-1, child11.compareTo(child2));
+        assertEquals(1, child2221.compareTo(child11));
+        assertEquals(-1, child2222.compareTo(child223));
+        assertEquals(1, child2223.compareTo(child21));
+    }
+
+    @Test
+    public void testPrefixOrderIndex() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.build();
+
+        final TestWindowContainer child1 = root.addChildWindow();
+
+        final TestWindowContainer child11 = child1.addChildWindow();
+        final TestWindowContainer child12 = child1.addChildWindow();
+
+        final TestWindowContainer child2 = root.addChildWindow();
+
+        final TestWindowContainer child21 = child2.addChildWindow();
+        final TestWindowContainer child22 = child2.addChildWindow();
+
+        final TestWindowContainer child221 = child22.addChildWindow();
+        final TestWindowContainer child222 = child22.addChildWindow();
+        final TestWindowContainer child223 = child22.addChildWindow();
+
+        final TestWindowContainer child23 = child2.addChildWindow();
+
+        assertEquals(0, root.getPrefixOrderIndex());
+        assertEquals(1, child1.getPrefixOrderIndex());
+        assertEquals(2, child11.getPrefixOrderIndex());
+        assertEquals(3, child12.getPrefixOrderIndex());
+        assertEquals(4, child2.getPrefixOrderIndex());
+        assertEquals(5, child21.getPrefixOrderIndex());
+        assertEquals(6, child22.getPrefixOrderIndex());
+        assertEquals(7, child221.getPrefixOrderIndex());
+        assertEquals(8, child222.getPrefixOrderIndex());
+        assertEquals(9, child223.getPrefixOrderIndex());
+        assertEquals(10, child23.getPrefixOrderIndex());
+    }
+
+    @Test
+    public void testPrefixOrder_addEntireSubtree() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.build();
+        final TestWindowContainer subtree = builder.build();
+        final TestWindowContainer subtree2 = builder.build();
+
+        final TestWindowContainer child1 = subtree.addChildWindow();
+        final TestWindowContainer child11 = child1.addChildWindow();
+        final TestWindowContainer child2 = subtree2.addChildWindow();
+        final TestWindowContainer child3 = subtree2.addChildWindow();
+        subtree.addChild(subtree2, 1);
+        root.addChild(subtree, 0);
+
+        assertEquals(0, root.getPrefixOrderIndex());
+        assertEquals(1, subtree.getPrefixOrderIndex());
+        assertEquals(2, child1.getPrefixOrderIndex());
+        assertEquals(3, child11.getPrefixOrderIndex());
+        assertEquals(4, subtree2.getPrefixOrderIndex());
+        assertEquals(5, child2.getPrefixOrderIndex());
+        assertEquals(6, child3.getPrefixOrderIndex());
+    }
+
+    @Test
+    public void testPrefixOrder_remove() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.build();
+
+        final TestWindowContainer child1 = root.addChildWindow();
+
+        final TestWindowContainer child11 = child1.addChildWindow();
+        final TestWindowContainer child12 = child1.addChildWindow();
+
+        final TestWindowContainer child2 = root.addChildWindow();
+
+        assertEquals(0, root.getPrefixOrderIndex());
+        assertEquals(1, child1.getPrefixOrderIndex());
+        assertEquals(2, child11.getPrefixOrderIndex());
+        assertEquals(3, child12.getPrefixOrderIndex());
+        assertEquals(4, child2.getPrefixOrderIndex());
+
+        root.removeChild(child1);
+
+        assertEquals(1, child2.getPrefixOrderIndex());
+    }
+
+    /**
+     * Ensure children of a {@link WindowContainer} do not have
+     * {@link WindowContainer#onParentResize()} called when {@link WindowContainer#onParentResize()}
+     * is invoked with overridden bounds.
+     */
+    @Test
+    public void testOnParentResizePropagation() throws Exception {
+        final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+        final TestWindowContainer root = builder.build();
+
+        final TestWindowContainer child = root.addChildWindow();
+        child.setBounds(new Rect(1,1,2,2));
+
+        final TestWindowContainer grandChild = mock(TestWindowContainer.class);
+
+        child.addChildWindow(grandChild);
+        root.onResize();
+
+        // Make sure the child does not propagate resize through onParentResize when bounds are set.
+        verify(grandChild, never()).onParentResize();
+
+        child.removeChild(grandChild);
+
+        child.setBounds(null);
+        child.addChildWindow(grandChild);
+        root.onResize();
+
+        // Make sure the child propagates resize through onParentResize when no bounds set.
+        verify(grandChild, times(1)).onParentResize();
+    }
+
+    /* Used so we can gain access to some protected members of the {@link WindowContainer} class */
+    private class TestWindowContainer extends WindowContainer<TestWindowContainer> {
+        private final int mLayer;
+        private boolean mIsAnimating;
+        private boolean mIsVisible;
+        private boolean mFillsParent;
+        private Integer mOrientation;
+
+        private boolean mOnParentSetCalled;
+        private boolean mOnDescendantOverrideCalled;
+
+        /**
+         * Compares 2 window layers and returns -1 if the first is lesser than the second in terms
+         * of z-order and 1 otherwise.
+         */
+        private final Comparator<TestWindowContainer> mWindowSubLayerComparator = (w1, w2) -> {
+            final int layer1 = w1.mLayer;
+            final int layer2 = w2.mLayer;
+            if (layer1 < layer2 || (layer1 == layer2 && layer2 < 0 )) {
+                // We insert the child window into the list ordered by the mLayer. For same layers,
+                // the negative one should go below others; the positive one should go above others.
+                return -1;
+            }
+            return 1;
+        };
+
+        TestWindowContainer(int layer, boolean isAnimating, boolean isVisible,
+            Integer orientation) {
+            super(sWm);
+            mLayer = layer;
+            mIsAnimating = isAnimating;
+            mIsVisible = isVisible;
+            mFillsParent = true;
+            mOrientation = orientation;
+        }
+
+        TestWindowContainer getParentWindow() {
+            return (TestWindowContainer) getParent();
+        }
+
+        int getChildrenCount() {
+            return mChildren.size();
+        }
+
+        TestWindowContainer addChildWindow(TestWindowContainer child) {
+            addChild(child, mWindowSubLayerComparator);
+            return child;
+        }
+
+        TestWindowContainer addChildWindow(TestWindowContainerBuilder childBuilder) {
+            TestWindowContainer child = childBuilder.build();
+            addChild(child, mWindowSubLayerComparator);
+            return child;
+        }
+
+        TestWindowContainer addChildWindow() {
+            return addChildWindow(new TestWindowContainerBuilder().setLayer(1));
+        }
+
+        @Override
+        void onParentSet() {
+            mOnParentSetCalled = true;
+        }
+
+        @Override
+        void onDescendantOverrideConfigurationChanged() {
+            mOnDescendantOverrideCalled = true;
+            super.onDescendantOverrideConfigurationChanged();
+        }
+
+        @Override
+        boolean isSelfAnimating() {
+            return mIsAnimating;
+        }
+
+        @Override
+        boolean isVisible() {
+            return mIsVisible;
+        }
+
+        @Override
+        int getOrientation(int candidate) {
+            return mOrientation != null ? mOrientation : super.getOrientation(candidate);
+        }
+
+        @Override
+        int getOrientation() {
+            return getOrientation(super.mOrientation);
+        }
+
+        @Override
+        boolean fillsParent() {
+            return mFillsParent;
+        }
+
+        void setFillsParent(boolean fillsParent) {
+            mFillsParent = fillsParent;
+        }
+    }
+
+    private class TestWindowContainerBuilder {
+        private int mLayer;
+        private boolean mIsAnimating;
+        private boolean mIsVisible;
+        private Integer mOrientation;
+
+        public TestWindowContainerBuilder() {
+            reset();
+        }
+
+        TestWindowContainerBuilder setLayer(int layer) {
+            mLayer = layer;
+            return this;
+        }
+
+        TestWindowContainerBuilder setIsAnimating(boolean isAnimating) {
+            mIsAnimating = isAnimating;
+            return this;
+        }
+
+        TestWindowContainerBuilder setIsVisible(boolean isVisible) {
+            mIsVisible = isVisible;
+            return this;
+        }
+
+        TestWindowContainerBuilder setOrientation(int orientation) {
+            mOrientation = orientation;
+            return this;
+        }
+
+        TestWindowContainerBuilder reset() {
+            mLayer = 0;
+            mIsAnimating = false;
+            mIsVisible = false;
+            mOrientation = null;
+            return this;
+        }
+
+        TestWindowContainer build() {
+            return new TestWindowContainer(mLayer, mIsAnimating, mIsVisible, mOrientation);
+        }
+    }
+
+    private class MockSurfaceBuildingContainer extends WindowContainer<WindowContainer> {
+        final SurfaceSession mSession = new SurfaceSession();
+
+        MockSurfaceBuildingContainer() {
+            super(sWm);
+        }
+
+        class MockSurfaceBuilder extends SurfaceControl.Builder {
+            MockSurfaceBuilder(SurfaceSession ss) {
+                super(ss);
+            }
+
+            @Override
+            public SurfaceControl build() {
+                return mock(SurfaceControl.class);
+            }
+        }
+
+        @Override
+        SurfaceControl.Builder makeChildSurface(WindowContainer child) {
+            return new MockSurfaceBuilder(mSession);
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTraversalTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTraversalTests.java
new file mode 100644
index 0000000..e076399
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTraversalTests.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Matchers.eq;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.mockito.Mock;
+
+import java.util.function.Consumer;
+
+/**
+ * Tests for {@link WindowContainer#forAllWindows} and various implementations.
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class WindowContainerTraversalTests extends WindowTestsBase {
+
+    @Test
+    public void testDockedDividerPosition() throws Exception {
+        final WindowState splitScreenWindow = createWindowOnStack(null,
+                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION,
+                mDisplayContent, "splitScreenWindow");
+        final WindowState splitScreenSecondaryWindow = createWindowOnStack(null,
+                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
+                TYPE_BASE_APPLICATION, mDisplayContent, "splitScreenSecondaryWindow");
+
+        sWm.mInputMethodTarget = splitScreenWindow;
+
+        Consumer<WindowState> c = mock(Consumer.class);
+        mDisplayContent.forAllWindows(c, false);
+
+        verify(c).accept(eq(mDockedDividerWindow));
+        verify(c).accept(eq(mImeWindow));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
new file mode 100644
index 0000000..5a56332
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -0,0 +1,474 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.app.ActivityManager.TaskDescription;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.DisplayInfo;
+import android.view.Gravity;
+import android.view.IWindow;
+import android.view.WindowManager;
+
+import static android.view.DisplayCutout.fromBoundingRect;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.FILL_PARENT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.android.server.wm.utils.WmDisplayCutout;
+
+/**
+ * Tests for the {@link WindowState#computeFrameLw} method and other window frame machinery.
+ *
+ * Build/Install/Run: bit FrameworksServicesTests:com.android.server.wm.WindowFrameTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class WindowFrameTests extends WindowTestsBase {
+
+    private WindowToken mWindowToken;
+    private final IWindow mIWindow = new TestIWindow();
+
+    class WindowStateWithTask extends WindowState {
+        final Task mTask;
+        boolean mDockedResizingForTest = false;
+        WindowStateWithTask(WindowManager.LayoutParams attrs, Task t) {
+            super(sWm, null, mIWindow, mWindowToken, null, 0, 0, attrs, 0, 0,
+                    false /* ownerCanAddInternalSystemWindow */);
+            mTask = t;
+        }
+
+        @Override
+        Task getTask() {
+            return mTask;
+        }
+
+        @Override
+        boolean isDockedResizing() {
+            return mDockedResizingForTest;
+        }
+    };
+
+    class TaskWithBounds extends Task {
+        final Rect mBounds;
+        final Rect mInsetBounds = new Rect();
+        boolean mFullscreenForTest = true;
+        TaskWithBounds(Rect bounds) {
+            super(0, mStubStack, 0, sWm, 0, false, new TaskDescription(), null);
+            mBounds = bounds;
+            setBounds(bounds);
+        }
+
+        @Override
+        public Rect getBounds() {
+            return mBounds;
+        }
+
+        @Override
+        public void getBounds(Rect out) {
+            out.set(mBounds);
+        }
+
+        @Override
+        public void getOverrideBounds(Rect outBounds) {
+            outBounds.set(mBounds);
+        }
+        @Override
+        void getTempInsetBounds(Rect outBounds) {
+            outBounds.set(mInsetBounds);
+        }
+        @Override
+        boolean isFullscreen() {
+            return mFullscreenForTest;
+        }
+    }
+
+    TaskStack mStubStack;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        // Just any non zero value.
+        sWm.mSystemDecorLayer = 10000;
+
+        mWindowToken = WindowTestUtils.createTestAppWindowToken(
+                sWm.getDefaultDisplayContentLocked());
+        mStubStack = new TaskStack(sWm, 0, null);
+    }
+
+    public void assertRect(Rect rect, int left, int top, int right, int bottom) {
+        assertEquals(left, rect.left);
+        assertEquals(top, rect.top);
+        assertEquals(right, rect.right);
+        assertEquals(bottom, rect.bottom);
+    }
+
+    @Test
+    public void testLayoutInFullscreenTaskInsets() throws Exception {
+        Task task = new TaskWithBounds(null); // fullscreen task doesn't use bounds for computeFrame
+        WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
+        w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
+
+        final int bottomContentInset = 100;
+        final int topContentInset = 50;
+        final int bottomVisibleInset = 30;
+        final int topVisibleInset = 70;
+        final int leftStableInset = 20;
+        final int rightStableInset = 90;
+
+        // With no insets or system decor all the frames incoming from PhoneWindowManager
+        // are identical.
+        final Rect pf = new Rect(0, 0, 1000, 1000);
+        final Rect df = pf;
+        final Rect of = df;
+        final Rect cf = new Rect(pf);
+        // Produce some insets
+        cf.top += 50;
+        cf.bottom -= 100;
+        final Rect vf = new Rect(pf);
+        vf.top += topVisibleInset;
+        vf.bottom -= bottomVisibleInset;
+        final Rect sf = new Rect(pf);
+        sf.left += leftStableInset;
+        sf.right -= rightStableInset;
+
+        final Rect dcf = pf;
+        // When mFrame extends past cf, the content insets are
+        // the difference between mFrame and ContentFrame. Visible
+        // and stable frames work the same way.
+        w.computeFrameLw(pf, df, of, cf, vf, dcf, sf, null, WmDisplayCutout.NO_CUTOUT, false);
+        assertRect(w.mFrame,0, 0, 1000, 1000);
+        assertRect(w.mContentInsets, 0, topContentInset, 0, bottomContentInset);
+        assertRect(w.mVisibleInsets, 0, topVisibleInset, 0, bottomVisibleInset);
+        assertRect(w.mStableInsets, leftStableInset, 0, rightStableInset, 0);
+        // The frames remain as passed in shrunk to the window frame
+        assertTrue(cf.equals(w.getContentFrameLw()));
+        assertTrue(vf.equals(w.getVisibleFrameLw()));
+        assertTrue(sf.equals(w.getStableFrameLw()));
+        // On the other hand mFrame doesn't extend past cf we won't get any insets
+        w.mAttrs.x = 100;
+        w.mAttrs.y = 100;
+        w.mAttrs.width = 100; w.mAttrs.height = 100; //have to clear MATCH_PARENT
+        w.mRequestedWidth = 100;
+        w.mRequestedHeight = 100;
+        w.computeFrameLw(pf, df, of, cf, vf, dcf, sf, null, WmDisplayCutout.NO_CUTOUT, false);
+        assertRect(w.mFrame, 100, 100, 200, 200);
+        assertRect(w.mContentInsets, 0, 0, 0, 0);
+        // In this case the frames are shrunk to the window frame.
+        assertTrue(w.mFrame.equals(w.getContentFrameLw()));
+        assertTrue(w.mFrame.equals(w.getVisibleFrameLw()));
+        assertTrue(w.mFrame.equals(w.getStableFrameLw()));
+    }
+
+    @Test
+    public void testLayoutInFullscreenTaskNoInsets() throws Exception {
+        Task task = new TaskWithBounds(null); // fullscreen task doesn't use bounds for computeFrame
+        WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
+        w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
+
+        // With no insets or system decor all the frames incoming from PhoneWindowManager
+        // are identical.
+        final Rect pf = new Rect(0, 0, 1000, 1000);
+
+        // Here the window has FILL_PARENT, FILL_PARENT
+        // so we expect it to fill the entire available frame.
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
+        assertRect(w.mFrame, 0, 0, 1000, 1000);
+
+        // It can select various widths and heights within the bounds.
+        // Strangely the window attribute width is ignored for normal windows
+        // and we use mRequestedWidth/mRequestedHeight
+        w.mAttrs.width = 300;
+        w.mAttrs.height = 300;
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
+        // Explicit width and height without requested width/height
+        // gets us nothing.
+        assertRect(w.mFrame, 0, 0, 0, 0);
+
+        w.mRequestedWidth = 300;
+        w.mRequestedHeight = 300;
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
+        // With requestedWidth/Height we can freely choose our size within the
+        // parent bounds.
+        assertRect(w.mFrame, 0, 0, 300, 300);
+
+        // With FLAG_SCALED though, requestedWidth/height is used to control
+        // the unscaled surface size, and mAttrs.width/height becomes the
+        // layout controller.
+        w.mAttrs.flags = WindowManager.LayoutParams.FLAG_SCALED;
+        w.mRequestedHeight = -1;
+        w.mRequestedWidth = -1;
+        w.mAttrs.width = 100;
+        w.mAttrs.height = 100;
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
+        assertRect(w.mFrame, 0, 0, 100, 100);
+        w.mAttrs.flags = 0;
+
+        // But sizes too large will be clipped to the containing frame
+        w.mRequestedWidth = 1200;
+        w.mRequestedHeight = 1200;
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
+        assertRect(w.mFrame, 0, 0, 1000, 1000);
+
+        // Before they are clipped though windows will be shifted
+        w.mAttrs.x = 300;
+        w.mAttrs.y = 300;
+        w.mRequestedWidth = 1000;
+        w.mRequestedHeight = 1000;
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
+        assertRect(w.mFrame, 0, 0, 1000, 1000);
+
+        // If there is room to move around in the parent frame the window will be shifted according
+        // to gravity.
+        w.mAttrs.x = 0;
+        w.mAttrs.y = 0;
+        w.mRequestedWidth = 300;
+        w.mRequestedHeight = 300;
+        w.mAttrs.gravity = Gravity.RIGHT | Gravity.TOP;
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
+        assertRect(w.mFrame, 700, 0, 1000, 300);
+        w.mAttrs.gravity = Gravity.RIGHT | Gravity.BOTTOM;
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
+        assertRect(w.mFrame, 700, 700, 1000, 1000);
+        // Window specified  x and y are interpreted as offsets in the opposite
+        // direction of gravity
+        w.mAttrs.x = 100;
+        w.mAttrs.y = 100;
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
+        assertRect(w.mFrame, 600, 600, 900, 900);
+    }
+
+    @Test
+    public void testLayoutNonfullscreenTask() {
+        final DisplayInfo displayInfo = sWm.getDefaultDisplayContentLocked().getDisplayInfo();
+        final int logicalWidth = displayInfo.logicalWidth;
+        final int logicalHeight = displayInfo.logicalHeight;
+
+        final int taskLeft = logicalWidth / 4;
+        final int taskTop = logicalHeight / 4;
+        final int taskRight = logicalWidth / 4 * 3;
+        final int taskBottom = logicalHeight / 4 * 3;
+        final Rect taskBounds = new Rect(taskLeft, taskTop, taskRight, taskBottom);
+        TaskWithBounds task = new TaskWithBounds(taskBounds);
+        task.mFullscreenForTest = false;
+        WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
+        w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
+
+        final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, null, WmDisplayCutout.NO_CUTOUT, false);
+        // For non fullscreen tasks the containing frame is based off the
+        // task bounds not the parent frame.
+        assertRect(w.mFrame, taskLeft, taskTop, taskRight, taskBottom);
+        assertRect(w.getContentFrameLw(), taskLeft, taskTop, taskRight, taskBottom);
+        assertRect(w.mContentInsets, 0, 0, 0, 0);
+
+        pf.set(0, 0, logicalWidth, logicalHeight);
+        // We still produce insets against the containing frame the same way.
+        final int cfRight = logicalWidth / 2;
+        final int cfBottom = logicalHeight / 2;
+        final Rect cf = new Rect(0, 0, cfRight, cfBottom);
+        w.computeFrameLw(pf, pf, pf, cf, cf, pf, cf, null, WmDisplayCutout.NO_CUTOUT, false);
+        assertRect(w.mFrame, taskLeft, taskTop, taskRight, taskBottom);
+        int contentInsetRight = taskRight - cfRight;
+        int contentInsetBottom = taskBottom - cfBottom;
+        assertRect(w.mContentInsets, 0, 0, contentInsetRight, contentInsetBottom);
+        assertRect(w.getContentFrameLw(), taskLeft, taskTop, taskRight - contentInsetRight,
+                taskBottom - contentInsetBottom);
+
+        pf.set(0, 0, logicalWidth, logicalHeight);
+        // However if we set temp inset bounds, the insets will be computed
+        // as if our window was laid out there,  but it will be laid out according to
+        // the task bounds.
+        final int insetLeft = logicalWidth / 5;
+        final int insetTop = logicalHeight / 5;
+        final int insetRight = insetLeft + (taskRight - taskLeft);
+        final int insetBottom = insetTop + (taskBottom - taskTop);
+        task.mInsetBounds.set(insetLeft, insetTop, insetRight, insetBottom);
+        w.computeFrameLw(pf, pf, pf, cf, cf, pf, cf, null, WmDisplayCutout.NO_CUTOUT, false);
+        assertRect(w.mFrame, taskLeft, taskTop, taskRight, taskBottom);
+        contentInsetRight = insetRight - cfRight;
+        contentInsetBottom = insetBottom - cfBottom;
+        assertRect(w.mContentInsets, 0, 0, contentInsetRight, contentInsetBottom);
+        assertRect(w.getContentFrameLw(), taskLeft, taskTop, taskRight - contentInsetRight,
+                taskBottom - contentInsetBottom);
+    }
+
+    @Test
+    public void testCalculatePolicyCrop() {
+        final WindowStateWithTask w = createWindow(
+                new TaskWithBounds(null), FILL_PARENT, FILL_PARENT);
+        w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
+
+        final DisplayInfo displayInfo = w.getDisplayContent().getDisplayInfo();
+        final int logicalWidth = displayInfo.logicalWidth;
+        final int logicalHeight = displayInfo.logicalHeight;
+        final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
+        final Rect df = pf;
+        final Rect of = df;
+        final Rect cf = new Rect(pf);
+        // Produce some insets
+        cf.top += displayInfo.logicalWidth / 10;
+        cf.bottom -= displayInfo.logicalWidth / 5;
+        final Rect vf = cf;
+        final Rect sf = vf;
+        // We use a decor content frame with insets to produce cropping.
+        Rect dcf = cf;
+
+        final Rect policyCrop = new Rect();
+
+        w.computeFrameLw(pf, df, of, cf, vf, dcf, sf, null, WmDisplayCutout.NO_CUTOUT, false);
+        w.calculatePolicyCrop(policyCrop);
+        assertRect(policyCrop, 0, cf.top, logicalWidth, cf.bottom);
+
+        dcf.setEmpty();
+        // Likewise with no decor frame we would get no crop
+        w.computeFrameLw(pf, df, of, cf, vf, dcf, sf, null, WmDisplayCutout.NO_CUTOUT, false);
+        w.calculatePolicyCrop(policyCrop);
+        assertRect(policyCrop, 0, 0, logicalWidth, logicalHeight);
+
+        // Now we set up a window which doesn't fill the entire decor frame.
+        // Normally it would be cropped to it's frame but in the case of docked resizing
+        // we need to account for the fact the windows surface will be made
+        // fullscreen and thus also make the crop fullscreen.
+        w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
+        w.mAttrs.width = logicalWidth / 2;
+        w.mAttrs.height = logicalHeight / 2;
+        w.mRequestedWidth = logicalWidth / 2;
+        w.mRequestedHeight = logicalHeight / 2;
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
+
+        w.calculatePolicyCrop(policyCrop);
+        // Normally the crop is shrunk from the decor frame
+        // to the computed window frame.
+        assertRect(policyCrop, 0, 0, logicalWidth / 2, logicalHeight / 2);
+
+        w.mDockedResizingForTest = true;
+        w.calculatePolicyCrop(policyCrop);
+        // But if we are docked resizing it won't be, however we will still be
+        // shrunk to the decor frame and the display.
+        assertRect(policyCrop, 0, 0,
+                Math.min(pf.width(), displayInfo.logicalWidth),
+                Math.min(pf.height(), displayInfo.logicalHeight));
+    }
+
+    @Test
+    public void testLayoutLetterboxedWindow() {
+        // First verify task behavior in multi-window mode.
+        final DisplayInfo displayInfo = sWm.getDefaultDisplayContentLocked().getDisplayInfo();
+        final int logicalWidth = displayInfo.logicalWidth;
+        final int logicalHeight = displayInfo.logicalHeight;
+
+        final int taskLeft = logicalWidth / 5;
+        final int taskTop = logicalHeight / 5;
+        final int taskRight = logicalWidth / 4 * 3;
+        final int taskBottom = logicalHeight / 4 * 3;
+        final Rect taskBounds = new Rect(taskLeft, taskTop, taskRight, taskBottom);
+        TaskWithBounds task = new TaskWithBounds(taskBounds);
+        task.mInsetBounds.set(taskLeft, taskTop, taskRight, taskBottom);
+        task.mFullscreenForTest = false;
+        WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
+        w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
+
+        final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
+        w.computeFrameLw(pf /* parentFrame */, pf /* displayFrame */, pf /* overscanFrame */,
+                pf /* contentFrame */, pf /* visibleFrame */, pf /* decorFrame */,
+                pf /* stableFrame */, null /* outsetFrame */, WmDisplayCutout.NO_CUTOUT, false);
+        // For non fullscreen tasks the containing frame is based off the
+        // task bounds not the parent frame.
+        assertRect(w.mFrame, taskLeft, taskTop, taskRight, taskBottom);
+        assertRect(w.getContentFrameLw(), taskLeft, taskTop, taskRight, taskBottom);
+        assertRect(w.mContentInsets, 0, 0, 0, 0);
+
+        // Now simulate switch to fullscreen for letterboxed app.
+        final int xInset = logicalWidth / 10;
+        final int yInset = logicalWidth / 10;
+        final Rect cf = new Rect(xInset, yInset, logicalWidth - xInset, logicalHeight - yInset);
+        Configuration config = new Configuration(w.mAppToken.getOverrideConfiguration());
+        config.windowConfiguration.setBounds(cf);
+        w.mAppToken.onOverrideConfigurationChanged(config);
+        pf.set(0, 0, logicalWidth, logicalHeight);
+        task.mFullscreenForTest = true;
+
+        w.computeFrameLw(pf /* parentFrame */, pf /* displayFrame */, pf /* overscanFrame */,
+                cf /* contentFrame */, cf /* visibleFrame */, pf /* decorFrame */,
+                cf /* stableFrame */, null /* outsetFrame */, WmDisplayCutout.NO_CUTOUT, false);
+        assertEquals(cf, w.mFrame);
+        assertEquals(cf, w.getContentFrameLw());
+        assertRect(w.mContentInsets, 0, 0, 0, 0);
+    }
+
+    @Test
+    public void testDisplayCutout() {
+        // Regular fullscreen task and window
+        Task task = new TaskWithBounds(null);
+        WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
+        w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
+
+        final Rect pf = new Rect(0, 0, 1000, 2000);
+        // Create a display cutout of size 50x50, aligned top-center
+        final WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
+                fromBoundingRect(500, 0, 550, 50), pf.width(), pf.height());
+
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, cutout, false);
+
+        assertEquals(w.mDisplayCutout.getDisplayCutout().getSafeInsetTop(), 50);
+        assertEquals(w.mDisplayCutout.getDisplayCutout().getSafeInsetBottom(), 0);
+        assertEquals(w.mDisplayCutout.getDisplayCutout().getSafeInsetLeft(), 0);
+        assertEquals(w.mDisplayCutout.getDisplayCutout().getSafeInsetRight(), 0);
+    }
+
+    @Test
+    public void testDisplayCutout_tempInsetBounds() {
+        // Regular fullscreen task and window
+        TaskWithBounds task = new TaskWithBounds(new Rect(0, -500, 1000, 1500));
+        task.mFullscreenForTest = false;
+        task.mInsetBounds.set(0, 0, 1000, 2000);
+        WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
+        w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
+
+        final Rect pf = new Rect(0, -500, 1000, 1500);
+        // Create a display cutout of size 50x50, aligned top-center
+        final WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
+                fromBoundingRect(500, 0, 550, 50), pf.width(), pf.height());
+
+        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, cutout, false);
+
+        assertEquals(w.mDisplayCutout.getDisplayCutout().getSafeInsetTop(), 50);
+        assertEquals(w.mDisplayCutout.getDisplayCutout().getSafeInsetBottom(), 0);
+        assertEquals(w.mDisplayCutout.getDisplayCutout().getSafeInsetLeft(), 0);
+        assertEquals(w.mDisplayCutout.getDisplayCutout().getSafeInsetRight(), 0);
+    }
+
+    private WindowStateWithTask createWindow(Task task, int width, int height) {
+        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
+        attrs.width = width;
+        attrs.height = height;
+
+        return new WindowStateWithTask(attrs, task);
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java b/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java
new file mode 100644
index 0000000..d91079e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import android.app.ActivityManagerInternal;
+import android.content.Context;
+import android.hardware.display.DisplayManagerInternal;
+import android.os.PowerManagerInternal;
+import android.os.PowerSaveState;
+import android.support.test.InstrumentationRegistry;
+import android.view.InputChannel;
+
+import com.android.server.LocalServices;
+import com.android.server.input.InputManagerService;
+import com.android.server.policy.WindowManagerPolicy;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.mockito.invocation.InvocationOnMock;
+
+/**
+ * A test rule that sets up a fresh WindowManagerService instance before each test and makes sure
+ * to properly tear it down after.
+ *
+ * <p>
+ * Usage:
+ * <pre>
+ * {@literal @}Rule
+ *  public final WindowManagerServiceRule mWmRule = new WindowManagerServiceRule();
+ * </pre>
+ */
+public class WindowManagerServiceRule implements TestRule {
+
+    private WindowManagerService mService;
+    private TestWindowManagerPolicy mPolicy;
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                runWithDexmakerShareClassLoader(this::setUp);
+                try {
+                    base.evaluate();
+                } finally {
+                    tearDown();
+                }
+            }
+
+            private void setUp() {
+                final Context context = InstrumentationRegistry.getTargetContext();
+
+                removeServices();
+
+                LocalServices.addService(DisplayManagerInternal.class,
+                        mock(DisplayManagerInternal.class));
+
+                LocalServices.addService(PowerManagerInternal.class,
+                        mock(PowerManagerInternal.class));
+                final PowerManagerInternal pm =
+                        LocalServices.getService(PowerManagerInternal.class);
+                PowerSaveState state = new PowerSaveState.Builder().build();
+                doReturn(state).when(pm).getLowPowerState(anyInt());
+
+                LocalServices.addService(ActivityManagerInternal.class,
+                        mock(ActivityManagerInternal.class));
+                final ActivityManagerInternal am =
+                        LocalServices.getService(ActivityManagerInternal.class);
+                doAnswer((InvocationOnMock invocationOnMock) -> {
+                    final Runnable runnable = invocationOnMock.<Runnable>getArgument(0);
+                    if (runnable != null) {
+                        runnable.run();
+                    }
+                    return null;
+                }).when(am).notifyKeyguardFlagsChanged(any());
+
+                InputManagerService ims = mock(InputManagerService.class);
+                // InputChannel is final and can't be mocked.
+                InputChannel[] input = InputChannel.openInputChannelPair(TAG_WM);
+                if (input != null && input.length > 1) {
+                    doReturn(input[1]).when(ims).monitorInput(anyString());
+                }
+
+                mService = WindowManagerService.main(context, ims, true, false,
+                        false, mPolicy = new TestWindowManagerPolicy(
+                                WindowManagerServiceRule.this::getWindowManagerService));
+
+                mService.onInitReady();
+
+                // Display creation is driven by the ActivityManagerService via ActivityStackSupervisor.
+                // We emulate those steps here.
+                mService.mRoot.createDisplayContent(
+                        mService.mDisplayManager.getDisplay(DEFAULT_DISPLAY),
+                        mock(DisplayWindowController.class));
+            }
+
+            private void removeServices() {
+                LocalServices.removeServiceForTest(DisplayManagerInternal.class);
+                LocalServices.removeServiceForTest(PowerManagerInternal.class);
+                LocalServices.removeServiceForTest(ActivityManagerInternal.class);
+                LocalServices.removeServiceForTest(WindowManagerInternal.class);
+                LocalServices.removeServiceForTest(WindowManagerPolicy.class);
+            }
+
+            private void tearDown() {
+                waitUntilWindowManagerHandlersIdle();
+                removeServices();
+                mService = null;
+                mPolicy = null;
+            }
+        };
+    }
+
+    public WindowManagerService getWindowManagerService() {
+        return mService;
+    }
+
+    public TestWindowManagerPolicy getWindowManagerPolicy() {
+        return mPolicy;
+    }
+
+    public void waitUntilWindowManagerHandlersIdle() {
+        final WindowManagerService wm = getWindowManagerService();
+        if (wm != null) {
+            wm.mH.runWithScissors(() -> { }, 0);
+            wm.mAnimationHandler.runWithScissors(() -> { }, 0);
+            SurfaceAnimationThread.getHandler().runWithScissors(() -> { }, 0);
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRuleTest.java b/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRuleTest.java
new file mode 100644
index 0000000..6cf6d7b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRuleTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@Presubmit
+@SmallTest
+public class WindowManagerServiceRuleTest {
+
+    @Rule
+    public final WindowManagerServiceRule mRule = new WindowManagerServiceRule();
+
+    @Test
+    public void testWindowManagerSetUp() {
+        assertThat(mRule.getWindowManagerService(), notNullValue());
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
new file mode 100644
index 0000000..85e846d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import android.view.WindowManager;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import java.util.LinkedList;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+/**
+ * Tests for the {@link WindowState} class.
+ *
+ * atest FrameworksServicesTests:com.android.server.wm.WindowStateTests
+ */
+@SmallTest
+@FlakyTest(bugId = 74078662)
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class WindowStateTests extends WindowTestsBase {
+
+    @Test
+    public void testIsParentWindowHidden() throws Exception {
+        final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow");
+        final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1");
+        final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2");
+
+        // parentWindow is initially set to hidden.
+        assertTrue(parentWindow.mHidden);
+        assertFalse(parentWindow.isParentWindowHidden());
+        assertTrue(child1.isParentWindowHidden());
+        assertTrue(child2.isParentWindowHidden());
+
+        parentWindow.mHidden = false;
+        assertFalse(parentWindow.isParentWindowHidden());
+        assertFalse(child1.isParentWindowHidden());
+        assertFalse(child2.isParentWindowHidden());
+
+    }
+
+    @Test
+    public void testIsChildWindow() throws Exception {
+        final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow");
+        final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1");
+        final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2");
+        final WindowState randomWindow = createWindow(null, TYPE_APPLICATION, "randomWindow");
+
+        assertFalse(parentWindow.isChildWindow());
+        assertTrue(child1.isChildWindow());
+        assertTrue(child2.isChildWindow());
+        assertFalse(randomWindow.isChildWindow());
+    }
+
+    @Test
+    public void testHasChild() throws Exception {
+        final WindowState win1 = createWindow(null, TYPE_APPLICATION, "win1");
+        final WindowState win11 = createWindow(win1, FIRST_SUB_WINDOW, "win11");
+        final WindowState win12 = createWindow(win1, FIRST_SUB_WINDOW, "win12");
+        final WindowState win2 = createWindow(null, TYPE_APPLICATION, "win2");
+        final WindowState win21 = createWindow(win2, FIRST_SUB_WINDOW, "win21");
+        final WindowState randomWindow = createWindow(null, TYPE_APPLICATION, "randomWindow");
+
+        assertTrue(win1.hasChild(win11));
+        assertTrue(win1.hasChild(win12));
+        assertTrue(win2.hasChild(win21));
+
+        assertFalse(win1.hasChild(win21));
+        assertFalse(win1.hasChild(randomWindow));
+
+        assertFalse(win2.hasChild(win11));
+        assertFalse(win2.hasChild(win12));
+        assertFalse(win2.hasChild(randomWindow));
+    }
+
+    @Test
+    public void testGetParentWindow() throws Exception {
+        final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow");
+        final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1");
+        final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2");
+
+        assertNull(parentWindow.getParentWindow());
+        assertEquals(parentWindow, child1.getParentWindow());
+        assertEquals(parentWindow, child2.getParentWindow());
+    }
+
+    @Test
+    public void testOverlayWindowHiddenWhenSuspended() {
+        final WindowState overlayWindow = spy(createWindow(null, TYPE_APPLICATION_OVERLAY,
+                "overlayWindow"));
+        overlayWindow.setHiddenWhileSuspended(true);
+        verify(overlayWindow).hideLw(true, true);
+        overlayWindow.setHiddenWhileSuspended(false);
+        verify(overlayWindow).showLw(true, true);
+    }
+
+    @Test
+    public void testGetTopParentWindow() throws Exception {
+        final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
+        final WindowState child1 = createWindow(root, FIRST_SUB_WINDOW, "child1");
+        final WindowState child2 = createWindow(child1, FIRST_SUB_WINDOW, "child2");
+
+        assertEquals(root, root.getTopParentWindow());
+        assertEquals(root, child1.getTopParentWindow());
+        assertEquals(child1, child2.getParentWindow());
+        assertEquals(root, child2.getTopParentWindow());
+
+        // Test case were child is detached from parent.
+        root.removeChild(child1);
+        assertEquals(child1, child1.getTopParentWindow());
+        assertEquals(child1, child2.getParentWindow());
+    }
+
+    @Test
+    public void testIsOnScreen_hiddenByPolicy() {
+        final WindowState window = createWindow(null, TYPE_APPLICATION, "window");
+        window.setHasSurface(true);
+        assertTrue(window.isOnScreen());
+        window.hideLw(false /* doAnimation */);
+        assertFalse(window.isOnScreen());
+    }
+
+    @Test
+    public void testCanBeImeTarget() throws Exception {
+        final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow");
+        final WindowState imeWindow = createWindow(null, TYPE_INPUT_METHOD, "imeWindow");
+
+        // Setting FLAG_NOT_FOCUSABLE without FLAG_ALT_FOCUSABLE_IM prevents the window from being
+        // an IME target.
+        appWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
+        imeWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
+
+        // Make windows visible
+        appWindow.setHasSurface(true);
+        imeWindow.setHasSurface(true);
+
+        // Windows without flags (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM) can't be IME targets
+        assertFalse(appWindow.canBeImeTarget());
+        assertFalse(imeWindow.canBeImeTarget());
+
+        // Add IME target flags
+        appWindow.mAttrs.flags |= (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);
+        imeWindow.mAttrs.flags |= (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);
+
+        // Visible app window with flags can be IME target while an IME window can never be an IME
+        // target regardless of its visibility or flags.
+        assertTrue(appWindow.canBeImeTarget());
+        assertFalse(imeWindow.canBeImeTarget());
+
+        // Make windows invisible
+        appWindow.hideLw(false /* doAnimation */);
+        imeWindow.hideLw(false /* doAnimation */);
+
+        // Invisible window can't be IME targets even if they have the right flags.
+        assertFalse(appWindow.canBeImeTarget());
+        assertFalse(imeWindow.canBeImeTarget());
+    }
+
+    @Test
+    public void testGetWindow() throws Exception {
+        final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
+        final WindowState mediaChild = createWindow(root, TYPE_APPLICATION_MEDIA, "mediaChild");
+        final WindowState mediaOverlayChild = createWindow(root,
+                TYPE_APPLICATION_MEDIA_OVERLAY, "mediaOverlayChild");
+        final WindowState attachedDialogChild = createWindow(root,
+                TYPE_APPLICATION_ATTACHED_DIALOG, "attachedDialogChild");
+        final WindowState subPanelChild = createWindow(root,
+                TYPE_APPLICATION_SUB_PANEL, "subPanelChild");
+        final WindowState aboveSubPanelChild = createWindow(root,
+                TYPE_APPLICATION_ABOVE_SUB_PANEL, "aboveSubPanelChild");
+
+        final LinkedList<WindowState> windows = new LinkedList();
+
+        root.getWindow(w -> {
+            windows.addLast(w);
+            return false;
+        });
+
+        // getWindow should have returned candidate windows in z-order.
+        assertEquals(aboveSubPanelChild, windows.pollFirst());
+        assertEquals(subPanelChild, windows.pollFirst());
+        assertEquals(attachedDialogChild, windows.pollFirst());
+        assertEquals(root, windows.pollFirst());
+        assertEquals(mediaOverlayChild, windows.pollFirst());
+        assertEquals(mediaChild, windows.pollFirst());
+        assertTrue(windows.isEmpty());
+    }
+
+    @Test
+    public void testPrepareWindowToDisplayDuringRelayout() throws Exception {
+        testPrepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
+        testPrepareWindowToDisplayDuringRelayout(true /*wasVisible*/);
+
+        // Call prepareWindowToDisplayDuringRelayout for a window without FLAG_TURN_SCREEN_ON
+        // before calling prepareWindowToDisplayDuringRelayout for windows with flag in the same
+        // appWindowToken.
+        final AppWindowToken appWindowToken = createAppWindowToken(mDisplayContent,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        final WindowState first = createWindow(null, TYPE_APPLICATION, appWindowToken, "first");
+        final WindowState second = createWindow(null, TYPE_APPLICATION, appWindowToken, "second");
+        second.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
+
+        reset(mPowerManagerWrapper);
+        first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
+        verify(mPowerManagerWrapper, never()).wakeUp(anyLong(), anyString());
+        assertTrue(appWindowToken.canTurnScreenOn());
+
+        reset(mPowerManagerWrapper);
+        second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
+        verify(mPowerManagerWrapper).wakeUp(anyLong(), anyString());
+        assertFalse(appWindowToken.canTurnScreenOn());
+
+        // Call prepareWindowToDisplayDuringRelayout for two window that have FLAG_TURN_SCREEN_ON
+        // from the same appWindowToken. Only one should trigger the wakeup.
+        appWindowToken.setCanTurnScreenOn(true);
+        first.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
+        second.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
+
+        reset(mPowerManagerWrapper);
+        first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
+        verify(mPowerManagerWrapper).wakeUp(anyLong(), anyString());
+        assertFalse(appWindowToken.canTurnScreenOn());
+
+        reset(mPowerManagerWrapper);
+        second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
+        verify(mPowerManagerWrapper, never()).wakeUp(anyLong(), anyString());
+        assertFalse(appWindowToken.canTurnScreenOn());
+
+        // Call prepareWindowToDisplayDuringRelayout for a windows that are not children of an
+        // appWindowToken. Both windows have the FLAG_TURNS_SCREEN_ON so both should call wakeup
+        final WindowToken windowToken = WindowTestUtils.createTestWindowToken(FIRST_SUB_WINDOW,
+                mDisplayContent);
+        final WindowState firstWindow = createWindow(null, TYPE_APPLICATION, windowToken,
+                "firstWindow");
+        final WindowState secondWindow = createWindow(null, TYPE_APPLICATION, windowToken,
+                "secondWindow");
+        firstWindow.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
+        secondWindow.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
+
+        reset(mPowerManagerWrapper);
+        firstWindow.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
+        verify(mPowerManagerWrapper).wakeUp(anyLong(), anyString());
+
+        reset(mPowerManagerWrapper);
+        secondWindow.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
+        verify(mPowerManagerWrapper).wakeUp(anyLong(), anyString());
+    }
+
+    @Test
+    public void testCanAffectSystemUiFlags() throws Exception {
+        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        app.mToken.setHidden(false);
+        assertTrue(app.canAffectSystemUiFlags());
+        app.mToken.setHidden(true);
+        assertFalse(app.canAffectSystemUiFlags());
+        app.mToken.setHidden(false);
+        app.mAttrs.alpha = 0.0f;
+        assertFalse(app.canAffectSystemUiFlags());
+
+    }
+
+    @Test
+    public void testCanAffectSystemUiFlags_disallow() throws Exception {
+        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        app.mToken.setHidden(false);
+        assertTrue(app.canAffectSystemUiFlags());
+        app.getTask().setCanAffectSystemUiFlags(false);
+        assertFalse(app.canAffectSystemUiFlags());
+    }
+
+    @Test
+    public void testIsSelfOrAncestorWindowAnimating() throws Exception {
+        final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
+        final WindowState child1 = createWindow(root, FIRST_SUB_WINDOW, "child1");
+        final WindowState child2 = createWindow(child1, FIRST_SUB_WINDOW, "child2");
+        assertFalse(child2.isSelfOrAncestorWindowAnimatingExit());
+        child2.mAnimatingExit = true;
+        assertTrue(child2.isSelfOrAncestorWindowAnimatingExit());
+        child2.mAnimatingExit = false;
+        root.mAnimatingExit = true;
+        assertTrue(child2.isSelfOrAncestorWindowAnimatingExit());
+    }
+
+    @Test
+    public void testLayoutSeqResetOnReparent() throws Exception {
+        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        app.mLayoutSeq = 1;
+        mDisplayContent.mLayoutSeq = 1;
+
+        app.onDisplayChanged(mDisplayContent);
+
+        assertThat(app.mLayoutSeq, not(is(mDisplayContent.mLayoutSeq)));
+    }
+
+    @Test
+    public void testDisplayIdUpdatedOnReparent() throws Exception {
+        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        // fake a different display
+        app.mInputWindowHandle.displayId = mDisplayContent.getDisplayId() + 1;
+        app.onDisplayChanged(mDisplayContent);
+
+        assertThat(app.mInputWindowHandle.displayId, is(mDisplayContent.getDisplayId()));
+        assertThat(app.getDisplayId(), is(mDisplayContent.getDisplayId()));
+    }
+
+    private void testPrepareWindowToDisplayDuringRelayout(boolean wasVisible) {
+        reset(mPowerManagerWrapper);
+        final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
+        root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
+
+        root.prepareWindowToDisplayDuringRelayout(wasVisible /*wasVisible*/);
+        verify(mPowerManagerWrapper).wakeUp(anyLong(), anyString());
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowSurfacePlacerTest.java b/services/tests/servicestests/src/com/android/server/wm/WindowSurfacePlacerTest.java
new file mode 100644
index 0000000..e173b7d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowSurfacePlacerTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
+import static android.view.WindowManager.TRANSIT_TASK_OPEN;
+import static junit.framework.Assert.assertEquals;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.WindowManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class WindowSurfacePlacerTest extends WindowTestsBase {
+
+    private WindowSurfacePlacer mWindowSurfacePlacer;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        mWindowSurfacePlacer = new WindowSurfacePlacer(sWm);
+    }
+
+    @Test
+    public void testTranslucentOpen() throws Exception {
+        synchronized (sWm.mWindowMap) {
+            final AppWindowToken behind = createAppWindowToken(mDisplayContent,
+                    WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+            final AppWindowToken translucentOpening = createAppWindowToken(mDisplayContent,
+                    WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+            translucentOpening.setFillsParent(false);
+            translucentOpening.setHidden(true);
+            sWm.mOpeningApps.add(behind);
+            sWm.mOpeningApps.add(translucentOpening);
+            assertEquals(WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_OPEN,
+                    mWindowSurfacePlacer.maybeUpdateTransitToTranslucentAnim(TRANSIT_TASK_OPEN));
+        }
+    }
+
+    @Test
+    public void testTranslucentClose() throws Exception {
+        synchronized (sWm.mWindowMap) {
+            final AppWindowToken behind = createAppWindowToken(mDisplayContent,
+                    WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+            final AppWindowToken translucentClosing = createAppWindowToken(mDisplayContent,
+                    WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+            translucentClosing.setFillsParent(false);
+            sWm.mClosingApps.add(translucentClosing);
+            assertEquals(WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE,
+                    mWindowSurfacePlacer.maybeUpdateTransitToTranslucentAnim(TRANSIT_TASK_CLOSE));
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
new file mode 100644
index 0000000..2e4740b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Binder;
+import android.os.IBinder;
+import android.view.IApplicationToken;
+import android.view.IWindow;
+import android.view.WindowManager;
+
+import static android.app.AppOpsManager.OP_NONE;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+
+import static com.android.server.wm.WindowContainer.POSITION_TOP;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.anyFloat;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.mockito.invocation.InvocationOnMock;
+
+/**
+ * A collection of static functions that can be referenced by other test packages to provide access
+ * to WindowManager related test functionality.
+ */
+public class WindowTestUtils {
+    public static int sNextTaskId = 0;
+
+    /**
+     * Retrieves an instance of a mock {@link WindowManagerService}.
+     */
+    public static WindowManagerService getMockWindowManagerService() {
+        final WindowManagerService service = mock(WindowManagerService.class);
+        final WindowHashMap windowMap = new WindowHashMap();
+        when(service.getWindowManagerLock()).thenReturn(windowMap);
+        return service;
+    }
+
+    /**
+     * Creates a mock instance of {@link StackWindowController}.
+     */
+    public static StackWindowController createMockStackWindowContainerController() {
+        StackWindowController controller = mock(StackWindowController.class);
+        controller.mContainer = mock(TestTaskStack.class);
+
+        // many components rely on the {@link StackWindowController#adjustConfigurationForBounds}
+        // to properly set bounds values in the configuration. We must mimick those actions here.
+        doAnswer((InvocationOnMock invocationOnMock) -> {
+            final Configuration config = invocationOnMock.<Configuration>getArgument(7);
+            final Rect bounds = invocationOnMock.<Rect>getArgument(0);
+            config.windowConfiguration.setBounds(bounds);
+            return null;
+        }).when(controller).adjustConfigurationForBounds(any(), any(), any(), any(),
+                anyBoolean(), anyBoolean(), anyFloat(), any(), any(), anyInt());
+
+        return controller;
+    }
+
+    /** Creates a {@link Task} and adds it to the specified {@link TaskStack}. */
+    public static Task createTaskInStack(WindowManagerService service, TaskStack stack,
+            int userId) {
+        synchronized (service.mWindowMap) {
+            final Task newTask = new Task(sNextTaskId++, stack, userId, service, 0, false,
+                    new ActivityManager.TaskDescription(), null);
+            stack.addTask(newTask, POSITION_TOP);
+            return newTask;
+        }
+    }
+
+    /**
+     * 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.mService.mWindowMap) {
+            return new TestAppWindowToken(dc);
+        }
+    }
+
+    /** Used so we can gain access to some protected members of the {@link AppWindowToken} class. */
+    public static class TestAppWindowToken extends AppWindowToken {
+        boolean mOnTop = false;
+
+        private TestAppWindowToken(DisplayContent dc) {
+            super(dc.mService, new IApplicationToken.Stub() {
+                public String getName() {return null;}
+                }, false, dc, true /* fillsParent */);
+        }
+
+        TestAppWindowToken(WindowManagerService service, IApplicationToken token,
+                boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos,
+                boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation,
+                int rotationAnimationHint, int configChanges, boolean launchTaskBehind,
+                boolean alwaysFocusable, AppWindowContainerController controller) {
+            super(service, token, voiceInteraction, dc, inputDispatchingTimeoutNanos, fullscreen,
+                    showForAllUsers, targetSdk, orientation, rotationAnimationHint, configChanges,
+                    launchTaskBehind, alwaysFocusable, controller);
+        }
+
+        int getWindowsCount() {
+            return mChildren.size();
+        }
+
+        boolean hasWindow(WindowState w) {
+            return mChildren.contains(w);
+        }
+
+        WindowState getFirstChild() {
+            return mChildren.peekFirst();
+        }
+
+        WindowState getLastChild() {
+            return mChildren.peekLast();
+        }
+
+        int positionInParent() {
+            return getParent().mChildren.indexOf(this);
+        }
+
+        void setIsOnTop(boolean onTop) {
+            mOnTop = onTop;
+        }
+
+        @Override
+        boolean isOnTop() {
+            return mOnTop;
+        }
+    }
+
+    static TestWindowToken createTestWindowToken(int type, DisplayContent dc) {
+        return createTestWindowToken(type, dc, false /* persistOnEmpty */);
+    }
+
+    static TestWindowToken createTestWindowToken(int type, DisplayContent dc,
+            boolean persistOnEmpty) {
+        synchronized (dc.mService.mWindowMap) {
+            return new TestWindowToken(type, dc, persistOnEmpty);
+        }
+    }
+
+    /* Used so we can gain access to some protected members of the {@link WindowToken} class */
+    public static class TestWindowToken extends WindowToken {
+
+        private TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) {
+            super(dc.mService, mock(IBinder.class), type, persistOnEmpty, dc,
+                    false /* ownerCanManageAppTokens */);
+        }
+
+        int getWindowsCount() {
+            return mChildren.size();
+        }
+
+        boolean hasWindow(WindowState w) {
+            return mChildren.contains(w);
+        }
+    }
+
+    /* Used so we can gain access to some protected members of the {@link Task} class */
+    public static class TestTask extends Task {
+        boolean mShouldDeferRemoval = false;
+        boolean mOnDisplayChangedCalled = false;
+        private boolean mIsAnimating = false;
+
+        TestTask(int taskId, TaskStack stack, int userId, WindowManagerService service,
+                int resizeMode, boolean supportsPictureInPicture,
+                TaskWindowContainerController controller) {
+            super(taskId, stack, userId, service, resizeMode, supportsPictureInPicture,
+                    new ActivityManager.TaskDescription(), controller);
+        }
+
+        boolean shouldDeferRemoval() {
+            return mShouldDeferRemoval;
+        }
+
+        int positionInParent() {
+            return getParent().mChildren.indexOf(this);
+        }
+
+        @Override
+        void onDisplayChanged(DisplayContent dc) {
+            super.onDisplayChanged(dc);
+            mOnDisplayChangedCalled = true;
+        }
+
+        @Override
+        boolean isSelfAnimating() {
+            return mIsAnimating;
+        }
+
+        void setLocalIsAnimating(boolean isAnimating) {
+            mIsAnimating = isAnimating;
+        }
+    }
+
+    /**
+     * Used so we can gain access to some protected members of {@link TaskWindowContainerController}
+     * class.
+     */
+    public static class TestTaskWindowContainerController extends TaskWindowContainerController {
+
+        TestTaskWindowContainerController(WindowTestsBase testsBase) {
+            this(testsBase.createStackControllerOnDisplay(testsBase.mDisplayContent));
+        }
+
+        TestTaskWindowContainerController(StackWindowController stackController) {
+            super(sNextTaskId++, new TaskWindowContainerListener() {
+                        @Override
+                        public void registerConfigurationChangeListener(
+                                ConfigurationContainerListener listener) {
+
+                        }
+
+                        @Override
+                        public void unregisterConfigurationChangeListener(
+                                ConfigurationContainerListener listener) {
+
+                        }
+
+                        @Override
+                        public void onSnapshotChanged(ActivityManager.TaskSnapshot snapshot) {
+
+                        }
+
+                        @Override
+                        public void requestResize(Rect bounds, int resizeMode) {
+
+                        }
+                    }, stackController, 0 /* userId */, null /* bounds */, RESIZE_MODE_UNRESIZEABLE,
+                    false /* supportsPictureInPicture */, true /* toTop*/,
+                    true /* showForAllUsers */, new ActivityManager.TaskDescription(),
+                    stackController.mService);
+        }
+
+        @Override
+        TestTask createTask(int taskId, TaskStack stack, int userId, int resizeMode,
+                boolean supportsPictureInPicture, ActivityManager.TaskDescription taskDescription) {
+            return new TestTask(taskId, stack, userId, mService, resizeMode,
+                    supportsPictureInPicture, this);
+        }
+    }
+
+    public static class TestAppWindowContainerController extends AppWindowContainerController {
+
+        final IApplicationToken mToken;
+
+        TestAppWindowContainerController(TestTaskWindowContainerController taskController) {
+            this(taskController, new TestIApplicationToken());
+        }
+
+        TestAppWindowContainerController(TestTaskWindowContainerController taskController,
+                IApplicationToken token) {
+            super(taskController, token, null /* listener */, 0 /* index */,
+                    SCREEN_ORIENTATION_UNSPECIFIED, true /* fullscreen */,
+                    true /* showForAllUsers */, 0 /* configChanges */, false /* voiceInteraction */,
+                    false /* launchTaskBehind */, false /* alwaysFocusable */,
+                    0 /* targetSdkVersion */, 0 /* rotationAnimationHint */,
+                    0 /* inputDispatchingTimeoutNanos */, taskController.mService);
+            mToken = token;
+        }
+
+        @Override
+        AppWindowToken createAppWindow(WindowManagerService service, IApplicationToken token,
+                boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos,
+                boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation,
+                int rotationAnimationHint, int configChanges, boolean launchTaskBehind,
+                boolean alwaysFocusable, AppWindowContainerController controller) {
+            return new TestAppWindowToken(service, token, voiceInteraction, dc,
+                    inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk,
+                    orientation,
+                    rotationAnimationHint, configChanges, launchTaskBehind, alwaysFocusable,
+                    controller);
+        }
+
+        AppWindowToken getAppWindowToken(DisplayContent dc) {
+            return (AppWindowToken) dc.getWindowToken(mToken.asBinder());
+        }
+    }
+
+    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 {
+        boolean resizeReported;
+
+        TestWindowState(WindowManagerService service, Session session, IWindow window,
+                WindowManager.LayoutParams attrs, WindowToken token) {
+            super(service, session, window, token, null, OP_NONE, 0, attrs, 0, 0,
+                    false /* ownerCanAddInternalSystemWindow */);
+        }
+
+        @Override
+        void reportResized() {
+            super.reportResized();
+            resizeReported = true;
+        }
+
+        @Override
+        public boolean isGoneForLayoutLw() {
+            return false;
+        }
+
+        @Override
+        void updateResizingWindowIfNeeded() {
+            // Used in AppWindowTokenTests#testLandscapeSeascapeRotationRelayout to deceive
+            // the system that it can actually update the window.
+            boolean hadSurface = mHasSurface;
+            mHasSurface = true;
+
+            super.updateResizingWindowIfNeeded();
+
+            mHasSurface = hadSurface;
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
new file mode 100644
index 0000000..473a287
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.View.VISIBLE;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.hardware.display.DisplayManagerGlobal;
+import android.testing.DexmakerShareClassLoaderRule;
+import android.util.Log;
+import android.view.Display;
+import android.view.DisplayInfo;
+import org.junit.Assert;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.view.IWindow;
+import android.view.WindowManager;
+
+import static android.app.AppOpsManager.OP_NONE;
+import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
+import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static org.mockito.Mockito.mock;
+
+import com.android.server.AttributeCache;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+
+/**
+ * Common base class for window manager unit test classes.
+ *
+ * Make sure any requests to WM hold the WM lock if needed b/73966377
+ */
+class WindowTestsBase {
+    private static final String TAG = WindowTestsBase.class.getSimpleName();
+    WindowManagerService sWm = null;  // TODO(roosa): rename to mWm in follow-up CL
+    private final IWindow mIWindow = new TestIWindow();
+    private Session mMockSession;
+    // The default display is removed in {@link #setUp} and then we iterate over all displays to
+    // make sure we don't collide with any existing display. If we run into no other display, the
+    // added display should be treated as default. This cannot be the default display
+    private static int sNextDisplayId = DEFAULT_DISPLAY + 1;
+    static int sNextStackId = 1000;
+
+    DisplayContent mDisplayContent;
+    DisplayInfo mDisplayInfo = new DisplayInfo();
+    WindowState mWallpaperWindow;
+    WindowState mImeWindow;
+    WindowState mImeDialogWindow;
+    WindowState mStatusBarWindow;
+    WindowState mDockedDividerWindow;
+    WindowState mNavBarWindow;
+    WindowState mAppWindow;
+    WindowState mChildAppWindowAbove;
+    WindowState mChildAppWindowBelow;
+    HashSet<WindowState> mCommonWindows;
+    WallpaperController mWallpaperController;
+
+    @Rule
+    public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
+            new DexmakerShareClassLoaderRule();
+
+    @Rule
+    public final WindowManagerServiceRule mWmRule = new WindowManagerServiceRule();
+
+    static WindowState.PowerManagerWrapper mPowerManagerWrapper;  // TODO(roosa): make non-static.
+
+    @Before
+    public void setUp() throws Exception {
+        // 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 {
+            mMockSession = mock(Session.class);
+            mPowerManagerWrapper = mock(WindowState.PowerManagerWrapper.class);
+
+            final Context context = InstrumentationRegistry.getTargetContext();
+            AttributeCache.init(context);
+
+            sWm = mWmRule.getWindowManagerService();
+            beforeCreateDisplay();
+
+            mWallpaperController = new WallpaperController(sWm);
+
+            context.getDisplay().getDisplayInfo(mDisplayInfo);
+            mDisplayContent = createNewDisplay();
+            sWm.mDisplayEnabled = true;
+            sWm.mDisplayReady = true;
+
+            // Set-up some common windows.
+            mCommonWindows = new HashSet();
+            synchronized (sWm.mWindowMap) {
+                mWallpaperWindow = createCommonWindow(null, TYPE_WALLPAPER, "wallpaperWindow");
+                mImeWindow = createCommonWindow(null, TYPE_INPUT_METHOD, "mImeWindow");
+                sWm.mInputMethodWindow = mImeWindow;
+                mImeDialogWindow = createCommonWindow(null, TYPE_INPUT_METHOD_DIALOG,
+                        "mImeDialogWindow");
+                mStatusBarWindow = createCommonWindow(null, TYPE_STATUS_BAR, "mStatusBarWindow");
+                mNavBarWindow = createCommonWindow(null, TYPE_NAVIGATION_BAR, "mNavBarWindow");
+                mDockedDividerWindow = createCommonWindow(null, TYPE_DOCK_DIVIDER,
+                        "mDockedDividerWindow");
+                mAppWindow = createCommonWindow(null, TYPE_BASE_APPLICATION, "mAppWindow");
+                mChildAppWindowAbove = createCommonWindow(mAppWindow,
+                        TYPE_APPLICATION_ATTACHED_DIALOG,
+                        "mChildAppWindowAbove");
+                mChildAppWindowBelow = createCommonWindow(mAppWindow,
+                        TYPE_APPLICATION_MEDIA_OVERLAY,
+                        "mChildAppWindowBelow");
+            }
+            // Adding a display will cause freezing the display. Make sure to wait until it's
+            // unfrozen to not run into race conditions with the tests.
+            waitUntilHandlersIdle();
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to set up test", e);
+            throw e;
+        }
+    }
+
+    void beforeCreateDisplay() {
+        // Called before display is created.
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        // If @After throws an exception, the error isn't logged. This will make sure any failures
+        // in the tear down are clear. This can be removed when b/37850063 is fixed.
+        try {
+            final LinkedList<WindowState> nonCommonWindows = new LinkedList();
+
+            synchronized (sWm.mWindowMap) {
+                sWm.mRoot.forAllWindows(w -> {
+                    if (!mCommonWindows.contains(w)) {
+                        nonCommonWindows.addLast(w);
+                    }
+                }, true /* traverseTopToBottom */);
+
+                while (!nonCommonWindows.isEmpty()) {
+                    nonCommonWindows.pollLast().removeImmediately();
+                }
+
+                mDisplayContent.removeImmediately();
+                sWm.mInputMethodTarget = null;
+                sWm.mClosingApps.clear();
+                sWm.mOpeningApps.clear();
+            }
+
+            // Wait until everything is really cleaned up.
+            waitUntilHandlersIdle();
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to tear down test", e);
+            throw e;
+        }
+    }
+
+    /**
+     * @return A SurfaceBuilderFactory to inject in to the WindowManagerService during
+     *         set-up (or null).
+     */
+    SurfaceBuilderFactory getSurfaceBuilderFactory() {
+        return null;
+    }
+
+    private WindowState createCommonWindow(WindowState parent, int type, String name) {
+        synchronized (sWm.mWindowMap) {
+            final WindowState win = createWindow(parent, type, name);
+            mCommonWindows.add(win);
+            // Prevent common windows from been IMe targets
+            win.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
+            return win;
+        }
+    }
+
+    /** Asserts that the first entry is greater than the second entry. */
+    void assertGreaterThan(int first, int second) throws Exception {
+        Assert.assertTrue("Excepted " + first + " to be greater than " + second, first > second);
+    }
+
+    /** Asserts that the first entry is greater than the second entry. */
+    void assertLessThan(int first, int second) throws Exception {
+        Assert.assertTrue("Excepted " + first + " to be less than " + second, first < second);
+    }
+
+    /**
+     * Waits until the main handler for WM has processed all messages.
+     */
+    void waitUntilHandlersIdle() {
+        mWmRule.waitUntilWindowManagerHandlersIdle();
+    }
+
+    private WindowToken createWindowToken(
+            DisplayContent dc, int windowingMode, int activityType, int type) {
+        synchronized (sWm.mWindowMap) {
+            if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) {
+                return WindowTestUtils.createTestWindowToken(type, dc);
+            }
+
+            return createAppWindowToken(dc, windowingMode, activityType);
+        }
+    }
+
+    AppWindowToken createAppWindowToken(DisplayContent dc, int windowingMode, int activityType) {
+        final TaskStack stack = createStackControllerOnStackOnDisplay(windowingMode, activityType,
+                dc).mContainer;
+        final Task task = createTaskInStack(stack, 0 /* userId */);
+        final WindowTestUtils.TestAppWindowToken appWindowToken =
+                WindowTestUtils.createTestAppWindowToken(dc);
+        task.addChild(appWindowToken, 0);
+        return appWindowToken;
+    }
+
+    WindowState createWindow(WindowState parent, int type, String name) {
+        synchronized (sWm.mWindowMap) {
+            return (parent == null)
+                    ? createWindow(parent, type, mDisplayContent, name)
+                    : createWindow(parent, type, parent.mToken, name);
+        }
+    }
+
+    WindowState createWindowOnStack(WindowState parent, int windowingMode, int activityType,
+            int type, DisplayContent dc, String name) {
+        synchronized (sWm.mWindowMap) {
+            final WindowToken token = createWindowToken(dc, windowingMode, activityType, type);
+            return createWindow(parent, type, token, name);
+        }
+    }
+
+    WindowState createAppWindow(Task task, int type, String name) {
+        synchronized (sWm.mWindowMap) {
+            final AppWindowToken token = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
+            task.addChild(token, 0);
+            return createWindow(null, type, token, name);
+        }
+    }
+
+    WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) {
+        synchronized (sWm.mWindowMap) {
+            final WindowToken token = createWindowToken(
+                    dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type);
+            return createWindow(parent, type, token, name);
+        }
+    }
+
+    WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name,
+            boolean ownerCanAddInternalSystemWindow) {
+        synchronized (sWm.mWindowMap) {
+            final WindowToken token = createWindowToken(
+                    dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type);
+            return createWindow(parent, type, token, name, 0 /* ownerId */,
+                    ownerCanAddInternalSystemWindow);
+        }
+    }
+
+    WindowState createWindow(WindowState parent, int type, WindowToken token, String name) {
+        synchronized (sWm.mWindowMap) {
+            return createWindow(parent, type, token, name, 0 /* ownerId */,
+                    false /* ownerCanAddInternalSystemWindow */);
+        }
+    }
+
+    WindowState createWindow(WindowState parent, int type, WindowToken token, String name,
+            int ownerId, boolean ownerCanAddInternalSystemWindow) {
+        return createWindow(parent, type, token, name, ownerId, ownerCanAddInternalSystemWindow,
+                sWm, mMockSession, mIWindow);
+    }
+
+    static WindowState createWindow(WindowState parent, int type, WindowToken token,
+            String name, int ownerId, boolean ownerCanAddInternalSystemWindow,
+            WindowManagerService service, Session session, IWindow iWindow) {
+        synchronized (service.mWindowMap) {
+            final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
+            attrs.setTitle(name);
+
+            final WindowState w = new WindowState(service, session, iWindow, token, parent,
+                    OP_NONE,
+                    0, attrs, VISIBLE, ownerId, ownerCanAddInternalSystemWindow,
+                    mPowerManagerWrapper);
+            // TODO: Probably better to make this call in the WindowState ctor to avoid errors with
+            // adding it to the token...
+            token.addWindow(w);
+            return w;
+        }
+    }
+
+    /** Creates a {@link TaskStack} and adds it to the specified {@link DisplayContent}. */
+    TaskStack createTaskStackOnDisplay(DisplayContent dc) {
+        synchronized (sWm.mWindowMap) {
+            return createStackControllerOnDisplay(dc).mContainer;
+        }
+    }
+
+    StackWindowController createStackControllerOnDisplay(DisplayContent dc) {
+        synchronized (sWm.mWindowMap) {
+            return createStackControllerOnStackOnDisplay(
+                    WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, dc);
+        }
+    }
+
+    StackWindowController createStackControllerOnStackOnDisplay(
+            int windowingMode, int activityType, DisplayContent dc) {
+        synchronized (sWm.mWindowMap) {
+            final Configuration overrideConfig = new Configuration();
+            overrideConfig.windowConfiguration.setWindowingMode(windowingMode);
+            overrideConfig.windowConfiguration.setActivityType(activityType);
+            final int stackId = ++sNextStackId;
+            final StackWindowController controller = new StackWindowController(stackId, null,
+                    dc.getDisplayId(), true /* onTop */, new Rect(), sWm);
+            controller.onOverrideConfigurationChanged(overrideConfig);
+            return controller;
+        }
+    }
+
+    /** Creates a {@link Task} and adds it to the specified {@link TaskStack}. */
+    Task createTaskInStack(TaskStack stack, int userId) {
+        return WindowTestUtils.createTaskInStack(sWm, stack, userId);
+    }
+
+    /** Creates a {@link DisplayContent} and adds it to the system. */
+    DisplayContent createNewDisplay() {
+        final int displayId = sNextDisplayId++;
+        final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
+                mDisplayInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
+        synchronized (sWm.mWindowMap) {
+            return new DisplayContent(display, sWm, mWallpaperController,
+                    mock(DisplayWindowController.class));
+        }
+    }
+
+    /** Creates a {@link com.android.server.wm.WindowTestUtils.TestWindowState} */
+    WindowTestUtils.TestWindowState createWindowState(WindowManager.LayoutParams attrs,
+            WindowToken token) {
+        synchronized (sWm.mWindowMap) {
+            return new WindowTestUtils.TestWindowState(sWm, mMockSession, mIWindow, attrs, token);
+        }
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
new file mode 100644
index 0000000..e3b7174
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Tests for the {@link WindowToken} class.
+ *
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.wm.WindowTokenTests
+ */
+@SmallTest
+@FlakyTest(bugId = 74078662)
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class WindowTokenTests extends WindowTestsBase {
+
+    @Test
+    public void testAddWindow() throws Exception {
+        final WindowTestUtils.TestWindowToken token =
+                WindowTestUtils.createTestWindowToken(0, mDisplayContent);
+
+        assertEquals(0, token.getWindowsCount());
+
+        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1");
+        final WindowState window11 = createWindow(window1, FIRST_SUB_WINDOW, token, "window11");
+        final WindowState window12 = createWindow(window1, FIRST_SUB_WINDOW, token, "window12");
+        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2");
+        final WindowState window3 = createWindow(null, TYPE_APPLICATION, token, "window3");
+
+        token.addWindow(window1);
+        // NOTE: Child windows will not be added to the token as window containers can only
+        // contain/reference their direct children.
+        token.addWindow(window11);
+        token.addWindow(window12);
+        token.addWindow(window2);
+        token.addWindow(window3);
+
+        // Should not contain the child windows that were added above.
+        assertEquals(3, token.getWindowsCount());
+        assertTrue(token.hasWindow(window1));
+        assertFalse(token.hasWindow(window11));
+        assertFalse(token.hasWindow(window12));
+        assertTrue(token.hasWindow(window2));
+        assertTrue(token.hasWindow(window3));
+    }
+
+    @Test
+    public void testChildRemoval() throws Exception {
+        final DisplayContent dc = mDisplayContent;
+        final WindowTestUtils.TestWindowToken token = WindowTestUtils.createTestWindowToken(0, dc);
+
+        assertEquals(token, dc.getWindowToken(token.token));
+
+        final WindowState window1 = createWindow(null, TYPE_APPLICATION, token, "window1");
+        final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2");
+
+        window2.removeImmediately();
+        // The token should still be mapped in the display content since it still has a child.
+        assertEquals(token, dc.getWindowToken(token.token));
+
+        window1.removeImmediately();
+        // The token should have been removed from the display content since it no longer has a
+        // child.
+        assertEquals(null, dc.getWindowToken(token.token));
+    }
+
+    /**
+     * Test that a window token isn't orphaned by the system when it is requested to be removed.
+     * Tokens should only be removed from the system when all their windows are gone.
+     */
+    @Test
+    public void testTokenRemovalProcess() throws Exception {
+        final WindowTestUtils.TestWindowToken token = WindowTestUtils.createTestWindowToken(
+                TYPE_TOAST, mDisplayContent, true /* persistOnEmpty */);
+
+        // Verify that the token is on the display
+        assertNotNull(mDisplayContent.getWindowToken(token.token));
+
+        final WindowState window1 = createWindow(null, TYPE_TOAST, token, "window1");
+        final WindowState window2 = createWindow(null, TYPE_TOAST, token, "window2");
+
+        mDisplayContent.removeWindowToken(token.token);
+        // Verify that the token is no longer mapped on the display
+        assertNull(mDisplayContent.getWindowToken(token.token));
+        // Verify that the token is still attached to its parent
+        assertNotNull(token.getParent());
+        // Verify that the token windows are still around.
+        assertEquals(2, token.getWindowsCount());
+
+        window1.removeImmediately();
+        // Verify that the token is still attached to its parent
+        assertNotNull(token.getParent());
+        // Verify that the other token window is still around.
+        assertEquals(1, token.getWindowsCount());
+
+        window2.removeImmediately();
+        // Verify that the token is no-longer attached to its parent
+        assertNull(token.getParent());
+        // Verify that the token windows are no longer attached to it.
+        assertEquals(0, token.getWindowsCount());
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTracingTest.java b/services/tests/servicestests/src/com/android/server/wm/WindowTracingTest.java
new file mode 100644
index 0000000..5085254
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTracingTest.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.filters.FlakyTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.internal.util.Preconditions;
+import com.android.server.wm.WindowManagerTraceProto;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Test class for {@link WindowTracing}.
+ *
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.wm.WindowTracingTest
+ */
+@SmallTest
+@FlakyTest(bugId = 74078662)
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class WindowTracingTest extends WindowTestsBase {
+
+    private static final byte[] MAGIC_HEADER = new byte[] {
+        0x9, 0x57, 0x49, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x45,
+    };
+
+    private Context mTestContext;
+    private WindowTracing mWindowTracing;
+    private WindowManagerService mWmMock;
+    private File mFile;
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        mWmMock = mock(WindowManagerService.class);
+
+        mTestContext = InstrumentationRegistry.getContext();
+
+        mFile = mTestContext.getFileStreamPath("tracing_test.dat");
+        mFile.delete();
+
+        mWindowTracing = new WindowTracing(mFile);
+    }
+
+    @Test
+    public void isEnabled_returnsFalseByDefault() throws Exception {
+        assertFalse(mWindowTracing.isEnabled());
+    }
+
+    @Test
+    public void isEnabled_returnsTrueAfterStart() throws Exception {
+        mWindowTracing.startTrace(mock(PrintWriter.class));
+        assertTrue(mWindowTracing.isEnabled());
+    }
+
+    @Test
+    public void isEnabled_returnsFalseAfterStop() throws Exception {
+        mWindowTracing.startTrace(mock(PrintWriter.class));
+        mWindowTracing.stopTrace(mock(PrintWriter.class));
+        assertFalse(mWindowTracing.isEnabled());
+    }
+
+    @Test
+    public void trace_discared_whenNotTracing() throws Exception {
+        mWindowTracing.traceStateLocked("where", mWmMock);
+        verifyZeroInteractions(mWmMock);
+    }
+
+    @Test
+    public void trace_dumpsWindowManagerState_whenTracing() throws Exception {
+        mWindowTracing.startTrace(mock(PrintWriter.class));
+        mWindowTracing.traceStateLocked("where", mWmMock);
+
+        verify(mWmMock).writeToProtoLocked(any(), eq(true));
+    }
+
+    @Test
+    public void traceFile_startsWithMagicHeader() throws Exception {
+        mWindowTracing.startTrace(mock(PrintWriter.class));
+        mWindowTracing.stopTrace(mock(PrintWriter.class));
+
+        byte[] header = new byte[MAGIC_HEADER.length];
+        try (InputStream is = new FileInputStream(mFile)) {
+            assertEquals(MAGIC_HEADER.length, is.read(header));
+            assertArrayEquals(MAGIC_HEADER, header);
+        }
+    }
+
+    @Test
+    @Ignore("Figure out why this test is crashing when setting up mWmMock.")
+    public void tracing_endsUpInFile() throws Exception {
+        mWindowTracing.startTrace(mock(PrintWriter.class));
+
+        doAnswer((inv) -> {
+            inv.<ProtoOutputStream>getArgument(0).write(
+                    WindowManagerTraceProto.WHERE, "TEST_WM_PROTO");
+            return null;
+        }).when(mWmMock).writeToProtoLocked(any(), any());
+        mWindowTracing.traceStateLocked("TEST_WHERE", mWmMock);
+
+        mWindowTracing.stopTrace(mock(PrintWriter.class));
+
+        byte[] file = new byte[1000];
+        int fileLength;
+        try (InputStream is = new FileInputStream(mFile)) {
+            fileLength = is.read(file);
+            assertTrue(containsBytes(file, fileLength,
+                    "TEST_WHERE".getBytes(StandardCharsets.UTF_8)));
+            assertTrue(containsBytes(file, fileLength,
+                    "TEST_WM_PROTO".getBytes(StandardCharsets.UTF_8)));
+        }
+    }
+
+    @Override
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+
+        mFile.delete();
+    }
+
+    /** Return true if {@code needle} appears anywhere in {@code haystack[0..length]} */
+    boolean containsBytes(byte[] haystack, int haystackLenght, byte[] needle) {
+        Preconditions.checkArgument(haystackLenght > 0);
+        Preconditions.checkArgument(needle.length > 0);
+
+        outer: for (int i = 0; i <= haystackLenght - needle.length; i++) {
+            for (int j = 0; j < needle.length; j++) {
+                if (haystack[i+j] != needle[j]) {
+                    continue outer;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void test_containsBytes() {
+        byte[] haystack = "hello_world".getBytes(StandardCharsets.UTF_8);
+        assertTrue(containsBytes(haystack, haystack.length,
+                "hello".getBytes(StandardCharsets.UTF_8)));
+        assertTrue(containsBytes(haystack, haystack.length,
+                "world".getBytes(StandardCharsets.UTF_8)));
+        assertFalse(containsBytes(haystack, 6,
+                "world".getBytes(StandardCharsets.UTF_8)));
+        assertFalse(containsBytes(haystack, haystack.length,
+                "world_".getBytes(StandardCharsets.UTF_8)));
+        assertFalse(containsBytes(haystack, haystack.length,
+                "absent".getBytes(StandardCharsets.UTF_8)));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java
new file mode 100644
index 0000000..547be55
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.filters.FlakyTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.SurfaceControl;
+import android.view.SurfaceSession;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+
+/**
+ * Tests for the {@link WindowLayersController} class.
+ *
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.wm.ZOrderingTests
+ */
+@SmallTest
+@FlakyTest(bugId = 74078662)
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class ZOrderingTests extends WindowTestsBase {
+
+    private class LayerRecordingTransaction extends SurfaceControl.Transaction {
+        HashMap<SurfaceControl, Integer> mLayersForControl = new HashMap();
+        HashMap<SurfaceControl, SurfaceControl> mRelativeLayersForControl = new HashMap();
+
+        @Override
+        public SurfaceControl.Transaction setLayer(SurfaceControl sc, int layer) {
+            mRelativeLayersForControl.remove(sc);
+            mLayersForControl.put(sc, layer);
+            return super.setLayer(sc, layer);
+        }
+
+        @Override
+        public SurfaceControl.Transaction setRelativeLayer(SurfaceControl sc,
+                SurfaceControl relativeTo,
+                int layer) {
+            mRelativeLayersForControl.put(sc, relativeTo);
+            mLayersForControl.put(sc, layer);
+            return super.setRelativeLayer(sc, relativeTo, layer);
+        }
+
+        private int getLayer(SurfaceControl sc) {
+            return mLayersForControl.getOrDefault(sc, 0);
+        }
+
+        private SurfaceControl getRelativeLayer(SurfaceControl sc) {
+            return mRelativeLayersForControl.get(sc);
+        }
+    };
+
+    // We have WM use our Hierarchy recording subclass of SurfaceControl.Builder
+    // such that we can keep track of the parents of Surfaces as they are constructed.
+    private HashMap<SurfaceControl, SurfaceControl> mParentFor = new HashMap();
+
+    private class HierarchyRecorder extends SurfaceControl.Builder {
+        SurfaceControl mPendingParent;
+
+        HierarchyRecorder(SurfaceSession s) {
+            super(s);
+        }
+
+        public SurfaceControl.Builder setParent(SurfaceControl sc) {
+            mPendingParent = sc;
+            return super.setParent(sc);
+        }
+        public SurfaceControl build() {
+            SurfaceControl sc = super.build();
+            mParentFor.put(sc, mPendingParent);
+            mPendingParent = null;
+            return sc;
+        }
+    };
+
+    class HierarchyRecordingBuilderFactory implements SurfaceBuilderFactory {
+        public SurfaceControl.Builder make(SurfaceSession s) {
+            return new HierarchyRecorder(s);
+        }
+    };
+
+    private LayerRecordingTransaction mTransaction;
+
+    @Override
+    void beforeCreateDisplay() {
+        // We can't use @Before here because it may happen after WindowTestsBase @Before
+        // which is after construction of the DisplayContent, meaning the HierarchyRecorder
+        // would miss construction of the top-level layers.
+        mTransaction = new LayerRecordingTransaction();
+        sWm.mSurfaceBuilderFactory = new HierarchyRecordingBuilderFactory();
+        sWm.mTransactionFactory = () -> mTransaction;
+    }
+
+    @After
+    public void after() {
+        mTransaction.close();
+        mParentFor.clear();
+    }
+
+    LinkedList<SurfaceControl> getAncestors(LayerRecordingTransaction t, SurfaceControl sc) {
+        LinkedList<SurfaceControl> p = new LinkedList();
+        SurfaceControl current = sc;
+        do {
+            p.addLast(current);
+
+            SurfaceControl rs = t.getRelativeLayer(current);
+            if (rs != null) {
+                current = rs;
+            } else {
+                current = mParentFor.get(current);
+            }
+        } while (current != null);
+        return p;
+    }
+
+
+    void assertZOrderGreaterThan(LayerRecordingTransaction t, SurfaceControl left,
+            SurfaceControl right) throws Exception {
+        final LinkedList<SurfaceControl> leftParentChain = getAncestors(t, left);
+        final LinkedList<SurfaceControl> rightParentChain = getAncestors(t, right);
+
+        SurfaceControl commonAncestor = null;
+        SurfaceControl leftTop = leftParentChain.peekLast();
+        SurfaceControl rightTop = rightParentChain.peekLast();
+        while (leftTop != null && rightTop != null && leftTop == rightTop) {
+            commonAncestor = leftParentChain.removeLast();
+            rightParentChain.removeLast();
+            leftTop = leftParentChain.peekLast();
+            rightTop = rightParentChain.peekLast();
+        }
+
+        if (rightTop == null) { // right is the parent of left.
+            assertGreaterThan(t.getLayer(leftTop), 0);
+        } else if (leftTop == null) { // left is the parent of right.
+            assertGreaterThan(0, t.getLayer(rightTop));
+        } else {
+            assertGreaterThan(t.getLayer(leftTop),
+                    t.getLayer(rightTop));
+        }
+    }
+
+    void assertWindowHigher(WindowState left, WindowState right) throws Exception {
+        assertZOrderGreaterThan(mTransaction, left.getSurfaceControl(), right.getSurfaceControl());
+    }
+
+    WindowState createWindow(String name) {
+        return createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, name);
+    }
+
+    @Test
+    public void testAssignWindowLayers_ForImeWithNoTarget() throws Exception {
+        sWm.mInputMethodTarget = null;
+        mDisplayContent.assignChildLayers(mTransaction);
+
+        // The Ime has an higher base layer than app windows and lower base layer than system
+        // windows, so it should be above app windows and below system windows if there isn't an IME
+        // target.
+        assertWindowHigher(mImeWindow, mChildAppWindowAbove);
+        assertWindowHigher(mImeWindow, mAppWindow);
+        assertWindowHigher(mNavBarWindow, mImeWindow);
+        assertWindowHigher(mStatusBarWindow, mImeWindow);
+
+        // And, IME dialogs should always have an higher layer than the IME.
+        assertWindowHigher(mImeDialogWindow, mImeWindow);
+    }
+
+    @Test
+    public void testAssignWindowLayers_ForImeWithAppTarget() throws Exception {
+        final WindowState imeAppTarget = createWindow("imeAppTarget");
+        sWm.mInputMethodTarget = imeAppTarget;
+
+        mDisplayContent.assignChildLayers(mTransaction);
+
+        // Ime should be above all app windows and below system windows if it is targeting an app
+        // window.
+        assertWindowHigher(mImeWindow, imeAppTarget);
+        assertWindowHigher(mImeWindow, mChildAppWindowAbove);
+        assertWindowHigher(mImeWindow, mAppWindow);
+        assertWindowHigher(mNavBarWindow, mImeWindow);
+        assertWindowHigher(mStatusBarWindow, mImeWindow);
+
+        // And, IME dialogs should always have an higher layer than the IME.
+        assertWindowHigher(mImeDialogWindow, mImeWindow);
+    }
+
+    @Test
+    public void testAssignWindowLayers_ForImeWithAppTargetWithChildWindows() throws Exception {
+        final WindowState imeAppTarget = createWindow("imeAppTarget");
+        final WindowState imeAppTargetChildAboveWindow = createWindow(imeAppTarget,
+                TYPE_APPLICATION_ATTACHED_DIALOG, imeAppTarget.mToken,
+                "imeAppTargetChildAboveWindow");
+        final WindowState imeAppTargetChildBelowWindow = createWindow(imeAppTarget,
+                TYPE_APPLICATION_MEDIA_OVERLAY, imeAppTarget.mToken,
+                "imeAppTargetChildBelowWindow");
+
+        sWm.mInputMethodTarget = imeAppTarget;
+        mDisplayContent.assignChildLayers(mTransaction);
+
+        // Ime should be above all app windows except for child windows that are z-ordered above it
+        // and below system windows if it is targeting an app window.
+        assertWindowHigher(mImeWindow, imeAppTarget);
+        assertWindowHigher(imeAppTargetChildAboveWindow, mImeWindow);
+        assertWindowHigher(mImeWindow, mChildAppWindowAbove);
+        assertWindowHigher(mImeWindow, mAppWindow);
+        assertWindowHigher(mNavBarWindow, mImeWindow);
+        assertWindowHigher(mStatusBarWindow, mImeWindow);
+
+        // And, IME dialogs should always have an higher layer than the IME.
+        assertWindowHigher(mImeDialogWindow, mImeWindow);
+    }
+
+    @Test
+    public void testAssignWindowLayers_ForImeWithAppTargetAndAppAbove() throws Exception {
+        final WindowState appBelowImeTarget = createWindow("appBelowImeTarget");
+        final WindowState imeAppTarget = createWindow("imeAppTarget");
+        final WindowState appAboveImeTarget = createWindow("appAboveImeTarget");
+
+        sWm.mInputMethodTarget = imeAppTarget;
+        mDisplayContent.assignChildLayers(mTransaction);
+
+        // Ime should be above all app windows except for non-fullscreen app window above it and
+        // below system windows if it is targeting an app window.
+        assertWindowHigher(mImeWindow, imeAppTarget);
+        assertWindowHigher(mImeWindow, appBelowImeTarget);
+        assertWindowHigher(appAboveImeTarget, mImeWindow);
+        assertWindowHigher(mImeWindow, mChildAppWindowAbove);
+        assertWindowHigher(mImeWindow, mAppWindow);
+        assertWindowHigher(mNavBarWindow, mImeWindow);
+        assertWindowHigher(mStatusBarWindow, mImeWindow);
+
+        // And, IME dialogs should always have an higher layer than the IME.
+        assertWindowHigher(mImeDialogWindow, mImeWindow);
+    }
+
+    @Test
+    public void testAssignWindowLayers_ForImeNonAppImeTarget() throws Exception {
+        final WindowState imeSystemOverlayTarget = createWindow(null, TYPE_SYSTEM_OVERLAY,
+                mDisplayContent, "imeSystemOverlayTarget",
+                true /* ownerCanAddInternalSystemWindow */);
+
+        sWm.mInputMethodTarget = imeSystemOverlayTarget;
+        mDisplayContent.assignChildLayers(mTransaction);
+
+        // The IME target base layer is higher than all window except for the nav bar window, so the
+        // IME should be above all windows except for the nav bar.
+        assertWindowHigher(mImeWindow, imeSystemOverlayTarget);
+        assertWindowHigher(mImeWindow, mChildAppWindowAbove);
+        assertWindowHigher(mImeWindow, mAppWindow);
+        assertWindowHigher(mImeWindow, mDockedDividerWindow);
+
+        // The IME has a higher base layer than the status bar so we may expect it to go
+        // above the status bar once they are both in the Non-App layer, as past versions of this
+        // test enforced. However this seems like the wrong behavior unless the status bar is the
+        // IME target.
+        assertWindowHigher(mNavBarWindow, mImeWindow);
+        assertWindowHigher(mStatusBarWindow, mImeWindow);
+
+        // And, IME dialogs should always have an higher layer than the IME.
+        assertWindowHigher(mImeDialogWindow, mImeWindow);
+    }
+
+    @Test
+    public void testAssignWindowLayers_ForStatusBarImeTarget() throws Exception {
+        sWm.mInputMethodTarget = mStatusBarWindow;
+        mDisplayContent.assignChildLayers(mTransaction);
+
+        assertWindowHigher(mImeWindow, mChildAppWindowAbove);
+        assertWindowHigher(mImeWindow, mAppWindow);
+        assertWindowHigher(mImeWindow, mDockedDividerWindow);
+        assertWindowHigher(mImeWindow, mStatusBarWindow);
+
+        // And, IME dialogs should always have an higher layer than the IME.
+        assertWindowHigher(mImeDialogWindow, mImeWindow);
+    }
+
+    @Test
+    public void testStackLayers() throws Exception {
+        final WindowState anyWindow1 = createWindow("anyWindow");
+        final WindowState pinnedStackWindow = createWindowOnStack(null, WINDOWING_MODE_PINNED,
+                ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION, mDisplayContent,
+                "pinnedStackWindow");
+        final WindowState dockedStackWindow = createWindowOnStack(null,
+                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION,
+                mDisplayContent, "dockedStackWindow");
+        final WindowState assistantStackWindow = createWindowOnStack(null, WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_ASSISTANT, TYPE_BASE_APPLICATION,
+                mDisplayContent, "assistantStackWindow");
+        final WindowState homeActivityWindow = createWindowOnStack(null, WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_HOME, TYPE_BASE_APPLICATION,
+                mDisplayContent, "homeActivityWindow");
+        final WindowState anyWindow2 = createWindow("anyWindow2");
+
+        mDisplayContent.assignChildLayers(mTransaction);
+
+        assertWindowHigher(dockedStackWindow, homeActivityWindow);
+        assertWindowHigher(assistantStackWindow, homeActivityWindow);
+        assertWindowHigher(pinnedStackWindow, homeActivityWindow);
+        assertWindowHigher(anyWindow1, homeActivityWindow);
+        assertWindowHigher(anyWindow2, homeActivityWindow);
+        assertWindowHigher(pinnedStackWindow, anyWindow1);
+        assertWindowHigher(pinnedStackWindow, anyWindow2);
+        assertWindowHigher(pinnedStackWindow, dockedStackWindow);
+        assertWindowHigher(pinnedStackWindow, assistantStackWindow);
+    }
+
+    @Test
+    public void testAssignWindowLayers_ForSysUiPanels() throws Exception {
+        final WindowState navBarPanel =
+                createWindow(null, TYPE_NAVIGATION_BAR_PANEL, mDisplayContent, "NavBarPanel");
+        final WindowState statusBarPanel =
+                createWindow(null, TYPE_STATUS_BAR_PANEL, mDisplayContent, "StatusBarPanel");
+        final WindowState statusBarSubPanel =
+                createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, mDisplayContent, "StatusBarSubPanel");
+        mDisplayContent.assignChildLayers(mTransaction);
+
+        // Ime should be above all app windows and below system windows if it is targeting an app
+        // window.
+        assertWindowHigher(navBarPanel, mNavBarWindow);
+        assertWindowHigher(statusBarPanel, mStatusBarWindow);
+        assertWindowHigher(statusBarSubPanel, statusBarPanel);
+    }
+
+    @Test
+    public void testAssignWindowLayers_ForNegativelyZOrderedSubtype() throws Exception {
+        // TODO(b/70040778): We should aim to eliminate the last user of TYPE_APPLICATION_MEDIA
+        // then we can drop all negative layering on the windowing side.
+
+        final WindowState anyWindow = createWindow("anyWindow");
+        final WindowState child = createWindow(anyWindow, TYPE_APPLICATION_MEDIA, mDisplayContent,
+                "TypeApplicationMediaChild");
+        final WindowState mediaOverlayChild = createWindow(anyWindow, TYPE_APPLICATION_MEDIA_OVERLAY,
+                mDisplayContent, "TypeApplicationMediaOverlayChild");
+
+        mDisplayContent.assignChildLayers(mTransaction);
+
+        assertWindowHigher(anyWindow, mediaOverlayChild);
+        assertWindowHigher(mediaOverlayChild, child);
+    }
+
+    @Test
+    public void testDockedDividerPosition() throws Exception {
+        final WindowState pinnedStackWindow = createWindowOnStack(null, WINDOWING_MODE_PINNED,
+                ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION, mDisplayContent,
+                "pinnedStackWindow");
+        final WindowState splitScreenWindow = createWindowOnStack(null,
+                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION,
+                mDisplayContent, "splitScreenWindow");
+        final WindowState splitScreenSecondaryWindow = createWindowOnStack(null,
+                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
+                TYPE_BASE_APPLICATION, mDisplayContent, "splitScreenSecondaryWindow");
+        final WindowState assistantStackWindow = createWindowOnStack(null, WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_ASSISTANT, TYPE_BASE_APPLICATION,
+                mDisplayContent, "assistantStackWindow");
+
+        mDisplayContent.assignChildLayers(mTransaction);
+
+        assertWindowHigher(mDockedDividerWindow, splitScreenWindow);
+        assertWindowHigher(mDockedDividerWindow, splitScreenSecondaryWindow);
+        assertWindowHigher(pinnedStackWindow, mDockedDividerWindow);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/utils/CoordinateTransformsTest.java b/services/tests/servicestests/src/com/android/server/wm/utils/CoordinateTransformsTest.java
new file mode 100644
index 0000000..40a10e0
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/utils/CoordinateTransformsTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.utils;
+
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
+
+import static com.android.server.wm.utils.CoordinateTransforms.transformPhysicalToLogicalCoordinates;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.*;
+
+import android.graphics.Matrix;
+import android.graphics.Point;
+import android.graphics.PointF;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ErrorCollector;
+
+public class CoordinateTransformsTest {
+
+    private static final int W = 200;
+    private static final int H = 400;
+
+    private final Matrix mMatrix = new Matrix();
+
+    @Rule
+    public final ErrorCollector mErrorCollector = new ErrorCollector();
+
+    @Before
+    public void setUp() throws Exception {
+        mMatrix.setTranslate(0xdeadbeef, 0xdeadbeef);
+    }
+
+    @Test
+    public void transformPhysicalToLogicalCoordinates_rot0() throws Exception {
+        transformPhysicalToLogicalCoordinates(ROTATION_0, W, H, mMatrix);
+        assertThat(mMatrix, is(Matrix.IDENTITY_MATRIX));
+    }
+
+    @Test
+    public void transformPhysicalToLogicalCoordinates_rot90() throws Exception {
+        transformPhysicalToLogicalCoordinates(ROTATION_90, W, H, mMatrix);
+
+        checkDevicePoint(0, 0).mapsToLogicalPoint(0, W);
+        checkDevicePoint(W, H).mapsToLogicalPoint(H, 0);
+    }
+
+    @Test
+    public void transformPhysicalToLogicalCoordinates_rot180() throws Exception {
+        transformPhysicalToLogicalCoordinates(ROTATION_180, W, H, mMatrix);
+
+        checkDevicePoint(0, 0).mapsToLogicalPoint(W, H);
+        checkDevicePoint(W, H).mapsToLogicalPoint(0, 0);
+    }
+
+    @Test
+    public void transformPhysicalToLogicalCoordinates_rot270() throws Exception {
+        transformPhysicalToLogicalCoordinates(ROTATION_270, W, H, mMatrix);
+
+        checkDevicePoint(0, 0).mapsToLogicalPoint(H, 0);
+        checkDevicePoint(W, H).mapsToLogicalPoint(0, W);
+    }
+
+    private DevicePointAssertable checkDevicePoint(int x, int y) {
+        final Point devicePoint = new Point(x, y);
+        final float[] fs = new float[] {x, y};
+        mMatrix.mapPoints(fs);
+        final PointF transformedPoint = new PointF(fs[0], fs[1]);
+
+        return (expectedX, expectedY) -> {
+            mErrorCollector.checkThat("t(" + devicePoint + ")",
+                    transformedPoint, is(new PointF(expectedX, expectedY)));
+        };
+    }
+
+    public interface DevicePointAssertable {
+        void mapsToLogicalPoint(int x, int y);
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java b/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java
new file mode 100644
index 0000000..d0f0fe3
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm.utils;
+
+import static junit.framework.Assert.assertEquals;
+
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Pair;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class InsetUtilsTest {
+
+    @Test
+    public void testAdd() throws Exception {
+        final Rect rect1 = new Rect(10, 20, 30, 40);
+        final Rect rect2 = new Rect(50, 60, 70, 80);
+        InsetUtils.addInsets(rect1, rect2);
+        assertEquals(new Rect(60, 80, 100, 120), rect1);
+    }
+}
+
diff --git a/services/tests/servicestests/src/com/android/server/wm/utils/RotationCacheTest.java b/services/tests/servicestests/src/com/android/server/wm/utils/RotationCacheTest.java
new file mode 100644
index 0000000..6bbc7eb
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/utils/RotationCacheTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.utils;
+
+import static android.util.Pair.create;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Pair;
+
+import com.android.server.wm.utils.RotationCache.RotationDependentComputation;
+
+import org.hamcrest.Matchers;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@FlakyTest(bugId = 74078662)
+@Presubmit
+public class RotationCacheTest {
+
+    private RotationCache<Object, Pair<Object, Integer>> mCache;
+    private boolean mComputationCalled;
+
+    @Before
+    public void setUp() throws Exception {
+        mComputationCalled = false;
+        mCache = new RotationCache<>((o, rot) -> {
+            mComputationCalled = true;
+            return create(o, rot);
+        });
+    }
+
+    @Test
+    public void getOrCompute_computes() throws Exception {
+        assertThat(mCache.getOrCompute("hello", 0), equalTo(create("hello", 0)));
+        assertThat(mCache.getOrCompute("hello", 1), equalTo(create("hello", 1)));
+        assertThat(mCache.getOrCompute("hello", 2), equalTo(create("hello", 2)));
+        assertThat(mCache.getOrCompute("hello", 3), equalTo(create("hello", 3)));
+    }
+
+    @Test
+    public void getOrCompute_sameParam_sameRot_hitsCache() throws Exception {
+        assertNotNull(mCache.getOrCompute("hello", 1));
+
+        mComputationCalled = false;
+        assertThat(mCache.getOrCompute("hello", 1), equalTo(create("hello", 1)));
+        assertThat(mComputationCalled, is(false));
+    }
+
+    @Test
+    public void getOrCompute_sameParam_hitsCache_forAllRots() throws Exception {
+        assertNotNull(mCache.getOrCompute("hello", 3));
+        assertNotNull(mCache.getOrCompute("hello", 2));
+        assertNotNull(mCache.getOrCompute("hello", 1));
+        assertNotNull(mCache.getOrCompute("hello", 0));
+
+        mComputationCalled = false;
+        assertThat(mCache.getOrCompute("hello", 1), equalTo(create("hello", 1)));
+        assertThat(mCache.getOrCompute("hello", 0), equalTo(create("hello", 0)));
+        assertThat(mCache.getOrCompute("hello", 2), equalTo(create("hello", 2)));
+        assertThat(mCache.getOrCompute("hello", 3), equalTo(create("hello", 3)));
+        assertThat(mComputationCalled, is(false));
+    }
+
+    @Test
+    public void getOrCompute_changingParam_recomputes() throws Exception {
+        assertNotNull(mCache.getOrCompute("hello", 1));
+
+        assertThat(mCache.getOrCompute("world", 1), equalTo(create("world", 1)));
+    }
+
+    @Test
+    public void getOrCompute_changingParam_clearsCacheForDifferentRots() throws Exception {
+        assertNotNull(mCache.getOrCompute("hello", 1));
+        assertNotNull(mCache.getOrCompute("world", 2));
+
+        mComputationCalled = false;
+        assertThat(mCache.getOrCompute("hello", 1), equalTo(create("hello", 1)));
+        assertThat(mComputationCalled, is(true));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/utils/WmDisplayCutoutTest.java b/services/tests/servicestests/src/com/android/server/wm/utils/WmDisplayCutoutTest.java
new file mode 100644
index 0000000..f7addf6
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/utils/WmDisplayCutoutTest.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.utils;
+
+
+import static android.view.DisplayCutout.NO_CUTOUT;
+import static android.view.DisplayCutout.fromBoundingRect;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Size;
+import android.view.DisplayCutout;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+/**
+ * Tests for {@link WmDisplayCutout}
+ *
+ * Run with: atest WmDisplayCutoutTest
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class WmDisplayCutoutTest {
+
+    private final DisplayCutout mCutoutTop = new DisplayCutout(
+            new Rect(0, 100, 0, 0),
+            Arrays.asList(new Rect(50, 0, 75, 100)));
+
+    @Test
+    public void calculateRelativeTo_top() {
+        WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
+                fromBoundingRect(0, 0, 100, 20), 200, 400)
+                .calculateRelativeTo(new Rect(5, 5, 95, 195));
+
+        assertEquals(new Rect(0, 15, 0, 0), cutout.getDisplayCutout().getSafeInsets());
+    }
+
+    @Test
+    public void calculateRelativeTo_left() {
+        WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
+                fromBoundingRect(0, 0, 20, 100), 400, 200)
+                .calculateRelativeTo(new Rect(5, 5, 195, 95));
+
+        assertEquals(new Rect(15, 0, 0, 0), cutout.getDisplayCutout().getSafeInsets());
+    }
+
+    @Test
+    public void calculateRelativeTo_bottom() {
+        WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
+                fromBoundingRect(0, 180, 100, 200), 100, 200)
+                .calculateRelativeTo(new Rect(5, 5, 95, 195));
+
+        assertEquals(new Rect(0, 0, 0, 15), cutout.getDisplayCutout().getSafeInsets());
+    }
+
+    @Test
+    public void calculateRelativeTo_right() {
+        WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
+                fromBoundingRect(180, 0, 200, 100), 200, 100)
+                .calculateRelativeTo(new Rect(5, 5, 195, 95));
+
+        assertEquals(new Rect(0, 0, 15, 0), cutout.getDisplayCutout().getSafeInsets());
+    }
+
+    @Test
+    public void calculateRelativeTo_bounds() {
+        WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
+                fromBoundingRect(0, 0, 100, 20), 200, 400)
+                .calculateRelativeTo(new Rect(5, 10, 95, 180));
+
+        assertEquals(new Rect(-5, -10, 95, 10), cutout.getDisplayCutout().getBounds().getBounds());
+    }
+
+    @Test
+    public void computeSafeInsets_top() {
+        WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
+                fromBoundingRect(0, 0, 100, 20), 200, 400);
+
+        assertEquals(new Rect(0, 20, 0, 0), cutout.getDisplayCutout().getSafeInsets());
+    }
+
+    @Test
+    public void computeSafeInsets_left() {
+        WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
+                fromBoundingRect(0, 0, 20, 100), 400, 200);
+
+        assertEquals(new Rect(20, 0, 0, 0), cutout.getDisplayCutout().getSafeInsets());
+    }
+
+    @Test
+    public void computeSafeInsets_bottom() {
+        WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
+                fromBoundingRect(0, 180, 100, 200), 100, 200);
+
+        assertEquals(new Rect(0, 0, 0, 20), cutout.getDisplayCutout().getSafeInsets());
+    }
+
+    @Test
+    public void computeSafeInsets_right() {
+        WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
+                fromBoundingRect(180, 0, 200, 100), 200, 100);
+
+        assertEquals(new Rect(0, 0, 20, 0), cutout.getDisplayCutout().getSafeInsets());
+    }
+
+    @Test
+    public void computeSafeInsets_bounds() {
+        DisplayCutout cutout = WmDisplayCutout.computeSafeInsets(mCutoutTop, 1000,
+                2000).getDisplayCutout();
+
+        assertEquals(mCutoutTop.getBounds().getBounds(),
+                cutout.getBounds().getBounds());
+    }
+
+    @Test
+    public void test_equals() {
+        assertEquals(new WmDisplayCutout(NO_CUTOUT, null), new WmDisplayCutout(NO_CUTOUT, null));
+        assertEquals(new WmDisplayCutout(mCutoutTop, new Size(1, 2)),
+                new WmDisplayCutout(mCutoutTop, new Size(1, 2)));
+
+        assertNotEquals(new WmDisplayCutout(mCutoutTop, new Size(1, 2)),
+                new WmDisplayCutout(mCutoutTop, new Size(5, 6)));
+        assertNotEquals(new WmDisplayCutout(mCutoutTop, new Size(1, 2)),
+                new WmDisplayCutout(NO_CUTOUT, new Size(1, 2)));
+    }
+
+    @Test
+    public void test_hashCode() {
+        assertEquals(new WmDisplayCutout(NO_CUTOUT, null).hashCode(),
+                new WmDisplayCutout(NO_CUTOUT, null).hashCode());
+        assertEquals(new WmDisplayCutout(mCutoutTop, new Size(1, 2)).hashCode(),
+                new WmDisplayCutout(mCutoutTop, new Size(1, 2)).hashCode());
+    }
+}
\ No newline at end of file
