Added foundation for supporting unit tests in WindowManager

- Check for null where appropriate when using WM from a test
- Inject WindowManagerPolicy for test can have its own policy
- Added skeleton for WindowStateTests that will contain tests
for WindowState class.

Bug: 30060889
Change-Id: I0cd7d50c98de16c7412759401075c4bb48d13dfe
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index fba439f..d76f19a 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -30,6 +30,7 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.graphics.Region.Op;
+import android.hardware.display.DisplayManagerInternal;
 import android.util.DisplayMetrics;
 import android.util.Slog;
 import android.view.Display;
@@ -200,12 +201,15 @@
     }
 
     void initializeDisplayBaseInfo() {
-        // Bootstrap the default logical display from the display manager.
-        final DisplayInfo newDisplayInfo =
-                mService.mDisplayManagerInternal.getDisplayInfo(mDisplayId);
-        if (newDisplayInfo != null) {
-            mDisplayInfo.copyFrom(newDisplayInfo);
+        final DisplayManagerInternal displayManagerInternal = mService.mDisplayManagerInternal;
+        if (displayManagerInternal != null) {
+            // Bootstrap the default logical display from the display manager.
+            final DisplayInfo newDisplayInfo = displayManagerInternal.getDisplayInfo(mDisplayId);
+            if (newDisplayInfo != null) {
+                mDisplayInfo.copyFrom(newDisplayInfo);
+            }
         }
+
         mBaseDisplayWidth = mInitialDisplayWidth = mDisplayInfo.logicalWidth;
         mBaseDisplayHeight = mInitialDisplayHeight = mDisplayInfo.logicalHeight;
         mBaseDisplayDensity = mInitialDisplayDensity = mDisplayInfo.logicalDensityDpi;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b9f1df4..eb27a15 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -389,7 +389,7 @@
 
     final boolean mLimitedAlphaCompositing;
 
-    final WindowManagerPolicy mPolicy = new PhoneWindowManager();
+    final WindowManagerPolicy mPolicy;
 
     final IActivityManager mActivityManager;
     final ActivityManagerInternal mAmInternal;
@@ -925,14 +925,11 @@
     public static WindowManagerService main(final Context context,
             final InputManagerService im,
             final boolean haveInputMethods, final boolean showBootMsgs,
-            final boolean onlyCore) {
+            final boolean onlyCore, WindowManagerPolicy policy) {
         final WindowManagerService[] holder = new WindowManagerService[1];
-        DisplayThread.getHandler().runWithScissors(new Runnable() {
-            @Override
-            public void run() {
-                holder[0] = new WindowManagerService(context, im,
-                        haveInputMethods, showBootMsgs, onlyCore);
-            }
+        DisplayThread.getHandler().runWithScissors(() -> {
+            holder[0] = new WindowManagerService(context, im, haveInputMethods, showBootMsgs,
+                    onlyCore, policy);
         }, 0);
         return holder[0];
     }
@@ -949,7 +946,8 @@
     }
 
     private WindowManagerService(Context context, InputManagerService inputManager,
-            boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
+            boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore,
+            WindowManagerPolicy policy) {
         mContext = context;
         mHaveInputMethods = haveInputMethods;
         mAllowBootMessages = showBootMsgs;
@@ -972,10 +970,12 @@
         mWallpaperControllerLocked = new WallpaperController(this);
         mWindowPlacerLocked = new WindowSurfacePlacer(this);
         mLayersController = new WindowLayersController(this);
+        mPolicy = policy;
 
         LocalServices.addService(WindowManagerPolicy.class, mPolicy);
 
-        mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG_WM));
+        mPointerEventDispatcher = mInputManager != null
+                ? new PointerEventDispatcher(mInputManager.monitorInput(TAG_WM)) : null;
 
         mFxSession = new SurfaceSession();
         mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
@@ -988,19 +988,18 @@
 
         mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
         mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
-        mPowerManagerInternal.registerLowPowerModeObserver(
-                new PowerManagerInternal.LowPowerModeListener() {
-            @Override
-            public void onLowPowerModeChanged(boolean enabled) {
+
+        if (mPowerManagerInternal != null) {
+            mPowerManagerInternal.registerLowPowerModeObserver((enabled) -> {
                 synchronized (mWindowMap) {
                     if (mAnimationsDisabled != enabled && !mAllowAnimationsInLowPowerMode) {
                         mAnimationsDisabled = enabled;
                         dispatchNewAnimatorScaleLocked(null);
                     }
                 }
-            }
-        });
-        mAnimationsDisabled = mPowerManagerInternal.getLowPowerModeEnabled();
+            });
+            mAnimationsDisabled = mPowerManagerInternal.getLowPowerModeEnabled();
+        }
         mScreenFrozenLock = mPowerManager.newWakeLock(
                 PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");
         mScreenFrozenLock.setReferenceCounted(false);
@@ -2032,8 +2031,8 @@
                 addToken = true;
             }
 
-            WindowState win = new WindowState(this, session, client, token,
-                    attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
+            WindowState win = new WindowState(this, session, client, token, attachedWindow,
+                    appOp[0], seq, attrs, viewVisibility, displayContent, session.mUid);
             if (win.mDeathRecipient == null) {
                 // Client has apparently died, so there is no reason to
                 // continue.
@@ -10857,14 +10856,16 @@
         displayInfo.overscanTop = rect.top;
         displayInfo.overscanRight = rect.right;
         displayInfo.overscanBottom = rect.bottom;
-        mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(displayId, displayInfo);
-        configureDisplayPolicyLocked(displayContent);
+        if (mDisplayManagerInternal != null) {
+            mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(displayId, displayInfo);
+            configureDisplayPolicyLocked(displayContent);
 
-        // TODO: Create an input channel for each display with touch capability.
-        if (displayId == Display.DEFAULT_DISPLAY) {
-            displayContent.mTapDetector = new TaskTapPointerEventListener(this, displayContent);
-            registerPointerEventListener(displayContent.mTapDetector);
-            registerPointerEventListener(mMousePositionTracker);
+            // TODO: Create an input channel for each display with touch capability.
+            if (displayId == Display.DEFAULT_DISPLAY) {
+                displayContent.mTapDetector = new TaskTapPointerEventListener(this, displayContent);
+                registerPointerEventListener(displayContent.mTapDetector);
+                registerPointerEventListener(mMousePositionTracker);
+            }
         }
 
         return displayContent;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 04af545..e38c1a3 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -505,13 +505,13 @@
 
     WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
            WindowState parentWindow, int appOp, int seq, WindowManager.LayoutParams a,
-           int viewVisibility, final DisplayContent displayContent) {
+           int viewVisibility, final DisplayContent displayContent, int ownerId) {
         mService = service;
         mSession = s;
         mClient = c;
         mAppOp = appOp;
         mToken = token;
-        mOwnerUid = s.mUid;
+        mOwnerUid = ownerId;
         mWindowId = new IWindowId.Stub() {
             @Override
             public void registerFocusObserver(IWindowFocusObserver observer) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 00cd07e..75b4dae 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -86,6 +86,7 @@
 import com.android.server.pm.PackageManagerService;
 import com.android.server.pm.ShortcutService;
 import com.android.server.pm.UserManagerService;
+import com.android.server.policy.PhoneWindowManager;
 import com.android.server.power.PowerManagerService;
 import com.android.server.power.ShutdownThread;
 import com.android.server.restrictions.RestrictionsManagerService;
@@ -616,7 +617,7 @@
             traceBeginAndSlog("StartWindowManagerService");
             wm = WindowManagerService.main(context, inputManager,
                     mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
-                    !mFirstBoot, mOnlyCore);
+                    !mFirstBoot, mOnlyCore, new PhoneWindowManager());
             ServiceManager.addService(Context.WINDOW_SERVICE, wm);
             ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
             Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
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..1514e69
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java
@@ -0,0 +1,110 @@
+/*
+ * 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.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+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, Configuration newConfig,
+            Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar)
+            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 {
+
+    }
+}
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..3bb797e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -0,0 +1,555 @@
+/*
+ * 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.policy.IShortcutService;
+
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+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.view.Display;
+import android.view.IWindowManager;
+import android.view.KeyEvent;
+import android.view.Surface;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManagerPolicy;
+import android.view.animation.Animation;
+
+import java.io.PrintWriter;
+
+public class TestWindowManagerPolicy implements WindowManagerPolicy {
+
+    @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 void setDisplayOverscan(Display display, int left, int top, int right, int bottom) {
+
+    }
+
+    @Override
+    public int checkAddPermission(WindowManager.LayoutParams attrs, int[] outAppOp) {
+        return 0;
+    }
+
+    @Override
+    public boolean checkShowToOwnerOnly(WindowManager.LayoutParams attrs) {
+        return false;
+    }
+
+    @Override
+    public void adjustWindowParamsLw(WindowManager.LayoutParams attrs) {
+
+    }
+
+    @Override
+    public void adjustConfigurationLw(Configuration config, int keyboardPresence,
+            int navigationPresence) {
+
+    }
+
+    @Override
+    public int windowTypeToLayerLw(int type) {
+        return 0;
+    }
+
+    @Override
+    public int subWindowTypeToLayerLw(int type) {
+        return 0;
+    }
+
+    @Override
+    public int getMaxWallpaperLayer() {
+        return 0;
+    }
+
+    @Override
+    public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode) {
+        return 0;
+    }
+
+    @Override
+    public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode) {
+        return 0;
+    }
+
+    @Override
+    public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode) {
+        return 0;
+    }
+
+    @Override
+    public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode) {
+        return 0;
+    }
+
+    @Override
+    public boolean isForceHiding(WindowManager.LayoutParams attrs) {
+        return false;
+    }
+
+    @Override
+    public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) {
+        return false;
+    }
+
+    @Override
+    public boolean canBeForceHidden(WindowState win,
+            WindowManager.LayoutParams attrs) {
+        return false;
+    }
+
+    @Override
+    public WindowState getWinShowWhenLockedLw() {
+        return null;
+    }
+
+    @Override
+    public View addStartingWindow(IBinder appToken, String packageName, int theme,
+            CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, int icon,
+            int logo, int windowFlags, Configuration overrideConfig) {
+        return null;
+    }
+
+    @Override
+    public void removeStartingWindow(IBinder appToken, View window) {
+
+    }
+
+    @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 createForceHideEnterAnimation(boolean onWallpaper,
+            boolean goingToNotificationShade) {
+        return null;
+    }
+
+    @Override
+    public Animation createForceHideWallpaperExitAnimation(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 void beginLayoutLw(boolean isDefaultDisplay, int displayWidth, int displayHeight,
+            int displayRotation, int uiMode) {
+
+    }
+
+    @Override
+    public int getSystemDecorLayerLw() {
+        return 0;
+    }
+
+    @Override
+    public void getContentRectLw(Rect r) {
+
+    }
+
+    @Override
+    public void layoutWindowLw(WindowState win,
+            WindowState attached) {
+
+    }
+
+    @Override
+    public boolean getInsetHintLw(WindowManager.LayoutParams attrs, Rect taskBounds,
+            int displayRotation, int displayWidth, int displayHeight, Rect outContentInsets,
+            Rect outStableInsets, Rect outOutsets) {
+        return false;
+    }
+
+    @Override
+    public void finishLayoutLw() {
+
+    }
+
+    @Override
+    public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) {
+
+    }
+
+    @Override
+    public void applyPostLayoutPolicyLw(WindowState win,
+            WindowManager.LayoutParams attrs, WindowState attached) {
+
+    }
+
+    @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 screenTurnedOff() {
+
+    }
+
+    @Override
+    public boolean isScreenOn() {
+        return false;
+    }
+
+    @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 false;
+    }
+
+    @Override
+    public boolean isKeyguardSecure(int userId) {
+        return false;
+    }
+
+    @Override
+    public boolean isKeyguardShowingOrOccluded() {
+        return false;
+    }
+
+    @Override
+    public boolean isKeyguardShowingAndNotOccluded() {
+        return false;
+    }
+
+    @Override
+    public boolean inKeyguardRestrictedKeyInputMode() {
+        return false;
+    }
+
+    @Override
+    public void dismissKeyguardLw() {
+
+    }
+
+    @Override
+    public void notifyActivityDrawnForKeyguardLw() {
+
+    }
+
+    @Override
+    public boolean isKeyguardDrawnLw() {
+        return false;
+    }
+
+    @Override
+    public int rotationForOrientationLw(int orientation,
+            int lastRotation) {
+        return 0;
+    }
+
+    @Override
+    public boolean rotationHasCompatibleMetricsLw(int orientation,
+            int rotation) {
+        return false;
+    }
+
+    @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(boolean fromHome) {
+
+    }
+
+    @Override
+    public void showGlobalActions() {
+
+    }
+
+    @Override
+    public int getInputMethodWindowVisibleHeightLw() {
+        return 0;
+    }
+
+    @Override
+    public void setCurrentUserLw(int newUserId) {
+
+    }
+
+    @Override
+    public void dump(String prefix, PrintWriter writer, String[] args) {
+
+    }
+
+    @Override
+    public boolean canMagnifyWindow(int windowType) {
+        return false;
+    }
+
+    @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,
+            Rect outInsets) {
+
+    }
+
+    @Override
+    public boolean isNavBarForcedShownLw(WindowState win) {
+        return false;
+    }
+
+    @Override
+    public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight,
+            Rect outInsets) {
+
+    }
+
+    @Override
+    public boolean isDockSideAllowed(int dockSide) {
+        return false;
+    }
+
+    @Override
+    public void onConfigurationChanged() {
+
+    }
+
+    @Override
+    public boolean shouldRotateSeamlessly(int oldRotation, int newRotation) {
+        return false;
+    }
+}
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..a969efe
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -0,0 +1,57 @@
+/*
+ * 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.content.Context;
+import android.test.AndroidTestCase;
+import android.view.IWindow;
+import android.view.WindowManager;
+import android.view.WindowManagerPolicy;
+
+import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+
+/**
+ * Tests for the {@link WindowState} class.
+ *
+ * Build: mmma -j32 frameworks/base/services/tests/servicestests
+ * Install: adb install -r out/target/product/angler/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
+ * Run: adb shell am instrument -w -e class com.android.server.wm.WindowStateTests com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
+ */
+public class WindowStateTests extends AndroidTestCase {
+
+    private WindowManagerService mWm;
+    private WindowToken mWindowToken;
+    private final WindowManagerPolicy mPolicy = new TestWindowManagerPolicy();
+    private final IWindow mIWindow = new TestIWindow();
+
+    @Override
+    public void setUp() throws Exception {
+        final Context context = getContext();
+//        final InputManagerService im = new InputManagerService(context);
+        mWm = WindowManagerService.main(context, /*im*/ null, true, false, false, mPolicy);
+        mWindowToken = new WindowToken(mWm, null, 0, false);
+    }
+
+    private WindowState createWindow(WindowState parent) {
+        final int type = (parent == null) ? TYPE_APPLICATION : FIRST_SUB_WINDOW;
+        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
+
+        return new WindowState(mWm, null, mIWindow, mWindowToken, parent, 0, 0, attrs, 0,
+                mWm.getDefaultDisplayContentLocked(), 0);
+    }
+}