diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 4fc649e..2d6308c 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -473,7 +473,7 @@
     /**
      * Notify the system that the keyguard is going away.
      *
-     * @param flags See {@link android.view.WindowManagerPolicy#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE}
+     * @param flags See {@link android.view.WindowManagerPolicyConstants#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE}
      *              etc.
      */
     void keyguardGoingAway(int flags);
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index ef77d6e..8935745 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.app.KeyguardManager;
 import android.content.Context;
 import android.graphics.Point;
 import android.media.projection.MediaProjection;
@@ -27,7 +28,6 @@
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.Surface;
-import android.view.WindowManagerPolicy;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -254,8 +254,8 @@
      * </p>
      *
      * @see #createVirtualDisplay
-     * @see WindowManagerPolicy#isKeyguardSecure(int)
-     * @see WindowManagerPolicy#isKeyguardTrustedLw()
+     * @see KeyguardManager#isDeviceSecure()
+     * @see KeyguardManager#isDeviceLocked()
      * @hide
      */
     // TODO: Update name and documentation and un-hide the flag. Don't change the value before that.
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 6a44cdb..9673be0 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -20,6 +20,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.RequiresPermission;
+import android.app.KeyguardManager;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -209,8 +210,8 @@
      * </p>
      *
      * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD
-     * @see WindowManagerPolicy#isKeyguardSecure(int)
-     * @see WindowManagerPolicy#isKeyguardTrustedLw()
+     * @see KeyguardManager#isDeviceSecure()
+     * @see KeyguardManager#isDeviceLocked()
      * @see #getFlags
      * @hide
      */
diff --git a/core/java/android/view/DisplayFrames.java b/core/java/android/view/DisplayFrames.java
deleted file mode 100644
index e6861d8..0000000
--- a/core/java/android/view/DisplayFrames.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * 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 android.view;
-
-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.proto.DisplayFramesProto.STABLE_BOUNDS;
-
-import android.graphics.Rect;
-import android.util.proto.ProtoOutputStream;
-
-import java.io.PrintWriter;
-
-/**
- * Container class for all the display frames that affect how we do window layout on a display.
- * @hide
- */
-public class DisplayFrames {
-    public final int mDisplayId;
-
-    /**
-     * The current size of the screen; really; extends into the overscan area of the screen and
-     * doesn't account for any system elements like the status bar.
-     */
-    public final Rect mOverscan = new Rect();
-
-    /**
-     * The current visible size of the screen; really; (ir)regardless of whether the status bar can
-     * be hidden but not extending into the overscan area.
-     */
-    public final Rect mUnrestricted = new Rect();
-
-    /** Like mOverscan*, but allowed to move into the overscan region where appropriate. */
-    public final Rect mRestrictedOverscan = new Rect();
-
-    /**
-     * The current size of the screen; these may be different than (0,0)-(dw,dh) if the status bar
-     * can't be hidden; in that case it effectively carves out that area of the display from all
-     * other windows.
-     */
-    public final Rect mRestricted = new Rect();
-
-    /**
-     * During layout, the current screen borders accounting for any currently visible system UI
-     * elements.
-     */
-    public final Rect mSystem = new Rect();
-
-    /** For applications requesting stable content insets, these are them. */
-    public final Rect mStable = new Rect();
-
-    /**
-     * For applications requesting stable content insets but have also set the fullscreen window
-     * flag, these are the stable dimensions without the status bar.
-     */
-    public final Rect mStableFullscreen = new Rect();
-
-    /**
-     * During layout, the current screen borders with all outer decoration (status bar, input method
-     * dock) accounted for.
-     */
-    public final Rect mCurrent = new Rect();
-
-    /**
-     * During layout, the frame in which content should be displayed to the user, accounting for all
-     * screen decoration except for any space they deem as available for other content. This is
-     * usually the same as mCurrent*, but may be larger if the screen decor has supplied content
-     * insets.
-     */
-    public final Rect mContent = new Rect();
-
-    /**
-     * During layout, the frame in which voice content should be displayed to the user, accounting
-     * for all screen decoration except for any space they deem as available for other content.
-     */
-    public final Rect mVoiceContent = new Rect();
-
-    /** During layout, the current screen borders along which input method windows are placed. */
-    public final Rect mDock = new Rect();
-
-    private final Rect mDisplayInfoOverscan = new Rect();
-    private final Rect mRotatedDisplayInfoOverscan = new Rect();
-    public int mDisplayWidth;
-    public int mDisplayHeight;
-
-    public int mRotation;
-
-    public DisplayFrames(int displayId, DisplayInfo info) {
-        mDisplayId = displayId;
-        onDisplayInfoUpdated(info);
-    }
-
-    public void onDisplayInfoUpdated(DisplayInfo info) {
-        mDisplayWidth = info.logicalWidth;
-        mDisplayHeight = info.logicalHeight;
-        mRotation = info.rotation;
-        mDisplayInfoOverscan.set(
-                info.overscanLeft, info.overscanTop, info.overscanRight, info.overscanBottom);
-    }
-
-    public void onBeginLayout() {
-        switch (mRotation) {
-            case ROTATION_90:
-                mRotatedDisplayInfoOverscan.left = mDisplayInfoOverscan.top;
-                mRotatedDisplayInfoOverscan.top = mDisplayInfoOverscan.right;
-                mRotatedDisplayInfoOverscan.right = mDisplayInfoOverscan.bottom;
-                mRotatedDisplayInfoOverscan.bottom = mDisplayInfoOverscan.left;
-                break;
-            case ROTATION_180:
-                mRotatedDisplayInfoOverscan.left = mDisplayInfoOverscan.right;
-                mRotatedDisplayInfoOverscan.top = mDisplayInfoOverscan.bottom;
-                mRotatedDisplayInfoOverscan.right = mDisplayInfoOverscan.left;
-                mRotatedDisplayInfoOverscan.bottom = mDisplayInfoOverscan.top;
-                break;
-            case ROTATION_270:
-                mRotatedDisplayInfoOverscan.left = mDisplayInfoOverscan.bottom;
-                mRotatedDisplayInfoOverscan.top = mDisplayInfoOverscan.left;
-                mRotatedDisplayInfoOverscan.right = mDisplayInfoOverscan.top;
-                mRotatedDisplayInfoOverscan.bottom = mDisplayInfoOverscan.right;
-                break;
-            default:
-                mRotatedDisplayInfoOverscan.set(mDisplayInfoOverscan);
-                break;
-        }
-
-        mRestrictedOverscan.set(0, 0, mDisplayWidth, mDisplayHeight);
-        mOverscan.set(mRestrictedOverscan);
-        mSystem.set(mRestrictedOverscan);
-        mUnrestricted.set(mRotatedDisplayInfoOverscan);
-        mUnrestricted.right = mDisplayWidth - mUnrestricted.right;
-        mUnrestricted.bottom = mDisplayHeight - mUnrestricted.bottom;
-        mRestricted.set(mUnrestricted);
-        mDock.set(mUnrestricted);
-        mContent.set(mUnrestricted);
-        mVoiceContent.set(mUnrestricted);
-        mStable.set(mUnrestricted);
-        mStableFullscreen.set(mUnrestricted);
-        mCurrent.set(mUnrestricted);
-
-    }
-
-    public int getInputMethodWindowVisibleHeight() {
-        return mDock.bottom - mCurrent.bottom;
-    }
-
-    public void writeToProto(ProtoOutputStream proto, long fieldId) {
-        final long token = proto.start(fieldId);
-        mStable.writeToProto(proto, STABLE_BOUNDS);
-        proto.end(token);
-    }
-
-    public void dump(String prefix, PrintWriter pw) {
-        pw.println(prefix + "DisplayFrames w=" + mDisplayWidth + " h=" + mDisplayHeight
-                + " r=" + mRotation);
-        final String myPrefix = prefix + "  ";
-        dumpFrame(mStable, "mStable", myPrefix, pw);
-        dumpFrame(mStableFullscreen, "mStableFullscreen", myPrefix, pw);
-        dumpFrame(mDock, "mDock", myPrefix, pw);
-        dumpFrame(mCurrent, "mCurrent", myPrefix, pw);
-        dumpFrame(mSystem, "mSystem", myPrefix, pw);
-        dumpFrame(mContent, "mContent", myPrefix, pw);
-        dumpFrame(mVoiceContent, "mVoiceContent", myPrefix, pw);
-        dumpFrame(mOverscan, "mOverscan", myPrefix, pw);
-        dumpFrame(mRestrictedOverscan, "mRestrictedOverscan", myPrefix, pw);
-        dumpFrame(mRestricted, "mRestricted", myPrefix, pw);
-        dumpFrame(mUnrestricted, "mUnrestricted", myPrefix, pw);
-        dumpFrame(mDisplayInfoOverscan, "mDisplayInfoOverscan", myPrefix, pw);
-        dumpFrame(mRotatedDisplayInfoOverscan, "mRotatedDisplayInfoOverscan", myPrefix, pw);
-    }
-
-    private void dumpFrame(Rect frame, String name, String prefix, PrintWriter pw) {
-        pw.print(prefix + name + "="); frame.printShortString(pw); pw.println();
-    }
-}
diff --git a/core/java/android/view/InputFilter.java b/core/java/android/view/InputFilter.java
index d0dab40..0ab4dc0 100644
--- a/core/java/android/view/InputFilter.java
+++ b/core/java/android/view/InputFilter.java
@@ -72,21 +72,21 @@
  * </p><p>
  * The early policy interception decides whether an input event should be delivered
  * to applications or dropped.  The policy indicates its decision by setting the
- * {@link WindowManagerPolicy#FLAG_PASS_TO_USER} policy flag.  The input filter may
+ * {@link WindowManagerPolicyConstants#FLAG_PASS_TO_USER} policy flag.  The input filter may
  * sometimes receive events that do not have this flag set.  It should take note of
  * the fact that the policy intends to drop the event, clean up its state, and
  * then send appropriate cancellation events to the dispatcher if needed.
  * </p><p>
  * For example, suppose the input filter is processing a gesture and one of the touch events
- * it receives does not have the {@link WindowManagerPolicy#FLAG_PASS_TO_USER} flag set.
+ * it receives does not have the {@link WindowManagerPolicyConstants#FLAG_PASS_TO_USER} flag set.
  * The input filter should clear its internal state about the gesture and then send key or
  * motion events to the dispatcher to cancel any keys or pointers that are down.
  * </p><p>
  * Corollary: Events that get sent to the dispatcher should usually include the
- * {@link WindowManagerPolicy#FLAG_PASS_TO_USER} flag.  Otherwise, they will be dropped!
+ * {@link WindowManagerPolicyConstants#FLAG_PASS_TO_USER} flag.  Otherwise, they will be dropped!
  * </p><p>
  * It may be prudent to disable automatic key repeating for synthetic key events
- * by setting the {@link WindowManagerPolicy#FLAG_DISABLE_KEY_REPEAT} policy flag.
+ * by setting the {@link WindowManagerPolicyConstants#FLAG_DISABLE_KEY_REPEAT} policy flag.
  * </p>
  *
  * @hide
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 4eab496e..578679b 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -17,9 +17,9 @@
 package android.view;
 
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
-import static android.view.WindowManagerPolicy.APPLICATION_MEDIA_OVERLAY_SUBLAYER;
-import static android.view.WindowManagerPolicy.APPLICATION_MEDIA_SUBLAYER;
-import static android.view.WindowManagerPolicy.APPLICATION_PANEL_SUBLAYER;
+import static android.view.WindowManagerPolicyConstants.APPLICATION_MEDIA_OVERLAY_SUBLAYER;
+import static android.view.WindowManagerPolicyConstants.APPLICATION_MEDIA_SUBLAYER;
+import static android.view.WindowManagerPolicyConstants.APPLICATION_PANEL_SUBLAYER;
 
 import android.content.Context;
 import android.content.res.CompatibilityInfo.Translator;
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
deleted file mode 100644
index d07b2ac..0000000
--- a/core/java/android/view/WindowManagerInternal.java
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Copyright (C) 2014 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 android.view;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ClipData;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.hardware.display.DisplayManagerInternal;
-import android.os.IBinder;
-import android.view.animation.Animation;
-
-import java.util.List;
-
-/**
- * Window manager local system service interface.
- *
- * @hide Only for use within the system server.
- */
-public abstract class WindowManagerInternal {
-
-    /**
-     * Interface to receive a callback when the windows reported for
-     * accessibility changed.
-     */
-    public interface WindowsForAccessibilityCallback {
-
-        /**
-         * Called when the windows for accessibility changed.
-         *
-         * @param windows The windows for accessibility.
-         */
-        public void onWindowsForAccessibilityChanged(List<WindowInfo> windows);
-    }
-
-    /**
-     * Callbacks for contextual changes that affect the screen magnification
-     * feature.
-     */
-    public interface MagnificationCallbacks {
-
-        /**
-         * Called when the region where magnification operates changes. Note that this isn't the
-         * entire screen. For example, IMEs are not magnified.
-         *
-         * @param magnificationRegion the current magnification region
-         */
-        public void onMagnificationRegionChanged(Region magnificationRegion);
-
-        /**
-         * Called when an application requests a rectangle on the screen to allow
-         * the client to apply the appropriate pan and scale.
-         *
-         * @param left The rectangle left.
-         * @param top The rectangle top.
-         * @param right The rectangle right.
-         * @param bottom The rectangle bottom.
-         */
-        public void onRectangleOnScreenRequested(int left, int top, int right, int bottom);
-
-        /**
-         * Notifies that the rotation changed.
-         *
-         * @param rotation The current rotation.
-         */
-        public void onRotationChanged(int rotation);
-
-        /**
-         * Notifies that the context of the user changed. For example, an application
-         * was started.
-         */
-        public void onUserContextChanged();
-    }
-
-    /**
-     * Abstract class to be notified about {@link com.android.server.wm.AppTransition} events. Held
-     * as an abstract class so a listener only needs to implement the methods of its interest.
-     */
-    public static abstract class AppTransitionListener {
-
-        /**
-         * Called when an app transition is being setup and about to be executed.
-         */
-        public void onAppTransitionPendingLocked() {}
-
-        /**
-         * Called when a pending app transition gets cancelled.
-         *
-         * @param transit transition type indicating what kind of transition got cancelled
-         */
-        public void onAppTransitionCancelledLocked(int transit) {}
-
-        /**
-         * Called when an app transition gets started
-         *
-         * @param transit transition type indicating what kind of transition gets run, must be one
-         *                of AppTransition.TRANSIT_* values
-         * @param openToken the token for the opening app
-         * @param closeToken the token for the closing app
-         * @param openAnimation the animation for the opening app
-         * @param closeAnimation the animation for the closing app
-         *
-         * @return Return any bit set of {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_LAYOUT},
-         * {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_CONFIG},
-         * {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_WALLPAPER},
-         * or {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_ANIM}.
-         */
-        public int onAppTransitionStartingLocked(int transit, IBinder openToken, IBinder closeToken,
-                Animation openAnimation, Animation closeAnimation) {
-            return 0;
-        }
-
-        /**
-         * Called when an app transition is finished running.
-         *
-         * @param token the token for app whose transition has finished
-         */
-        public void onAppTransitionFinishedLocked(IBinder token) {}
-    }
-
-    /**
-      * An interface to be notified about hardware keyboard status.
-      */
-    public interface OnHardKeyboardStatusChangeListener {
-        public void onHardKeyboardStatusChange(boolean available);
-    }
-
-    /**
-     * An interface to customize drag and drop behaviors.
-     */
-    public interface IDragDropCallback {
-        /**
-         * Called when drag operation is started.
-         */
-        default boolean performDrag(IWindow window, IBinder dragToken,
-                int touchSource, float touchX, float touchY, float thumbCenterX, float thumbCenterY,
-                ClipData data) {
-            return true;
-        }
-
-        /**
-         * Called when drop result is reported.
-         */
-        default void reportDropResult(IWindow window, boolean consumed) {}
-
-        /**
-         * Called when drag operation is cancelled.
-         */
-        default void cancelDragAndDrop(IBinder dragToken) {}
-    }
-
-    /**
-     * Request that the window manager call
-     * {@link DisplayManagerInternal#performTraversalInTransactionFromWindowManager}
-     * within a surface transaction at a later time.
-     */
-    public abstract void requestTraversalFromDisplayManager();
-
-    /**
-     * Set by the accessibility layer to observe changes in the magnified region,
-     * rotation, and other window transformations related to display magnification
-     * as the window manager is responsible for doing the actual magnification
-     * and has access to the raw window data while the accessibility layer serves
-     * as a controller.
-     *
-     * @param callbacks The callbacks to invoke.
-     */
-    public abstract void setMagnificationCallbacks(@Nullable MagnificationCallbacks callbacks);
-
-    /**
-     * Set by the accessibility layer to specify the magnification and panning to
-     * be applied to all windows that should be magnified.
-     *
-     * @param spec The MagnficationSpec to set.
-     *
-     * @see #setMagnificationCallbacks(MagnificationCallbacks)
-     */
-    public abstract void setMagnificationSpec(MagnificationSpec spec);
-
-    /**
-     * Set by the accessibility framework to indicate whether the magnifiable regions of the display
-     * should be shown.
-     *
-     * @param show {@code true} to show magnifiable region bounds, {@code false} to hide
-     */
-    public abstract void setForceShowMagnifiableBounds(boolean show);
-
-    /**
-     * Obtains the magnification regions.
-     *
-     * @param magnificationRegion the current magnification region
-     */
-    public abstract void getMagnificationRegion(@NonNull Region magnificationRegion);
-
-    /**
-     * Gets the magnification and translation applied to a window given its token.
-     * Not all windows are magnified and the window manager policy determines which
-     * windows are magnified. The returned result also takes into account the compat
-     * scale if necessary.
-     *
-     * @param windowToken The window's token.
-     *
-     * @return The magnification spec for the window.
-     *
-     * @see #setMagnificationCallbacks(MagnificationCallbacks)
-     */
-    public abstract MagnificationSpec getCompatibleMagnificationSpecForWindow(
-            IBinder windowToken);
-
-    /**
-     * Sets a callback for observing which windows are touchable for the purposes
-     * of accessibility.
-     *
-     * @param callback The callback.
-     */
-    public abstract void setWindowsForAccessibilityCallback(
-            WindowsForAccessibilityCallback callback);
-
-    /**
-     * Sets a filter for manipulating the input event stream.
-     *
-     * @param filter The filter implementation.
-     */
-    public abstract void setInputFilter(IInputFilter filter);
-
-    /**
-     * Gets the token of the window that has input focus.
-     *
-     * @return The token.
-     */
-    public abstract IBinder getFocusedWindowToken();
-
-    /**
-     * @return Whether the keyguard is engaged.
-     */
-    public abstract boolean isKeyguardLocked();
-
-    /**
-    * @return Whether the keyguard is showing and not occluded.
-    */
-    public abstract boolean isKeyguardShowingAndNotOccluded();
-
-    /**
-     * Gets the frame of a window given its token.
-     *
-     * @param token The token.
-     * @param outBounds The frame to populate.
-     */
-    public abstract void getWindowFrame(IBinder token, Rect outBounds);
-
-    /**
-     * Opens the global actions dialog.
-     */
-    public abstract void showGlobalActions();
-
-    /**
-     * Invalidate all visible windows. Then report back on the callback once all windows have
-     * redrawn.
-     */
-    public abstract void waitForAllWindowsDrawn(Runnable callback, long timeout);
-
-    /**
-     * Adds a window token for a given window type.
-     *
-     * @param token The token to add.
-     * @param type The window type.
-     * @param displayId The display to add the token to.
-     */
-    public abstract void addWindowToken(android.os.IBinder token, int type, int displayId);
-
-    /**
-     * Removes a window token.
-     *
-     * @param token The toke to remove.
-     * @param removeWindows Whether to also remove the windows associated with the token.
-     * @param displayId The display to remove the token from.
-     */
-    public abstract void removeWindowToken(android.os.IBinder token, boolean removeWindows,
-            int displayId);
-
-    /**
-     * Registers a listener to be notified about app transition events.
-     *
-     * @param listener The listener to register.
-     */
-    public abstract void registerAppTransitionListener(AppTransitionListener listener);
-
-    /**
-     * Retrieves a height of input method window.
-     */
-    public abstract int getInputMethodWindowVisibleHeight();
-
-    /**
-      * Saves last input method window for transition.
-      *
-      * Note that it is assumed that this method is called only by InputMethodManagerService.
-      */
-    public abstract void saveLastInputMethodWindowForTransition();
-
-    /**
-     * Clears last input method window for transition.
-     *
-     * Note that it is assumed that this method is called only by InputMethodManagerService.
-     */
-    public abstract void clearLastInputMethodWindowForTransition();
-
-    /**
-     * Notifies WindowManagerService that the current IME window status is being changed.
-     *
-     * <p>Only {@link com.android.server.InputMethodManagerService} is the expected and tested
-     * caller of this method.</p>
-     *
-     * @param imeToken token to track the active input method. Corresponding IME windows can be
-     *                 identified by checking {@link android.view.WindowManager.LayoutParams#token}.
-     *                 Note that there is no guarantee that the corresponding window is already
-     *                 created
-     * @param imeWindowVisible whether the active IME thinks that its window should be visible or
-     *                         hidden, no matter how WindowManagerService will react / has reacted
-     *                         to corresponding API calls.  Note that this state is not guaranteed
-     *                         to be synchronized with state in WindowManagerService.
-     * @param dismissImeOnBackKeyPressed {@code true} if the software keyboard is shown and the back
-     *                                   key is expected to dismiss the software keyboard.
-     * @param targetWindowToken token to identify the target window that the IME is associated with.
-     *                          {@code null} when application, system, or the IME itself decided to
-     *                          change its window visibility before being associated with any target
-     *                          window.
-     */
-    public abstract void updateInputMethodWindowStatus(@NonNull IBinder imeToken,
-            boolean imeWindowVisible, boolean dismissImeOnBackKeyPressed,
-            @Nullable IBinder targetWindowToken);
-
-    /**
-      * Returns true when the hardware keyboard is available.
-      */
-    public abstract boolean isHardKeyboardAvailable();
-
-    /**
-      * Sets the callback listener for hardware keyboard status changes.
-      *
-      * @param listener The listener to set.
-      */
-    public abstract void setOnHardKeyboardStatusChangeListener(
-        OnHardKeyboardStatusChangeListener listener);
-
-    /** Returns true if a stack in the windowing mode is currently visible. */
-    public abstract boolean isStackVisible(int windowingMode);
-
-    /**
-     * @return True if and only if the docked divider is currently in resize mode.
-     */
-    public abstract boolean isDockedDividerResizing();
-
-    /**
-     * Requests the window manager to recompute the windows for accessibility.
-     */
-    public abstract void computeWindowsForAccessibility();
-
-    /**
-     * Called after virtual display Id is updated by
-     * {@link com.android.server.vr.Vr2dDisplay} with a specific
-     * {@param vr2dDisplayId}.
-     */
-    public abstract void setVr2dDisplayId(int vr2dDisplayId);
-
-    /**
-     * Sets callback to DragDropController.
-     */
-    public abstract void registerDragDropControllerCallback(IDragDropCallback callback);
-
-    /**
-     * @see android.view.IWindowManager#lockNow
-     */
-    public abstract void lockNow();
-}
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
deleted file mode 100644
index c192f5c..0000000
--- a/core/java/android/view/WindowManagerPolicy.java
+++ /dev/null
@@ -1,1776 +0,0 @@
-/*
- * Copyright (C) 2006 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 android.view;
-
-import static android.Manifest.permission;
-import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
-import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
-import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
-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_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
-import static android.view.WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
-import static android.view.WindowManager.LayoutParams.TYPE_DRAG;
-import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
-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_KEYGUARD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_PHONE;
-import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
-import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
-import static android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
-import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
-import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
-import static android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
-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_ALERT;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
-import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
-import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
-import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType;
-
-import android.annotation.IntDef;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.content.Context;
-import android.content.pm.ActivityInfo;
-import android.content.res.CompatibilityInfo;
-import android.content.res.Configuration;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.util.Slog;
-import android.util.proto.ProtoOutputStream;
-import android.view.animation.Animation;
-
-import com.android.internal.policy.IKeyguardDismissCallback;
-import com.android.internal.policy.IShortcutService;
-
-import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This interface supplies all UI-specific behavior of the window manager.  An
- * instance of it is created by the window manager when it starts up, and allows
- * customization of window layering, special window types, key dispatching, and
- * layout.
- *
- * <p>Because this provides deep interaction with the system window manager,
- * specific methods on this interface can be called from a variety of contexts
- * with various restrictions on what they can do.  These are encoded through
- * a suffixes at the end of a method encoding the thread the method is called
- * from and any locks that are held when it is being called; if no suffix
- * is attached to a method, then it is not called with any locks and may be
- * called from the main window manager thread or another thread calling into
- * the window manager.
- *
- * <p>The current suffixes are:
- *
- * <dl>
- * <dt> Ti <dd> Called from the input thread.  This is the thread that
- * collects pending input events and dispatches them to the appropriate window.
- * It may block waiting for events to be processed, so that the input stream is
- * properly serialized.
- * <dt> Tq <dd> Called from the low-level input queue thread.  This is the
- * thread that reads events out of the raw input devices and places them
- * into the global input queue that is read by the <var>Ti</var> thread.
- * This thread should not block for a long period of time on anything but the
- * key driver.
- * <dt> Lw <dd> Called with the main window manager lock held.  Because the
- * window manager is a very low-level system service, there are few other
- * system services you can call with this lock held.  It is explicitly okay to
- * make calls into the package manager and power manager; it is explicitly not
- * okay to make calls into the activity manager or most other services.  Note that
- * {@link android.content.Context#checkPermission(String, int, int)} and
- * variations require calling into the activity manager.
- * <dt> Li <dd> Called with the input thread lock held.  This lock can be
- * acquired by the window manager while it holds the window lock, so this is
- * even more restrictive than <var>Lw</var>.
- * </dl>
- *
- * @hide
- */
-public interface WindowManagerPolicy {
-    // Policy flags.  These flags are also defined in frameworks/base/include/ui/Input.h.
-    public final static int FLAG_WAKE = 0x00000001;
-    public final static int FLAG_VIRTUAL = 0x00000002;
-
-    public final static int FLAG_INJECTED = 0x01000000;
-    public final static int FLAG_TRUSTED = 0x02000000;
-    public final static int FLAG_FILTERED = 0x04000000;
-    public final static int FLAG_DISABLE_KEY_REPEAT = 0x08000000;
-
-    public final static int FLAG_INTERACTIVE = 0x20000000;
-    public final static int FLAG_PASS_TO_USER = 0x40000000;
-
-    // Flags for IActivityManager.keyguardGoingAway()
-    public final static int KEYGUARD_GOING_AWAY_FLAG_TO_SHADE = 1 << 0;
-    public final static int KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS = 1 << 1;
-    public final static int KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER = 1 << 2;
-
-    // Flags used for indicating whether the internal and/or external input devices
-    // of some type are available.
-    public final static int PRESENCE_INTERNAL = 1 << 0;
-    public final static int PRESENCE_EXTERNAL = 1 << 1;
-
-    // Navigation bar position values
-    int NAV_BAR_LEFT = 1 << 0;
-    int NAV_BAR_RIGHT = 1 << 1;
-    int NAV_BAR_BOTTOM = 1 << 2;
-
-    public final static boolean WATCH_POINTER = false;
-
-    /**
-     * Sticky broadcast of the current HDMI plugged state.
-     */
-    public final static String ACTION_HDMI_PLUGGED = "android.intent.action.HDMI_PLUGGED";
-
-    /**
-     * Extra in {@link #ACTION_HDMI_PLUGGED} indicating the state: true if
-     * plugged in to HDMI, false if not.
-     */
-    public final static String EXTRA_HDMI_PLUGGED_STATE = "state";
-
-    /**
-     * Set to {@code true} when intent was invoked from pressing the home key.
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_FROM_HOME_KEY = "android.intent.extra.FROM_HOME_KEY";
-
-    /**
-     * Pass this event to the user / app.  To be returned from
-     * {@link #interceptKeyBeforeQueueing}.
-     */
-    public final static int ACTION_PASS_TO_USER = 0x00000001;
-
-    /**
-     * Register shortcuts for window manager to dispatch.
-     * Shortcut code is packed as (metaState << Integer.SIZE) | keyCode
-     * @hide
-     */
-    void registerShortcutKey(long shortcutCode, IShortcutService shortcutKeyReceiver)
-            throws RemoteException;
-
-    /**
-     * Called when the Keyguard occluded state changed.
-     * @param occluded Whether Keyguard is currently occluded or not.
-     */
-    void onKeyguardOccludedChangedLw(boolean occluded);
-
-    /**
-     * Interface to the Window Manager state associated with a particular
-     * window.  You can hold on to an instance of this interface from the call
-     * to prepareAddWindow() until removeWindow().
-     */
-    public interface WindowState {
-        /**
-         * Return the uid of the app that owns this window.
-         */
-        int getOwningUid();
-
-        /**
-         * Return the package name of the app that owns this window.
-         */
-        String getOwningPackage();
-
-        /**
-         * Perform standard frame computation.  The result can be obtained with
-         * getFrame() if so desired.  Must be called with the window manager
-         * lock held.
-         *
-         * @param parentFrame The frame of the parent container this window
-         * is in, used for computing its basic position.
-         * @param displayFrame The frame of the overall display in which this
-         * window can appear, used for constraining the overall dimensions
-         * of the window.
-         * @param overlayFrame The frame within the display that is inside
-         * of the overlay region.
-         * @param contentFrame The frame within the display in which we would
-         * like active content to appear.  This will cause windows behind to
-         * be resized to match the given content frame.
-         * @param visibleFrame The frame within the display that the window
-         * is actually visible, used for computing its visible insets to be
-         * given to windows behind.
-         * This can be used as a hint for scrolling (avoiding resizing)
-         * the window to make certain that parts of its content
-         * are visible.
-         * @param decorFrame The decor frame specified by policy specific to this window,
-         * to use for proper cropping during animation.
-         * @param stableFrame The frame around which stable system decoration is positioned.
-         * @param outsetFrame The frame that includes areas that aren't part of the surface but we
-         * want to treat them as such.
-         */
-        public void computeFrameLw(Rect parentFrame, Rect displayFrame,
-                Rect overlayFrame, Rect contentFrame, Rect visibleFrame, Rect decorFrame,
-                Rect stableFrame, Rect outsetFrame);
-
-        /**
-         * Retrieve the current frame of the window that has been assigned by
-         * the window manager.  Must be called with the window manager lock held.
-         *
-         * @return Rect The rectangle holding the window frame.
-         */
-        public Rect getFrameLw();
-
-        /**
-         * Retrieve the current position of the window that is actually shown.
-         * Must be called with the window manager lock held.
-         *
-         * @return Point The point holding the shown window position.
-         */
-        public Point getShownPositionLw();
-
-        /**
-         * Retrieve the frame of the display that this window was last
-         * laid out in.  Must be called with the
-         * window manager lock held.
-         *
-         * @return Rect The rectangle holding the display frame.
-         */
-        public Rect getDisplayFrameLw();
-
-        /**
-         * Retrieve the frame of the area inside the overscan region of the
-         * display that this window was last laid out in.  Must be called with the
-         * window manager lock held.
-         *
-         * @return Rect The rectangle holding the display overscan frame.
-         */
-        public Rect getOverscanFrameLw();
-
-        /**
-         * Retrieve the frame of the content area that this window was last
-         * laid out in.  This is the area in which the content of the window
-         * should be placed.  It will be smaller than the display frame to
-         * account for screen decorations such as a status bar or soft
-         * keyboard.  Must be called with the
-         * window manager lock held.
-         *
-         * @return Rect The rectangle holding the content frame.
-         */
-        public Rect getContentFrameLw();
-
-        /**
-         * Retrieve the frame of the visible area that this window was last
-         * laid out in.  This is the area of the screen in which the window
-         * will actually be fully visible.  It will be smaller than the
-         * content frame to account for transient UI elements blocking it
-         * such as an input method's candidates UI.  Must be called with the
-         * window manager lock held.
-         *
-         * @return Rect The rectangle holding the visible frame.
-         */
-        public Rect getVisibleFrameLw();
-
-        /**
-         * Returns true if this window is waiting to receive its given
-         * internal insets from the client app, and so should not impact the
-         * layout of other windows.
-         */
-        public boolean getGivenInsetsPendingLw();
-
-        /**
-         * Retrieve the insets given by this window's client for the content
-         * area of windows behind it.  Must be called with the
-         * window manager lock held.
-         *
-         * @return Rect The left, top, right, and bottom insets, relative
-         * to the window's frame, of the actual contents.
-         */
-        public Rect getGivenContentInsetsLw();
-
-        /**
-         * Retrieve the insets given by this window's client for the visible
-         * area of windows behind it.  Must be called with the
-         * window manager lock held.
-         *
-         * @return Rect The left, top, right, and bottom insets, relative
-         * to the window's frame, of the actual visible area.
-         */
-        public Rect getGivenVisibleInsetsLw();
-
-        /**
-         * Retrieve the current LayoutParams of the window.
-         *
-         * @return WindowManager.LayoutParams The window's internal LayoutParams
-         *         instance.
-         */
-        public WindowManager.LayoutParams getAttrs();
-
-        /**
-         * Return whether this window needs the menu key shown.  Must be called
-         * with window lock held, because it may need to traverse down through
-         * window list to determine the result.
-         * @param bottom The bottom-most window to consider when determining this.
-         */
-        public boolean getNeedsMenuLw(WindowState bottom);
-
-        /**
-         * Retrieve the current system UI visibility flags associated with
-         * this window.
-         */
-        public int getSystemUiVisibility();
-
-        /**
-         * Get the layer at which this window's surface will be Z-ordered.
-         */
-        public int getSurfaceLayer();
-
-        /**
-         * Retrieve the type of the top-level window.
-         *
-         * @return the base type of the parent window if attached or its own type otherwise
-         */
-        public int getBaseType();
-
-        /**
-         * Return the token for the application (actually activity) that owns
-         * this window.  May return null for system windows.
-         *
-         * @return An IApplicationToken identifying the owning activity.
-         */
-        public IApplicationToken getAppToken();
-
-        /**
-         * Return true if this window is participating in voice interaction.
-         */
-        public boolean isVoiceInteraction();
-
-        /**
-         * Return true if, at any point, the application token associated with
-         * this window has actually displayed any windows.  This is most useful
-         * with the "starting up" window to determine if any windows were
-         * displayed when it is closed.
-         *
-         * @return Returns true if one or more windows have been displayed,
-         *         else false.
-         */
-        public boolean hasAppShownWindows();
-
-        /**
-         * Is this window visible?  It is not visible if there is no
-         * surface, or we are in the process of running an exit animation
-         * that will remove the surface.
-         */
-        boolean isVisibleLw();
-
-        /**
-         * Is this window currently visible to the user on-screen?  It is
-         * displayed either if it is visible or it is currently running an
-         * animation before no longer being visible.  Must be called with the
-         * window manager lock held.
-         */
-        boolean isDisplayedLw();
-
-        /**
-         * Return true if this window (or a window it is attached to, but not
-         * considering its app token) is currently animating.
-         */
-        boolean isAnimatingLw();
-
-        /**
-         * @return Whether the window can affect SystemUI flags, meaning that SystemUI (system bars,
-         *         for example) will be  affected by the flags specified in this window. This is the
-         *         case when the surface is on screen but not exiting.
-         */
-        boolean canAffectSystemUiFlags();
-
-        /**
-         * Is this window considered to be gone for purposes of layout?
-         */
-        boolean isGoneForLayoutLw();
-
-        /**
-         * Returns true if the window has a surface that it has drawn a
-         * complete UI in to. Note that this is different from {@link #hasDrawnLw()}
-         * in that it also returns true if the window is READY_TO_SHOW, but was not yet
-         * promoted to HAS_DRAWN.
-         */
-        boolean isDrawnLw();
-
-        /**
-         * Returns true if this window has been shown on screen at some time in
-         * the past.  Must be called with the window manager lock held.
-         */
-        public boolean hasDrawnLw();
-
-        /**
-         * Can be called by the policy to force a window to be hidden,
-         * regardless of whether the client or window manager would like
-         * it shown.  Must be called with the window manager lock held.
-         * Returns true if {@link #showLw} was last called for the window.
-         */
-        public boolean hideLw(boolean doAnimation);
-
-        /**
-         * Can be called to undo the effect of {@link #hideLw}, allowing a
-         * window to be shown as long as the window manager and client would
-         * also like it to be shown.  Must be called with the window manager
-         * lock held.
-         * Returns true if {@link #hideLw} was last called for the window.
-         */
-        public boolean showLw(boolean doAnimation);
-
-        /**
-         * Check whether the process hosting this window is currently alive.
-         */
-        public boolean isAlive();
-
-        /**
-         * Check if window is on {@link Display#DEFAULT_DISPLAY}.
-         * @return true if window is on default display.
-         */
-        public boolean isDefaultDisplay();
-
-        /**
-         * Check whether the window is currently dimming.
-         */
-        public boolean isDimming();
-
-        /** @return the current windowing mode of this window. */
-        int getWindowingMode();
-
-        /**
-         * Returns true if the window is current in multi-windowing mode. i.e. it shares the
-         * screen with other application windows.
-         */
-        public boolean isInMultiWindowMode();
-
-        public int getRotationAnimationHint();
-
-        public boolean isInputMethodWindow();
-
-        public int getDisplayId();
-
-        /**
-         * Returns true if the window owner can add internal system windows.
-         * That is, they have {@link permission#INTERNAL_SYSTEM_WINDOW}.
-         */
-        default boolean canAddInternalSystemWindow() {
-            return false;
-        }
-
-        /**
-         * Returns true if the window owner has the permission to acquire a sleep token when it's
-         * visible. That is, they have the permission {@link permission#DEVICE_POWER}.
-         */
-        boolean canAcquireSleepToken();
-    }
-
-    /**
-     * Representation of a input consumer that the policy has added to the
-     * window manager to consume input events going to windows below it.
-     */
-    public interface InputConsumer {
-        /**
-         * Remove the input consumer from the window manager.
-         */
-        void dismiss();
-    }
-
-    /**
-     * Holds the contents of a starting window. {@link #addSplashScreen} needs to wrap the
-     * contents of the starting window into an class implementing this interface, which then will be
-     * held by WM and released with {@link #remove} when no longer needed.
-     */
-    interface StartingSurface {
-
-        /**
-         * Removes the starting window surface. Do not hold the window manager lock when calling
-         * this method!
-         */
-        void remove();
-    }
-
-    /**
-     * Interface for calling back in to the window manager that is private
-     * between it and the policy.
-     */
-    public interface WindowManagerFuncs {
-        public static final int LID_ABSENT = -1;
-        public static final int LID_CLOSED = 0;
-        public static final int LID_OPEN = 1;
-
-        public static final int CAMERA_LENS_COVER_ABSENT = -1;
-        public static final int CAMERA_LENS_UNCOVERED = 0;
-        public static final int CAMERA_LENS_COVERED = 1;
-
-        /**
-         * Ask the window manager to re-evaluate the system UI flags.
-         */
-        public void reevaluateStatusBarVisibility();
-
-        /**
-         * Add a input consumer which will consume all input events going to any window below it.
-         */
-        public InputConsumer createInputConsumer(Looper looper, String name,
-                InputEventReceiver.Factory inputEventReceiverFactory);
-
-        /**
-         * Returns a code that describes the current state of the lid switch.
-         */
-        public int getLidState();
-
-        /**
-         * Lock the device now.
-         */
-        public void lockDeviceNow();
-
-        /**
-         * Returns a code that descripbes whether the camera lens is covered or not.
-         */
-        public int getCameraLensCoverState();
-
-        /**
-         * Switch the input method, to be precise, input method subtype.
-         *
-         * @param forwardDirection {@code true} to rotate in a forward direction.
-         */
-        public void switchInputMethod(boolean forwardDirection);
-
-        public void shutdown(boolean confirm);
-        public void reboot(boolean confirm);
-        public void rebootSafeMode(boolean confirm);
-
-        /**
-         * Return the window manager lock needed to correctly call "Lw" methods.
-         */
-        public Object getWindowManagerLock();
-
-        /** Register a system listener for touch events */
-        void registerPointerEventListener(PointerEventListener listener);
-
-        /** Unregister a system listener for touch events */
-        void unregisterPointerEventListener(PointerEventListener listener);
-
-        /**
-         * @return The content insets of the docked divider window.
-         */
-        int getDockedDividerInsetsLw();
-
-        /**
-         * Retrieves the {@param outBounds} from the stack matching the {@param windowingMode} and
-         * {@param activityType}.
-         */
-        void getStackBounds(int windowingMode, int activityType, Rect outBounds);
-
-        /**
-         * Notifies window manager that {@link #isShowingDreamLw} has changed.
-         */
-        void notifyShowingDreamChanged();
-
-        /**
-         * @return The currently active input method window.
-         */
-        WindowState getInputMethodWindowLw();
-
-        /**
-         * Notifies window manager that {@link #isKeyguardTrustedLw} has changed.
-         */
-        void notifyKeyguardTrustedChanged();
-
-        /**
-         * Notifies the window manager that screen is being turned off.
-         *
-         * @param listener callback to call when display can be turned off
-         */
-        void screenTurningOff(ScreenOffListener listener);
-
-        /**
-         * Convert the lid state to a human readable format.
-         */
-        static String lidStateToString(int lid) {
-            switch (lid) {
-                case LID_ABSENT:
-                    return "LID_ABSENT";
-                case LID_CLOSED:
-                    return "LID_CLOSED";
-                case LID_OPEN:
-                    return "LID_OPEN";
-                default:
-                    return Integer.toString(lid);
-            }
-        }
-
-        /**
-         * Convert the camera lens state to a human readable format.
-         */
-        static String cameraLensStateToString(int lens) {
-            switch (lens) {
-                case CAMERA_LENS_COVER_ABSENT:
-                    return "CAMERA_LENS_COVER_ABSENT";
-                case CAMERA_LENS_UNCOVERED:
-                    return "CAMERA_LENS_UNCOVERED";
-                case CAMERA_LENS_COVERED:
-                    return "CAMERA_LENS_COVERED";
-                default:
-                    return Integer.toString(lens);
-            }
-        }
-    }
-
-    public interface PointerEventListener {
-        /**
-         * 1. onPointerEvent will be called on the service.UiThread.
-         * 2. motionEvent will be recycled after onPointerEvent returns so if it is needed later a
-         * copy() must be made and the copy must be recycled.
-         **/
-        void onPointerEvent(MotionEvent motionEvent);
-
-        /**
-         * @see #onPointerEvent(MotionEvent)
-         **/
-        default void onPointerEvent(MotionEvent motionEvent, int displayId) {
-            if (displayId == DEFAULT_DISPLAY) {
-                onPointerEvent(motionEvent);
-            }
-        }
-    }
-
-    /** Window has been added to the screen. */
-    public static final int TRANSIT_ENTER = 1;
-    /** Window has been removed from the screen. */
-    public static final int TRANSIT_EXIT = 2;
-    /** Window has been made visible. */
-    public static final int TRANSIT_SHOW = 3;
-    /** Window has been made invisible.
-     * TODO: Consider removal as this is unused. */
-    public static final int TRANSIT_HIDE = 4;
-    /** The "application starting" preview window is no longer needed, and will
-     * animate away to show the real window. */
-    public static final int TRANSIT_PREVIEW_DONE = 5;
-
-    // NOTE: screen off reasons are in order of significance, with more
-    // important ones lower than less important ones.
-
-    /** Screen turned off because of a device admin */
-    public final int OFF_BECAUSE_OF_ADMIN = 1;
-    /** Screen turned off because of power button */
-    public final int OFF_BECAUSE_OF_USER = 2;
-    /** Screen turned off because of timeout */
-    public final int OFF_BECAUSE_OF_TIMEOUT = 3;
-
-    /** @hide */
-    @IntDef({USER_ROTATION_FREE, USER_ROTATION_LOCKED})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface UserRotationMode {}
-
-    /** When not otherwise specified by the activity's screenOrientation, rotation should be
-     * determined by the system (that is, using sensors). */
-    public final int USER_ROTATION_FREE = 0;
-    /** When not otherwise specified by the activity's screenOrientation, rotation is set by
-     * the user. */
-    public final int USER_ROTATION_LOCKED = 1;
-
-    /**
-     * Perform initialization of the policy.
-     *
-     * @param context The system context we are running in.
-     */
-    public void init(Context context, IWindowManager windowManager,
-            WindowManagerFuncs windowManagerFuncs);
-
-    /**
-     * @return true if com.android.internal.R.bool#config_forceDefaultOrientation is true.
-     */
-    public boolean isDefaultOrientationForced();
-
-    /**
-     * Called by window manager once it has the initial, default native
-     * display dimensions.
-     */
-    public void setInitialDisplaySize(Display display, int width, int height, int density);
-
-    /**
-     * Check permissions when adding a window.
-     *
-     * @param attrs The window's LayoutParams.
-     * @param outAppOp First element will be filled with the app op corresponding to
-     *                 this window, or OP_NONE.
-     *
-     * @return {@link WindowManagerGlobal#ADD_OKAY} if the add can proceed;
-     *      else an error code, usually
-     *      {@link WindowManagerGlobal#ADD_PERMISSION_DENIED}, to abort the add.
-     */
-    public int checkAddPermission(WindowManager.LayoutParams attrs, int[] outAppOp);
-
-    /**
-     * Check permissions when adding a window.
-     *
-     * @param attrs The window's LayoutParams.
-     *
-     * @return True if the window may only be shown to the current user, false if the window can
-     * be shown on all users' windows.
-     */
-    public boolean checkShowToOwnerOnly(WindowManager.LayoutParams attrs);
-
-    /**
-     * Sanitize the layout parameters coming from a client.  Allows the policy
-     * to do things like ensure that windows of a specific type can't take
-     * input focus.
-     *
-     * @param attrs The window layout parameters to be modified.  These values
-     * are modified in-place.
-     */
-    public void adjustWindowParamsLw(WindowState win, WindowManager.LayoutParams attrs,
-            boolean hasStatusBarServicePermission);
-
-    /**
-     * After the window manager has computed the current configuration based
-     * on its knowledge of the display and input devices, it gives the policy
-     * a chance to adjust the information contained in it.  If you want to
-     * leave it as-is, simply do nothing.
-     *
-     * <p>This method may be called by any thread in the window manager, but
-     * no internal locks in the window manager will be held.
-     *
-     * @param config The Configuration being computed, for you to change as
-     * desired.
-     * @param keyboardPresence Flags that indicate whether internal or external
-     * keyboards are present.
-     * @param navigationPresence Flags that indicate whether internal or external
-     * navigation devices are present.
-     */
-    public void adjustConfigurationLw(Configuration config, int keyboardPresence,
-            int navigationPresence);
-
-    /**
-     * Returns the layer assignment for the window state. Allows you to control how different
-     * kinds of windows are ordered on-screen.
-     *
-     * @param win The window state
-     * @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
-     */
-    default int getWindowLayerLw(WindowState win) {
-        return getWindowLayerFromTypeLw(win.getBaseType(), win.canAddInternalSystemWindow());
-    }
-
-    /**
-     * Returns the layer assignment for the window type. Allows you to control how different
-     * kinds of windows are ordered on-screen.
-     *
-     * @param type The type of window being assigned.
-     * @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
-     */
-    default int getWindowLayerFromTypeLw(int type) {
-        if (isSystemAlertWindowType(type)) {
-            throw new IllegalArgumentException("Use getWindowLayerFromTypeLw() or"
-                    + " getWindowLayerLw() for alert window types");
-        }
-        return getWindowLayerFromTypeLw(type, false /* canAddInternalSystemWindow */);
-    }
-
-    /**
-     * Returns the layer assignment for the window type. Allows you to control how different
-     * kinds of windows are ordered on-screen.
-     *
-     * @param type The type of window being assigned.
-     * @param canAddInternalSystemWindow If the owner window associated with the type we are
-     *        evaluating can add internal system windows. I.e they have
-     *        {@link permission#INTERNAL_SYSTEM_WINDOW}. If true, alert window
-     *        types {@link android.view.WindowManager.LayoutParams#isSystemAlertWindowType(int)}
-     *        can be assigned layers greater than the layer for
-     *        {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY} Else, their
-     *        layers would be lesser.
-     * @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
-     */
-    default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow) {
-        if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
-            return APPLICATION_LAYER;
-        }
-
-        switch (type) {
-            case TYPE_WALLPAPER:
-                // wallpaper is at the bottom, though the window manager may move it.
-                return  1;
-            case TYPE_PRESENTATION:
-            case TYPE_PRIVATE_PRESENTATION:
-                return  APPLICATION_LAYER;
-            case TYPE_DOCK_DIVIDER:
-                return  APPLICATION_LAYER;
-            case TYPE_QS_DIALOG:
-                return  APPLICATION_LAYER;
-            case TYPE_PHONE:
-                return  3;
-            case TYPE_SEARCH_BAR:
-            case TYPE_VOICE_INTERACTION_STARTING:
-                return  4;
-            case TYPE_VOICE_INTERACTION:
-                // voice interaction layer is almost immediately above apps.
-                return  5;
-            case TYPE_INPUT_CONSUMER:
-                return  6;
-            case TYPE_SYSTEM_DIALOG:
-                return  7;
-            case TYPE_TOAST:
-                // toasts and the plugged-in battery thing
-                return  8;
-            case TYPE_PRIORITY_PHONE:
-                // SIM errors and unlock.  Not sure if this really should be in a high layer.
-                return  9;
-            case TYPE_SYSTEM_ALERT:
-                // like the ANR / app crashed dialogs
-                return  canAddInternalSystemWindow ? 11 : 10;
-            case TYPE_APPLICATION_OVERLAY:
-                return  12;
-            case TYPE_DREAM:
-                // used for Dreams (screensavers with TYPE_DREAM windows)
-                return  13;
-            case TYPE_INPUT_METHOD:
-                // on-screen keyboards and other such input method user interfaces go here.
-                return  14;
-            case TYPE_INPUT_METHOD_DIALOG:
-                // on-screen keyboards and other such input method user interfaces go here.
-                return  15;
-            case TYPE_STATUS_BAR_SUB_PANEL:
-                return  17;
-            case TYPE_STATUS_BAR:
-                return  18;
-            case TYPE_STATUS_BAR_PANEL:
-                return  19;
-            case TYPE_KEYGUARD_DIALOG:
-                return  20;
-            case TYPE_VOLUME_OVERLAY:
-                // the on-screen volume indicator and controller shown when the user
-                // changes the device volume
-                return  21;
-            case TYPE_SYSTEM_OVERLAY:
-                // the on-screen volume indicator and controller shown when the user
-                // changes the device volume
-                return  canAddInternalSystemWindow ? 22 : 11;
-            case TYPE_NAVIGATION_BAR:
-                // the navigation bar, if available, shows atop most things
-                return  23;
-            case TYPE_NAVIGATION_BAR_PANEL:
-                // some panels (e.g. search) need to show on top of the navigation bar
-                return  24;
-            case TYPE_SCREENSHOT:
-                // screenshot selection layer shouldn't go above system error, but it should cover
-                // navigation bars at the very least.
-                return  25;
-            case TYPE_SYSTEM_ERROR:
-                // system-level error dialogs
-                return  canAddInternalSystemWindow ? 26 : 10;
-            case TYPE_MAGNIFICATION_OVERLAY:
-                // used to highlight the magnified portion of a display
-                return  27;
-            case TYPE_DISPLAY_OVERLAY:
-                // used to simulate secondary display devices
-                return  28;
-            case TYPE_DRAG:
-                // the drag layer: input for drag-and-drop is associated with this window,
-                // which sits above all other focusable windows
-                return  29;
-            case TYPE_ACCESSIBILITY_OVERLAY:
-                // overlay put by accessibility services to intercept user interaction
-                return  30;
-            case TYPE_SECURE_SYSTEM_OVERLAY:
-                return  31;
-            case TYPE_BOOT_PROGRESS:
-                return  32;
-            case TYPE_POINTER:
-                // the (mouse) pointer layer
-                return  33;
-            default:
-                Slog.e("WindowManager", "Unknown window type: " + type);
-                return APPLICATION_LAYER;
-        }
-    }
-
-    int APPLICATION_LAYER = 2;
-    int APPLICATION_MEDIA_SUBLAYER = -2;
-    int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
-    int APPLICATION_PANEL_SUBLAYER = 1;
-    int APPLICATION_SUB_PANEL_SUBLAYER = 2;
-    int APPLICATION_ABOVE_SUB_PANEL_SUBLAYER = 3;
-
-    /**
-     * Return how to Z-order sub-windows in relation to the window they are attached to.
-     * Return positive to have them ordered in front, negative for behind.
-     *
-     * @param type The sub-window type code.
-     *
-     * @return int Layer in relation to the attached window, where positive is
-     *         above and negative is below.
-     */
-    default int getSubWindowLayerFromTypeLw(int type) {
-        switch (type) {
-            case TYPE_APPLICATION_PANEL:
-            case TYPE_APPLICATION_ATTACHED_DIALOG:
-                return APPLICATION_PANEL_SUBLAYER;
-            case TYPE_APPLICATION_MEDIA:
-                return APPLICATION_MEDIA_SUBLAYER;
-            case TYPE_APPLICATION_MEDIA_OVERLAY:
-                return APPLICATION_MEDIA_OVERLAY_SUBLAYER;
-            case TYPE_APPLICATION_SUB_PANEL:
-                return APPLICATION_SUB_PANEL_SUBLAYER;
-            case TYPE_APPLICATION_ABOVE_SUB_PANEL:
-                return APPLICATION_ABOVE_SUB_PANEL_SUBLAYER;
-        }
-        Slog.e("WindowManager", "Unknown sub-window type: " + type);
-        return 0;
-    }
-
-    /**
-     * Get the highest layer (actually one more than) that the wallpaper is
-     * allowed to be in.
-     */
-    public int getMaxWallpaperLayer();
-
-    /**
-     * Return the display width available after excluding any screen
-     * decorations that could never be removed in Honeycomb. That is, system bar or
-     * button bar.
-     */
-    public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation,
-            int uiMode, int displayId);
-
-    /**
-     * Return the display height available after excluding any screen
-     * decorations that could never be removed in Honeycomb. That is, system bar or
-     * button bar.
-     */
-    public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation,
-            int uiMode, int displayId);
-
-    /**
-     * Return the available screen width that we should report for the
-     * configuration.  This must be no larger than
-     * {@link #getNonDecorDisplayWidth(int, int, int)}; it may be smaller than
-     * that to account for more transient decoration like a status bar.
-     */
-    public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation,
-            int uiMode, int displayId);
-
-    /**
-     * Return the available screen height that we should report for the
-     * configuration.  This must be no larger than
-     * {@link #getNonDecorDisplayHeight(int, int, int)}; it may be smaller than
-     * that to account for more transient decoration like a status bar.
-     */
-    public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation,
-            int uiMode, int displayId);
-
-    /**
-     * Return whether the given window can become the Keyguard window. Typically returns true for
-     * the StatusBar.
-     */
-    public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs);
-
-    /**
-     * @return whether {@param win} can be hidden by Keyguard
-     */
-    public boolean canBeHiddenByKeyguardLw(WindowState win);
-
-    /**
-     * Called when the system would like to show a UI to indicate that an
-     * application is starting.  You can use this to add a
-     * APPLICATION_STARTING_TYPE window with the given appToken to the window
-     * manager (using the normal window manager APIs) that will be shown until
-     * the application displays its own window.  This is called without the
-     * window manager locked so that you can call back into it.
-     *
-     * @param appToken Token of the application being started.
-     * @param packageName The name of the application package being started.
-     * @param theme Resource defining the application's overall visual theme.
-     * @param nonLocalizedLabel The default title label of the application if
-     *        no data is found in the resource.
-     * @param labelRes The resource ID the application would like to use as its name.
-     * @param icon The resource ID the application would like to use as its icon.
-     * @param windowFlags Window layout flags.
-     * @param overrideConfig override configuration to consider when generating
-     *        context to for resources.
-     * @param displayId Id of the display to show the splash screen at.
-     *
-     * @return The starting surface.
-     *
-     */
-    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);
-
-    /**
-     * Prepare for a window being added to the window manager.  You can throw an
-     * exception here to prevent the window being added, or do whatever setup
-     * you need to keep track of the window.
-     *
-     * @param win The window being added.
-     * @param attrs The window's LayoutParams.
-     *
-     * @return {@link WindowManagerGlobal#ADD_OKAY} if the add can proceed, else an
-     *         error code to abort the add.
-     */
-    public int prepareAddWindowLw(WindowState win,
-            WindowManager.LayoutParams attrs);
-
-    /**
-     * Called when a window is being removed from a window manager.  Must not
-     * throw an exception -- clean up as much as possible.
-     *
-     * @param win The window being removed.
-     */
-    public void removeWindowLw(WindowState win);
-
-    /**
-     * Control the animation to run when a window's state changes.  Return a
-     * non-0 number to force the animation to a specific resource ID, or 0
-     * to use the default animation.
-     *
-     * @param win The window that is changing.
-     * @param transit What is happening to the window: {@link #TRANSIT_ENTER},
-     *                {@link #TRANSIT_EXIT}, {@link #TRANSIT_SHOW}, or
-     *                {@link #TRANSIT_HIDE}.
-     *
-     * @return Resource ID of the actual animation to use, or 0 for none.
-     */
-    public int selectAnimationLw(WindowState win, int transit);
-
-    /**
-     * Determine the animation to run for a rotation transition based on the
-     * top fullscreen windows {@link WindowManager.LayoutParams#rotationAnimation}
-     * and whether it is currently fullscreen and frontmost.
-     *
-     * @param anim The exiting animation resource id is stored in anim[0], the
-     * entering animation resource id is stored in anim[1].
-     */
-    public void selectRotationAnimationLw(int anim[]);
-
-    /**
-     * Validate whether the current top fullscreen has specified the same
-     * {@link WindowManager.LayoutParams#rotationAnimation} value as that
-     * being passed in from the previous top fullscreen window.
-     *
-     * @param exitAnimId exiting resource id from the previous window.
-     * @param enterAnimId entering resource id from the previous window.
-     * @param forceDefault For rotation animations only, if true ignore the
-     * animation values and just return false.
-     * @return true if the previous values are still valid, false if they
-     * should be replaced with the default.
-     */
-    public boolean validateRotationAnimationLw(int exitAnimId, int enterAnimId,
-            boolean forceDefault);
-
-    /**
-     * Create and return an animation to re-display a window that was force hidden by Keyguard.
-     */
-    public Animation createHiddenByKeyguardExit(boolean onWallpaper,
-            boolean goingToNotificationShade);
-
-    /**
-     * Create and return an animation to let the wallpaper disappear after being shown behind
-     * Keyguard.
-     */
-    public Animation createKeyguardWallpaperExit(boolean goingToNotificationShade);
-
-    /**
-     * Called from the input reader thread before a key is enqueued.
-     *
-     * <p>There are some actions that need to be handled here because they
-     * affect the power state of the device, for example, the power keys.
-     * Generally, it's best to keep as little as possible in the queue thread
-     * because it's the most fragile.
-     * @param event The key event.
-     * @param policyFlags The policy flags associated with the key.
-     *
-     * @return Actions flags: may be {@link #ACTION_PASS_TO_USER}.
-     */
-    public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags);
-
-    /**
-     * Called from the input reader thread before a motion is enqueued when the device is in a
-     * non-interactive state.
-     *
-     * <p>There are some actions that need to be handled here because they
-     * affect the power state of the device, for example, waking on motions.
-     * Generally, it's best to keep as little as possible in the queue thread
-     * because it's the most fragile.
-     * @param policyFlags The policy flags associated with the motion.
-     *
-     * @return Actions flags: may be {@link #ACTION_PASS_TO_USER}.
-     */
-    public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags);
-
-    /**
-     * Called from the input dispatcher thread before a key is dispatched to a window.
-     *
-     * <p>Allows you to define
-     * behavior for keys that can not be overridden by applications.
-     * This method is called from the input thread, with no locks held.
-     *
-     * @param win The window that currently has focus.  This is where the key
-     *            event will normally go.
-     * @param event The key event.
-     * @param policyFlags The policy flags associated with the key.
-     * @return 0 if the key should be dispatched immediately, -1 if the key should
-     * not be dispatched ever, or a positive value indicating the number of
-     * milliseconds by which the key dispatch should be delayed before trying
-     * again.
-     */
-    public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags);
-
-    /**
-     * Called from the input dispatcher thread when an application did not handle
-     * a key that was dispatched to it.
-     *
-     * <p>Allows you to define default global behavior for keys that were not handled
-     * by applications.  This method is called from the input thread, with no locks held.
-     *
-     * @param win The window that currently has focus.  This is where the key
-     *            event will normally go.
-     * @param event The key event.
-     * @param policyFlags The policy flags associated with the key.
-     * @return Returns an alternate key event to redispatch as a fallback, or null to give up.
-     * The caller is responsible for recycling the key event.
-     */
-    public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags);
-
-    /**
-     * Called when layout of the windows is about to start.
-     *
-     * @param displayFrames frames of the display we are doing layout on.
-     * @param uiMode The current uiMode in configuration.
-     */
-    default void beginLayoutLw(DisplayFrames displayFrames, int uiMode) {}
-
-    /**
-     * Returns the bottom-most layer of the system decor, above which no policy decor should
-     * be applied.
-     */
-    public int getSystemDecorLayerLw();
-
-    /**
-     * Called for each window attached to the window manager as layout is proceeding. The
-     * implementation of this function must take care of setting the window's frame, either here or
-     * in finishLayout().
-     *
-     * @param win The window being positioned.
-     * @param attached For sub-windows, the window it is attached to; this
-     *                 window will already have had layoutWindow() called on it
-     *                 so you can use its Rect.  Otherwise null.
-     * @param displayFrames The display frames.
-     */
-    default void layoutWindowLw(
-            WindowState win, WindowState attached, DisplayFrames displayFrames) {}
-
-
-    /**
-     * Return the insets for the areas covered by system windows. These values are computed on the
-     * most recent layout, so they are not guaranteed to be correct.
-     *
-     * @param attrs The LayoutParams of the window.
-     * @param taskBounds The bounds of the task this window is on or {@code null} if no task is
-     *                   associated with the window.
-     * @param displayFrames display frames.
-     * @param outContentInsets The areas covered by system windows, expressed as positive insets.
-     * @param outStableInsets The areas covered by stable system windows irrespective of their
-     *                        current visibility. Expressed as positive insets.
-     * @param outOutsets The areas that are not real display, but we would like to treat as such.
-     * @return Whether to always consume the navigation bar.
-     *         See {@link #isNavBarForcedShownLw(WindowState)}.
-     */
-    default boolean getInsetHintLw(WindowManager.LayoutParams attrs, Rect taskBounds,
-            DisplayFrames displayFrames, Rect outContentInsets, Rect outStableInsets,
-            Rect outOutsets) {
-        return false;
-    }
-
-    /** Layout state may have changed (so another layout will be performed) */
-    static final int FINISH_LAYOUT_REDO_LAYOUT = 0x0001;
-    /** Configuration state may have changed */
-    static final int FINISH_LAYOUT_REDO_CONFIG = 0x0002;
-    /** Wallpaper may need to move */
-    static final int FINISH_LAYOUT_REDO_WALLPAPER = 0x0004;
-    /** Need to recompute animations */
-    static final int FINISH_LAYOUT_REDO_ANIM = 0x0008;
-
-    /**
-     * Called following layout of all windows before each window has policy applied.
-     *
-     * @param displayWidth The current full width of the screen.
-     * @param displayHeight The current full height of the screen.
-     */
-    public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight);
-
-    /**
-     * Called following layout of all window to apply policy to each window.
-     *
-     * @param win The window being positioned.
-     * @param attrs The LayoutParams of the window.
-     * @param attached For sub-windows, the window it is attached to. Otherwise null.
-     */
-    public void applyPostLayoutPolicyLw(WindowState win,
-            WindowManager.LayoutParams attrs, WindowState attached, WindowState imeTarget);
-
-    /**
-     * Called following layout of all windows and after policy has been applied
-     * to each window. If in this function you do
-     * something that may have modified the animation state of another window,
-     * be sure to return non-zero in order to perform another pass through layout.
-     *
-     * @return Return any bit set of {@link #FINISH_LAYOUT_REDO_LAYOUT},
-     * {@link #FINISH_LAYOUT_REDO_CONFIG}, {@link #FINISH_LAYOUT_REDO_WALLPAPER},
-     * or {@link #FINISH_LAYOUT_REDO_ANIM}.
-     */
-    public int finishPostLayoutPolicyLw();
-
-    /**
-     * Return true if it is okay to perform animations for an app transition
-     * that is about to occur.  You may return false for this if, for example,
-     * the lock screen is currently displayed so the switch should happen
-     * immediately.
-     */
-    public boolean allowAppAnimationsLw();
-
-
-    /**
-     * A new window has been focused.
-     */
-    public int focusChangedLw(WindowState lastFocus, WindowState newFocus);
-
-    /**
-     * Called when the device has started waking up.
-     */
-    public void startedWakingUp();
-
-    /**
-     * Called when the device has finished waking up.
-     */
-    public void finishedWakingUp();
-
-    /**
-     * Called when the device has started going to sleep.
-     *
-     * @param why {@link #OFF_BECAUSE_OF_USER}, {@link #OFF_BECAUSE_OF_ADMIN},
-     * or {@link #OFF_BECAUSE_OF_TIMEOUT}.
-     */
-    public void startedGoingToSleep(int why);
-
-    /**
-     * Called when the device has finished going to sleep.
-     *
-     * @param why {@link #OFF_BECAUSE_OF_USER}, {@link #OFF_BECAUSE_OF_ADMIN},
-     * or {@link #OFF_BECAUSE_OF_TIMEOUT}.
-     */
-    public void finishedGoingToSleep(int why);
-
-    /**
-     * Called when the device is about to turn on the screen to show content.
-     * When waking up, this method will be called once after the call to wakingUp().
-     * When dozing, the method will be called sometime after the call to goingToSleep() and
-     * may be called repeatedly in the case where the screen is pulsing on and off.
-     *
-     * Must call back on the listener to tell it when the higher-level system
-     * is ready for the screen to go on (i.e. the lock screen is shown).
-     */
-    public void screenTurningOn(ScreenOnListener screenOnListener);
-
-    /**
-     * Called when the device has actually turned on the screen, i.e. the display power state has
-     * been set to ON and the screen is unblocked.
-     */
-    public void screenTurnedOn();
-
-    /**
-     * Called when the display would like to be turned off. This gives policy a chance to do some
-     * things before the display power state is actually changed to off.
-     *
-     * @param screenOffListener Must be called to tell that the display power state can actually be
-     *                          changed now after policy has done its work.
-     */
-    public void screenTurningOff(ScreenOffListener screenOffListener);
-
-    /**
-     * Called when the device has turned the screen off.
-     */
-    public void screenTurnedOff();
-
-    public interface ScreenOnListener {
-        void onScreenOn();
-    }
-
-    /**
-     * See {@link #screenTurnedOff}
-     */
-    public interface ScreenOffListener {
-        void onScreenOff();
-    }
-
-    /**
-     * Return whether the default display is on and not blocked by a black surface.
-     */
-    public boolean isScreenOn();
-
-    /**
-     * @return whether the device is currently allowed to animate.
-     *
-     * Note: this can be true even if it is not appropriate to animate for reasons that are outside
-     *       of the policy's authority.
-     */
-    boolean okToAnimate();
-
-    /**
-     * Tell the policy that the lid switch has changed state.
-     * @param whenNanos The time when the change occurred in uptime nanoseconds.
-     * @param lidOpen True if the lid is now open.
-     */
-    public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen);
-
-    /**
-     * Tell the policy that the camera lens has been covered or uncovered.
-     * @param whenNanos The time when the change occurred in uptime nanoseconds.
-     * @param lensCovered True if the lens is covered.
-     */
-    public void notifyCameraLensCoverSwitchChanged(long whenNanos, boolean lensCovered);
-
-    /**
-     * Tell the policy if anyone is requesting that keyguard not come on.
-     *
-     * @param enabled Whether keyguard can be on or not.  does not actually
-     * turn it on, unless it was previously disabled with this function.
-     *
-     * @see android.app.KeyguardManager.KeyguardLock#disableKeyguard()
-     * @see android.app.KeyguardManager.KeyguardLock#reenableKeyguard()
-     */
-    @SuppressWarnings("javadoc")
-    public void enableKeyguard(boolean enabled);
-
-    /**
-     * Callback used by {@link WindowManagerPolicy#exitKeyguardSecurely}
-     */
-    interface OnKeyguardExitResult {
-        void onKeyguardExitResult(boolean success);
-    }
-
-    /**
-     * Tell the policy if anyone is requesting the keyguard to exit securely
-     * (this would be called after the keyguard was disabled)
-     * @param callback Callback to send the result back.
-     * @see android.app.KeyguardManager#exitKeyguardSecurely(android.app.KeyguardManager.OnKeyguardExitResult)
-     */
-    @SuppressWarnings("javadoc")
-    void exitKeyguardSecurely(OnKeyguardExitResult callback);
-
-    /**
-     * isKeyguardLocked
-     *
-     * Return whether the keyguard is currently locked.
-     *
-     * @return true if in keyguard is locked.
-     */
-    public boolean isKeyguardLocked();
-
-    /**
-     * isKeyguardSecure
-     *
-     * Return whether the keyguard requires a password to unlock.
-     * @param userId
-     *
-     * @return true if in keyguard is secure.
-     */
-    public boolean isKeyguardSecure(int userId);
-
-    /**
-     * Return whether the keyguard is currently occluded.
-     *
-     * @return true if in keyguard is occluded, false otherwise
-     */
-    public boolean isKeyguardOccluded();
-
-    /**
-     * @return true if in keyguard is on and not occluded.
-     */
-    public boolean isKeyguardShowingAndNotOccluded();
-
-    /**
-     * @return whether Keyguard is in trusted state and can be dismissed without credentials
-     */
-    public boolean isKeyguardTrustedLw();
-
-    /**
-     * inKeyguardRestrictedKeyInputMode
-     *
-     * if keyguard screen is showing or in restricted key input mode (i.e. in
-     * keyguard password emergency screen). When in such mode, certain keys,
-     * such as the Home key and the right soft keys, don't work.
-     *
-     * @return true if in keyguard restricted input mode.
-     */
-    public boolean inKeyguardRestrictedKeyInputMode();
-
-    /**
-     * Ask the policy to dismiss the keyguard, if it is currently shown.
-     *
-     * @param callback Callback to be informed about the result.
-     */
-    public void dismissKeyguardLw(@Nullable IKeyguardDismissCallback callback);
-
-    /**
-     * Ask the policy whether the Keyguard has drawn. If the Keyguard is disabled, this method
-     * returns true as soon as we know that Keyguard is disabled.
-     *
-     * @return true if the keyguard has drawn.
-     */
-    public boolean isKeyguardDrawnLw();
-
-    public boolean isShowingDreamLw();
-
-    /**
-     * Given an orientation constant, returns the appropriate surface rotation,
-     * taking into account sensors, docking mode, rotation lock, and other factors.
-     *
-     * @param orientation An orientation constant, such as
-     * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
-     * @param lastRotation The most recently used rotation.
-     * @return The surface rotation to use.
-     */
-    public int rotationForOrientationLw(@ActivityInfo.ScreenOrientation int orientation,
-            int lastRotation);
-
-    /**
-     * Given an orientation constant and a rotation, returns true if the rotation
-     * has compatible metrics to the requested orientation.  For example, if
-     * the application requested landscape and got seascape, then the rotation
-     * has compatible metrics; if the application requested portrait and got landscape,
-     * then the rotation has incompatible metrics; if the application did not specify
-     * a preference, then anything goes.
-     *
-     * @param orientation An orientation constant, such as
-     * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
-     * @param rotation The rotation to check.
-     * @return True if the rotation is compatible with the requested orientation.
-     */
-    public boolean rotationHasCompatibleMetricsLw(@ActivityInfo.ScreenOrientation int orientation,
-            int rotation);
-
-    /**
-     * Called by the window manager when the rotation changes.
-     *
-     * @param rotation The new rotation.
-     */
-    public void setRotationLw(int rotation);
-
-    /**
-     * Called when the system is mostly done booting to set whether
-     * the system should go into safe mode.
-     */
-    public void setSafeMode(boolean safeMode);
-
-    /**
-     * Called when the system is mostly done booting.
-     */
-    public void systemReady();
-
-    /**
-     * Called when the system is done booting to the point where the
-     * user can start interacting with it.
-     */
-    public void systemBooted();
-
-    /**
-     * Show boot time message to the user.
-     */
-    public void showBootMessage(final CharSequence msg, final boolean always);
-
-    /**
-     * Hide the UI for showing boot messages, never to be displayed again.
-     */
-    public void hideBootMessages();
-
-    /**
-     * Called when userActivity is signalled in the power manager.
-     * This is safe to call from any thread, with any window manager locks held or not.
-     */
-    public void userActivity();
-
-    /**
-     * Called when we have finished booting and can now display the home
-     * screen to the user.  This will happen after systemReady(), and at
-     * this point the display is active.
-     */
-    public void enableScreenAfterBoot();
-
-    public void setCurrentOrientationLw(@ActivityInfo.ScreenOrientation int newOrientation);
-
-    /**
-     * Call from application to perform haptic feedback on its window.
-     */
-    public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always);
-
-    /**
-     * Called when we have started keeping the screen on because a window
-     * requesting this has become visible.
-     */
-    public void keepScreenOnStartedLw();
-
-    /**
-     * Called when we have stopped keeping the screen on because the last window
-     * requesting this is no longer visible.
-     */
-    public void keepScreenOnStoppedLw();
-
-    /**
-     * Gets the current user rotation mode.
-     *
-     * @return The rotation mode.
-     *
-     * @see WindowManagerPolicy#USER_ROTATION_LOCKED
-     * @see WindowManagerPolicy#USER_ROTATION_FREE
-     */
-    @UserRotationMode
-    public int getUserRotationMode();
-
-    /**
-     * Inform the policy that the user has chosen a preferred orientation ("rotation lock").
-     *
-     * @param mode One of {@link WindowManagerPolicy#USER_ROTATION_LOCKED} or
-     *             {@link WindowManagerPolicy#USER_ROTATION_FREE}.
-     * @param rotation One of {@link Surface#ROTATION_0}, {@link Surface#ROTATION_90},
-     *                 {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}.
-     */
-    public void setUserRotationMode(@UserRotationMode int mode, @Surface.Rotation int rotation);
-
-    /**
-     * Called when a new system UI visibility is being reported, allowing
-     * the policy to adjust what is actually reported.
-     * @param visibility The raw visibility reported by the status bar.
-     * @return The new desired visibility.
-     */
-    public int adjustSystemUiVisibilityLw(int visibility);
-
-    /**
-     * Called by System UI to notify of changes to the visibility of Recents.
-     */
-    public void setRecentsVisibilityLw(boolean visible);
-
-    /**
-     * Called by System UI to notify of changes to the visibility of PIP.
-     */
-    void setPipVisibilityLw(boolean visible);
-
-    /**
-     * Specifies whether there is an on-screen navigation bar separate from the status bar.
-     */
-    public boolean hasNavigationBar();
-
-    /**
-     * Lock the device now.
-     */
-    public void lockNow(Bundle options);
-
-    /**
-     * Set the last used input method window state. This state is used to make IME transition
-     * smooth.
-     * @hide
-     */
-    public void setLastInputMethodWindowLw(WindowState ime, WindowState target);
-
-    /**
-     * An internal callback (from InputMethodManagerService) to notify a state change regarding
-     * whether the back key should dismiss the software keyboard (IME) or not.
-     *
-     * @param newValue {@code true} if the software keyboard is shown and the back key is expected
-     *                 to dismiss the software keyboard.
-     * @hide
-     */
-    default void setDismissImeOnBackKeyPressed(boolean newValue) {
-        // Default implementation does nothing.
-    }
-
-    /**
-     * Show the recents task list app.
-     * @hide
-     */
-    public void showRecentApps(boolean fromHome);
-
-    /**
-     * Show the global actions dialog.
-     * @hide
-     */
-    public void showGlobalActions();
-
-    /**
-     * Called when the current user changes. Guaranteed to be called before the broadcast
-     * of the new user id is made to all listeners.
-     *
-     * @param newUserId The id of the incoming user.
-     */
-    public void setCurrentUserLw(int newUserId);
-
-    /**
-     * For a given user-switch operation, this will be called once with switching=true before the
-     * user-switch and once with switching=false afterwards (or if the user-switch was cancelled).
-     * This gives the policy a chance to alter its behavior for the duration of a user-switch.
-     *
-     * @param switching true if a user-switch is in progress
-     */
-    void setSwitchingUser(boolean switching);
-
-    /**
-     * Print the WindowManagerPolicy's state into the given stream.
-     *
-     * @param prefix Text to print at the front of each line.
-     * @param writer The PrintWriter to which you should dump your state.  This will be
-     * closed for you after you return.
-     * @param args additional arguments to the dump request.
-     */
-    public void dump(String prefix, PrintWriter writer, String[] args);
-
-    /**
-     * Write the WindowManagerPolicy's state into the protocol buffer.
-     * The message is described in {@link com.android.server.wm.proto.WindowManagerPolicyProto}
-     *
-     * @param proto The protocol buffer output stream to write to.
-     */
-    void writeToProto(ProtoOutputStream proto, long fieldId);
-
-    /**
-     * Returns whether a given window type is considered a top level one.
-     * A top level window does not have a container, i.e. attached window,
-     * or if it has a container it is laid out as a top-level window, not
-     * as a child of its container.
-     *
-     * @param windowType The window type.
-     * @return True if the window is a top level one.
-     */
-    public boolean isTopLevelWindow(int windowType);
-
-    /**
-     * Notifies the keyguard to start fading out.
-     *
-     * @param startTime the start time of the animation in uptime milliseconds
-     * @param fadeoutDuration the duration of the exit animation, in milliseconds
-     */
-    public void startKeyguardExitAnimation(long startTime, long fadeoutDuration);
-
-    /**
-     * Calculates the stable insets without running a layout.
-     *
-     * @param displayRotation the current display rotation
-     * @param displayWidth the current display width
-     * @param displayHeight the current display height
-     * @param outInsets the insets to return
-     */
-    public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight,
-            Rect outInsets);
-
-
-    /**
-     * @return true if the navigation bar is forced to stay visible
-     */
-    public boolean isNavBarForcedShownLw(WindowState win);
-
-    /**
-     * @return The side of the screen where navigation bar is positioned.
-     * @see #NAV_BAR_LEFT
-     * @see #NAV_BAR_RIGHT
-     * @see #NAV_BAR_BOTTOM
-     */
-    int getNavBarPosition();
-
-    /**
-     * Calculates the insets for the areas that could never be removed in Honeycomb, i.e. system
-     * bar or button bar. See {@link #getNonDecorDisplayWidth}.
-     *
-     * @param displayRotation the current display rotation
-     * @param displayWidth the current display width
-     * @param displayHeight the current display height
-     * @param outInsets the insets to return
-     */
-    public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight,
-            Rect outInsets);
-
-    /**
-     * @return True if a specified {@param dockSide} is allowed on the current device, or false
-     *         otherwise. It is guaranteed that at least one dock side for a particular orientation
-     *         is allowed, so for example, if DOCKED_RIGHT is not allowed, DOCKED_LEFT is allowed.
-     */
-    public boolean isDockSideAllowed(int dockSide);
-
-    /**
-     * Called when the configuration has changed, and it's safe to load new values from resources.
-     */
-    public void onConfigurationChanged();
-
-    public boolean shouldRotateSeamlessly(int oldRotation, int newRotation);
-
-    /**
-     * Called when System UI has been started.
-     */
-    void onSystemUiStarted();
-
-    /**
-     * Checks whether the policy is ready for dismissing the boot animation and completing the boot.
-     *
-     * @return true if ready; false otherwise.
-     */
-    boolean canDismissBootAnimation();
-
-    /**
-     * Convert the user rotation mode to a human readable format.
-     */
-    static String userRotationModeToString(int mode) {
-        switch(mode) {
-            case USER_ROTATION_FREE:
-                return "USER_ROTATION_FREE";
-            case USER_ROTATION_LOCKED:
-                return "USER_ROTATION_LOCKED";
-            default:
-                return Integer.toString(mode);
-        }
-    }
-
-    /**
-     * Convert the off reason to a human readable format.
-     */
-    static String offReasonToString(int why) {
-        switch (why) {
-            case OFF_BECAUSE_OF_ADMIN:
-                return "OFF_BECAUSE_OF_ADMIN";
-            case OFF_BECAUSE_OF_USER:
-                return "OFF_BECAUSE_OF_USER";
-            case OFF_BECAUSE_OF_TIMEOUT:
-                return "OFF_BECAUSE_OF_TIMEOUT";
-            default:
-                return Integer.toString(why);
-        }
-    }
-}
diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java
new file mode 100644
index 0000000..21943bd
--- /dev/null
+++ b/core/java/android/view/WindowManagerPolicyConstants.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2006 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 android.view;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.annotation.SystemApi;
+
+/**
+ * Constants for interfacing with WindowManagerService and WindowManagerPolicyInternal.
+ * @hide
+ */
+public interface WindowManagerPolicyConstants {
+    // Policy flags.  These flags are also defined in frameworks/base/include/ui/Input.h.
+    int FLAG_WAKE = 0x00000001;
+    int FLAG_VIRTUAL = 0x00000002;
+
+    int FLAG_INJECTED = 0x01000000;
+    int FLAG_TRUSTED = 0x02000000;
+    int FLAG_FILTERED = 0x04000000;
+    int FLAG_DISABLE_KEY_REPEAT = 0x08000000;
+
+    int FLAG_INTERACTIVE = 0x20000000;
+    int FLAG_PASS_TO_USER = 0x40000000;
+
+    // Flags for IActivityManager.keyguardGoingAway()
+    int KEYGUARD_GOING_AWAY_FLAG_TO_SHADE = 1 << 0;
+    int KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS = 1 << 1;
+    int KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER = 1 << 2;
+
+    // Flags used for indicating whether the internal and/or external input devices
+    // of some type are available.
+    int PRESENCE_INTERNAL = 1 << 0;
+    int PRESENCE_EXTERNAL = 1 << 1;
+
+    /**
+     * Sticky broadcast of the current HDMI plugged state.
+     */
+    String ACTION_HDMI_PLUGGED = "android.intent.action.HDMI_PLUGGED";
+
+    /**
+     * Extra in {@link #ACTION_HDMI_PLUGGED} indicating the state: true if
+     * plugged in to HDMI, false if not.
+     */
+    String EXTRA_HDMI_PLUGGED_STATE = "state";
+
+    /**
+     * Set to {@code true} when intent was invoked from pressing the home key.
+     * @hide
+     */
+    @SystemApi
+    String EXTRA_FROM_HOME_KEY = "android.intent.extra.FROM_HOME_KEY";
+
+    // TODO: move this to a more appropriate place.
+    interface PointerEventListener {
+        /**
+         * 1. onPointerEvent will be called on the service.UiThread.
+         * 2. motionEvent will be recycled after onPointerEvent returns so if it is needed later a
+         * copy() must be made and the copy must be recycled.
+         **/
+        void onPointerEvent(MotionEvent motionEvent);
+
+        /**
+         * @see #onPointerEvent(MotionEvent)
+         **/
+        default void onPointerEvent(MotionEvent motionEvent, int displayId) {
+            if (displayId == DEFAULT_DISPLAY) {
+                onPointerEvent(motionEvent);
+            }
+        }
+    }
+
+    /** Screen turned off because of a device admin */
+    int OFF_BECAUSE_OF_ADMIN = 1;
+    /** Screen turned off because of power button */
+    int OFF_BECAUSE_OF_USER = 2;
+    /** Screen turned off because of timeout */
+    int OFF_BECAUSE_OF_TIMEOUT = 3;
+
+    int APPLICATION_LAYER = 2;
+    int APPLICATION_MEDIA_SUBLAYER = -2;
+    int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
+    int APPLICATION_PANEL_SUBLAYER = 1;
+    int APPLICATION_SUB_PANEL_SUBLAYER = 2;
+    int APPLICATION_ABOVE_SUB_PANEL_SUBLAYER = 3;
+
+    /**
+     * Convert the off reason to a human readable format.
+     */
+    static String offReasonToString(int why) {
+        switch (why) {
+            case OFF_BECAUSE_OF_ADMIN:
+                return "OFF_BECAUSE_OF_ADMIN";
+            case OFF_BECAUSE_OF_USER:
+                return "OFF_BECAUSE_OF_USER";
+            case OFF_BECAUSE_OF_TIMEOUT:
+                return "OFF_BECAUSE_OF_TIMEOUT";
+            default:
+                return Integer.toString(why);
+        }
+    }
+}
