Alert Windows behavioral changes

- Introduced TYPE_APPLICATION_OVERLAY window type. Can be used by apps
to display windows on top of other app windows, but below critical
system windows.
- Deprecate alert window types TYPE_PHONE, TYPE_SYSTEM_ALERT,
TYPE_SYSTEM_OVERLAY, TYPE_PRIORITY_PHONE, and TYPE_SYSTEM_ERROR.
Apps should now use TYPE_APP_OVERLAY for this.
- Apps targetting O or greater are not allowed to add the old alert
window types.
Apps targetting less than O can still add the old types.
Apps with permission INTERNAL_SYSTEM_WINDOW (system signature apps) can
still add the old types.
- Z-order old alert windows types below TYPE_APPLICATION_OVERLAY if
they are added by an app without the INTERNAL_SYSTEM_WINDOW permission.

Test: android.server.cts.AlertWindowsTests
Bug: 33256752
Change-Id: I12170955a7a333151d3387c169b51c53c32164fc
diff --git a/api/current.txt b/api/current.txt
index 4f63ff6..8219531 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -45684,6 +45684,7 @@
     field public static final int TYPE_APPLICATION = 2; // 0x2
     field public static final int TYPE_APPLICATION_ATTACHED_DIALOG = 1003; // 0x3eb
     field public static final int TYPE_APPLICATION_MEDIA = 1001; // 0x3e9
+    field public static final int TYPE_APPLICATION_OVERLAY = 2038; // 0x7f6
     field public static final int TYPE_APPLICATION_PANEL = 1000; // 0x3e8
     field public static final int TYPE_APPLICATION_STARTING = 3; // 0x3
     field public static final int TYPE_APPLICATION_SUB_PANEL = 1002; // 0x3ea
@@ -45693,17 +45694,17 @@
     field public static final int TYPE_INPUT_METHOD = 2011; // 0x7db
     field public static final int TYPE_INPUT_METHOD_DIALOG = 2012; // 0x7dc
     field public static final int TYPE_KEYGUARD_DIALOG = 2009; // 0x7d9
-    field public static final int TYPE_PHONE = 2002; // 0x7d2
-    field public static final int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
+    field public static final deprecated int TYPE_PHONE = 2002; // 0x7d2
+    field public static final deprecated int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
     field public static final int TYPE_PRIVATE_PRESENTATION = 2030; // 0x7ee
     field public static final int TYPE_SEARCH_BAR = 2001; // 0x7d1
     field public static final int TYPE_STATUS_BAR = 2000; // 0x7d0
     field public static final int TYPE_STATUS_BAR_PANEL = 2014; // 0x7de
-    field public static final int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
+    field public static final deprecated int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
     field public static final int TYPE_SYSTEM_DIALOG = 2008; // 0x7d8
-    field public static final int TYPE_SYSTEM_ERROR = 2010; // 0x7da
-    field public static final int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
-    field public static final int TYPE_TOAST = 2005; // 0x7d5
+    field public static final deprecated int TYPE_SYSTEM_ERROR = 2010; // 0x7da
+    field public static final deprecated int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
+    field public static final deprecated int TYPE_TOAST = 2005; // 0x7d5
     field public static final int TYPE_WALLPAPER = 2013; // 0x7dd
     field public float alpha;
     field public float buttonBrightness;
diff --git a/api/system-current.txt b/api/system-current.txt
index 03710e6..ce306bd 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -49093,6 +49093,7 @@
     field public static final int TYPE_APPLICATION = 2; // 0x2
     field public static final int TYPE_APPLICATION_ATTACHED_DIALOG = 1003; // 0x3eb
     field public static final int TYPE_APPLICATION_MEDIA = 1001; // 0x3e9
+    field public static final int TYPE_APPLICATION_OVERLAY = 2038; // 0x7f6
     field public static final int TYPE_APPLICATION_PANEL = 1000; // 0x3e8
     field public static final int TYPE_APPLICATION_STARTING = 3; // 0x3
     field public static final int TYPE_APPLICATION_SUB_PANEL = 1002; // 0x3ea
@@ -49102,17 +49103,17 @@
     field public static final int TYPE_INPUT_METHOD = 2011; // 0x7db
     field public static final int TYPE_INPUT_METHOD_DIALOG = 2012; // 0x7dc
     field public static final int TYPE_KEYGUARD_DIALOG = 2009; // 0x7d9
-    field public static final int TYPE_PHONE = 2002; // 0x7d2
-    field public static final int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
+    field public static final deprecated int TYPE_PHONE = 2002; // 0x7d2
+    field public static final deprecated int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
     field public static final int TYPE_PRIVATE_PRESENTATION = 2030; // 0x7ee
     field public static final int TYPE_SEARCH_BAR = 2001; // 0x7d1
     field public static final int TYPE_STATUS_BAR = 2000; // 0x7d0
     field public static final int TYPE_STATUS_BAR_PANEL = 2014; // 0x7de
-    field public static final int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
+    field public static final deprecated int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
     field public static final int TYPE_SYSTEM_DIALOG = 2008; // 0x7d8
-    field public static final int TYPE_SYSTEM_ERROR = 2010; // 0x7da
-    field public static final int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
-    field public static final int TYPE_TOAST = 2005; // 0x7d5
+    field public static final deprecated int TYPE_SYSTEM_ERROR = 2010; // 0x7da
+    field public static final deprecated int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
+    field public static final deprecated int TYPE_TOAST = 2005; // 0x7d5
     field public static final int TYPE_WALLPAPER = 2013; // 0x7dd
     field public float alpha;
     field public float buttonBrightness;
diff --git a/api/test-current.txt b/api/test-current.txt
index 29d152a..ceb2465 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -45995,6 +45995,7 @@
     field public static final int TYPE_APPLICATION = 2; // 0x2
     field public static final int TYPE_APPLICATION_ATTACHED_DIALOG = 1003; // 0x3eb
     field public static final int TYPE_APPLICATION_MEDIA = 1001; // 0x3e9
+    field public static final int TYPE_APPLICATION_OVERLAY = 2038; // 0x7f6
     field public static final int TYPE_APPLICATION_PANEL = 1000; // 0x3e8
     field public static final int TYPE_APPLICATION_STARTING = 3; // 0x3
     field public static final int TYPE_APPLICATION_SUB_PANEL = 1002; // 0x3ea
@@ -46004,17 +46005,17 @@
     field public static final int TYPE_INPUT_METHOD = 2011; // 0x7db
     field public static final int TYPE_INPUT_METHOD_DIALOG = 2012; // 0x7dc
     field public static final int TYPE_KEYGUARD_DIALOG = 2009; // 0x7d9
-    field public static final int TYPE_PHONE = 2002; // 0x7d2
-    field public static final int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
+    field public static final deprecated int TYPE_PHONE = 2002; // 0x7d2
+    field public static final deprecated int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
     field public static final int TYPE_PRIVATE_PRESENTATION = 2030; // 0x7ee
     field public static final int TYPE_SEARCH_BAR = 2001; // 0x7d1
     field public static final int TYPE_STATUS_BAR = 2000; // 0x7d0
     field public static final int TYPE_STATUS_BAR_PANEL = 2014; // 0x7de
-    field public static final int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
+    field public static final deprecated int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
     field public static final int TYPE_SYSTEM_DIALOG = 2008; // 0x7d8
-    field public static final int TYPE_SYSTEM_ERROR = 2010; // 0x7da
-    field public static final int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
-    field public static final int TYPE_TOAST = 2005; // 0x7d5
+    field public static final deprecated int TYPE_SYSTEM_ERROR = 2010; // 0x7da
+    field public static final deprecated int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
+    field public static final deprecated int TYPE_TOAST = 2005; // 0x7d5
     field public static final int TYPE_WALLPAPER = 2013; // 0x7dd
     field public float alpha;
     field public float buttonBrightness;
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 388054d..dfcab3d 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -516,6 +516,7 @@
      * <li>{@link LayoutParams#TYPE_SYSTEM_ALERT}</li>
      * <li>{@link LayoutParams#TYPE_SYSTEM_ERROR}</li>
      * <li>{@link LayoutParams#TYPE_SYSTEM_OVERLAY}</li>
+     * <li>{@link LayoutParams#TYPE_APPLICATION_OVERLAY}</li>
      *
      * <p>This can only be set by device owners and profile owners on the primary user.
      * The default value is <code>false</code>.
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index bf840e5..5a640fa 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -335,7 +335,9 @@
                 @ViewDebug.IntToString(from = TYPE_QS_DIALOG,
                         to = "TYPE_QS_DIALOG"),
                 @ViewDebug.IntToString(from = TYPE_SCREENSHOT,
-                        to = "TYPE_SCREENSHOT")
+                        to = "TYPE_SCREENSHOT"),
+                @ViewDebug.IntToString(from = TYPE_APPLICATION_OVERLAY,
+                        to = "TYPE_APPLICATION_OVERLAY")
         })
         public int type;
 
@@ -462,14 +464,18 @@
          * These windows are normally placed above all applications, but behind
          * the status bar.
          * In multiuser systems shows on all users' windows.
+         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
          */
+        @Deprecated
         public static final int TYPE_PHONE              = FIRST_SYSTEM_WINDOW+2;
 
         /**
          * Window type: system window, such as low power alert. These windows
          * are always on top of application windows.
          * In multiuser systems shows only on the owning user's window.
+         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
          */
+        @Deprecated
         public static final int TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3;
 
         /**
@@ -482,7 +488,9 @@
         /**
          * Window type: transient notifications.
          * In multiuser systems shows only on the owning user's window.
+         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
          */
+        @Deprecated
         public static final int TYPE_TOAST              = FIRST_SYSTEM_WINDOW+5;
 
         /**
@@ -490,7 +498,9 @@
          * on top of everything else.  These windows must not take input
          * focus, or they will interfere with the keyguard.
          * In multiuser systems shows only on the owning user's window.
+         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
          */
+        @Deprecated
         public static final int TYPE_SYSTEM_OVERLAY     = FIRST_SYSTEM_WINDOW+6;
 
         /**
@@ -498,7 +508,9 @@
          * the keyguard is active.  These windows must not take input
          * focus, or they will interfere with the keyguard.
          * In multiuser systems shows on all users' windows.
+         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
          */
+        @Deprecated
         public static final int TYPE_PRIORITY_PHONE     = FIRST_SYSTEM_WINDOW+7;
 
         /**
@@ -517,7 +529,9 @@
          * Window type: internal system error windows, appear on top of
          * everything they can.
          * In multiuser systems shows only on the owning user's window.
+         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
          */
+        @Deprecated
         public static final int TYPE_SYSTEM_ERROR       = FIRST_SYSTEM_WINDOW+10;
 
         /**
@@ -703,10 +717,44 @@
         public static final int TYPE_PRESENTATION = FIRST_SYSTEM_WINDOW + 37;
 
         /**
+         * Window type: Application overlay windows are displayed above all activity windows
+         * (types between {@link #FIRST_APPLICATION_WINDOW} and {@link #LAST_APPLICATION_WINDOW})
+         * but below critical system windows like the status bar or IME.
+         * <p>
+         * The system may change the position, size, or visibility of these windows at anytime
+         * to reduce visual clutter to the user and also manage resources.
+         * <p>
+         * Requires {@link android.Manifest.permission#SYSTEM_ALERT_WINDOW} permission.
+         * <p>
+         * In mult-iuser systems shows only on the owning user's screen.
+         */
+        public static final int TYPE_APPLICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 38;
+
+        /**
          * End of types of system windows.
          */
         public static final int LAST_SYSTEM_WINDOW      = 2999;
 
+        /**
+         * Return true if the window type is an alert window.
+         *
+         * @param type The window type.
+         * @return If the window type is an alert window.
+         * @hide
+         */
+        public static boolean isSystemAlertWindowType(int type) {
+            switch (type) {
+                case TYPE_PHONE:
+                case TYPE_PRIORITY_PHONE:
+                case TYPE_SYSTEM_ALERT:
+                case TYPE_SYSTEM_ERROR:
+                case TYPE_SYSTEM_OVERLAY:
+                case TYPE_APPLICATION_OVERLAY:
+                    return true;
+            }
+            return false;
+        }
+
         /** @deprecated this is ignored, this value is set automatically when needed. */
         @Deprecated
         public static final int MEMORY_TYPE_NORMAL = 0;
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index bc4ae6d..8e597dc 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -16,6 +16,51 @@
 
 package android.view;
 
+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;
@@ -30,6 +75,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
+import android.util.Slog;
 import android.view.animation.Animation;
 
 import com.android.internal.policy.IKeyguardDismissCallback;
@@ -423,6 +469,14 @@
         public boolean isInputMethodWindow();
 
         public int getDisplayId();
+
+        /**
+         * Returns true if the window owner can add internal system windows.
+         * That is, they have {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW}.
+         */
+        default boolean canAddInternalSystemWindow() {
+            return false;
+        }
     }
 
     /**
@@ -659,27 +713,181 @@
             int navigationPresence);
 
     /**
-     * Assign a window type to a layer.  Allows you to control how different
+     * 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.
+     * @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
      */
-    public int windowTypeToLayerLw(int type);
+    default int getWindowLayerFromTypeLw(int type) {
+        if (isSystemAlertWindowType(type)) {
+            throw new IllegalArgumentException("Use getWindowLayerFromTypeLw() or"
+                    + " getWindowLayerLw() for alert window types");
+        }
+        return getWindowLayerFromTypeLw(type, false /* canAddInternalSystemWindow */);
+    }
 
     /**
-     * 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.
+     * 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 android.Manifest.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_DREAM:
+                // used for Dreams (screensavers with TYPE_DREAM windows)
+                return  10;
+            case TYPE_SYSTEM_ALERT:
+                // like the ANR / app crashed dialogs
+                return  canAddInternalSystemWindow ? 11 : 10;
+            case TYPE_APPLICATION_OVERLAY:
+                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.
      */
-    public int subWindowTypeToLayerLw(int type);
+    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
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 3ba8915..a861522 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -3899,6 +3899,7 @@
                 case WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG:
                 case WindowManager.LayoutParams.TYPE_SYSTEM_ERROR:
                 case WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY:
+                case WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY:
                 case WindowManager.LayoutParams.TYPE_SCREENSHOT: {
                     return AccessibilityWindowInfo.TYPE_SYSTEM;
                 }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 37fff68..180f6c9 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -16,17 +16,24 @@
 
 package com.android.server.policy;
 
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
+import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
+import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
+import static android.app.AppOpsManager.OP_TOAST_WINDOW;
 import static android.content.Context.DISPLAY_SERVICE;
 import static android.content.Context.WINDOW_SERVICE;
 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
 import static android.content.pm.PackageManager.FEATURE_TELEVISION;
 import static android.content.pm.PackageManager.FEATURE_WATCH;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.content.res.Configuration.EMPTY;
 import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
 import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
+import static android.os.Build.VERSION_CODES.M;
+import static android.os.Build.VERSION_CODES.O;
 import static android.view.WindowManager.DOCKED_LEFT;
 import static android.view.WindowManager.DOCKED_RIGHT;
 import static android.view.WindowManager.DOCKED_TOP;
@@ -63,21 +70,14 @@
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
 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_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 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;
@@ -103,8 +103,11 @@
 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 static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
 import static android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION;
+import static android.view.WindowManagerGlobal.ADD_OKAY;
+import static android.view.WindowManagerGlobal.ADD_PERMISSION_DENIED;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVER_ABSENT;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_UNCOVERED;
@@ -156,7 +159,6 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.Debug;
 import android.os.FactoryTest;
 import android.os.Handler;
 import android.os.IBinder;
@@ -314,12 +316,6 @@
     // Nav bar is always translucent when the freeform stack is visible, otherwise always opaque.
     static final int NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE = 1;
 
-    static final int APPLICATION_MEDIA_SUBLAYER = -2;
-    static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
-    static final int APPLICATION_PANEL_SUBLAYER = 1;
-    static final int APPLICATION_SUB_PANEL_SUBLAYER = 2;
-    static final int APPLICATION_ABOVE_SUB_PANEL_SUBLAYER = 3;
-
     static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
     static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
     static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
@@ -2315,86 +2311,82 @@
 
         if (type < FIRST_SYSTEM_WINDOW || type > LAST_SYSTEM_WINDOW) {
             // Window manager will make sure these are okay.
-            return WindowManagerGlobal.ADD_OKAY;
+            return ADD_OKAY;
         }
-        String permission = null;
-        switch (type) {
-            case TYPE_TOAST:
-                // XXX right now the app process has complete control over
-                // this...  should introduce a token to let the system
-                // monitor/control what they are doing.
-                outAppOp[0] = AppOpsManager.OP_TOAST_WINDOW;
-                break;
-            case TYPE_DREAM:
-            case TYPE_INPUT_METHOD:
-            case TYPE_WALLPAPER:
-            case TYPE_PRESENTATION:
-            case TYPE_PRIVATE_PRESENTATION:
-            case TYPE_VOICE_INTERACTION:
-            case TYPE_ACCESSIBILITY_OVERLAY:
-            case TYPE_QS_DIALOG:
-                // The window manager will check these.
-                break;
-            case TYPE_PHONE:
-            case TYPE_PRIORITY_PHONE:
-            case TYPE_SYSTEM_ALERT:
-            case TYPE_SYSTEM_ERROR:
-            case TYPE_SYSTEM_OVERLAY:
-                permission = android.Manifest.permission.SYSTEM_ALERT_WINDOW;
-                outAppOp[0] = AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
-                break;
+
+        if (!isSystemAlertWindowType(type)) {
+            switch (type) {
+                case TYPE_TOAST:
+                    // Only apps that target older than O SDK can add window without a token, after
+                    // that we require a token so apps cannot add toasts directly as the token is
+                    // added by the notification system.
+                    // Window manager does the checking for this.
+                    outAppOp[0] = OP_TOAST_WINDOW;
+                    return ADD_OKAY;
+                case TYPE_DREAM:
+                case TYPE_INPUT_METHOD:
+                case TYPE_WALLPAPER:
+                case TYPE_PRESENTATION:
+                case TYPE_PRIVATE_PRESENTATION:
+                case TYPE_VOICE_INTERACTION:
+                case TYPE_ACCESSIBILITY_OVERLAY:
+                case TYPE_QS_DIALOG:
+                    // The window manager will check these.
+                    return ADD_OKAY;
+            }
+            return mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW)
+                    == PERMISSION_GRANTED ? ADD_OKAY : ADD_PERMISSION_DENIED;
+        }
+
+        // Things get a little more interesting for alert windows...
+        outAppOp[0] = OP_SYSTEM_ALERT_WINDOW;
+
+        final int callingUid = Binder.getCallingUid();
+        // system processes will be automatically granted privilege to draw
+        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
+            return ADD_OKAY;
+        }
+
+        ApplicationInfo appInfo;
+        try {
+            appInfo = mContext.getPackageManager().getApplicationInfo(attrs.packageName,
+                            UserHandle.getUserId(callingUid));
+        } catch (PackageManager.NameNotFoundException e) {
+            appInfo = null;
+        }
+
+        if (appInfo == null || (type != TYPE_APPLICATION_OVERLAY && appInfo.targetSdkVersion >= O)) {
+            /**
+             * Apps targeting >= {@link Build.VERSION_CODES#O} are required to hold
+             * {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW} (system signature apps)
+             * permission to add alert windows that aren't
+             * {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY}.
+             */
+            return (mContext.checkCallingPermission(INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED)
+                    ? ADD_OKAY : ADD_PERMISSION_DENIED;
+        }
+
+        // check if user has enabled this operation. SecurityException will be thrown if this app
+        // has not been allowed by the user
+        final int mode = mAppOpsManager.checkOpNoThrow(outAppOp[0], callingUid, attrs.packageName);
+        switch (mode) {
+            case AppOpsManager.MODE_ALLOWED:
+            case AppOpsManager.MODE_IGNORED:
+                // although we return ADD_OKAY for MODE_IGNORED, the added window will
+                // actually be hidden in WindowManagerService
+                return ADD_OKAY;
+            case AppOpsManager.MODE_ERRORED:
+                // Don't crash legacy apps
+                if (appInfo.targetSdkVersion < M) {
+                    return ADD_OKAY;
+                }
+                return ADD_PERMISSION_DENIED;
             default:
-                permission = android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
+                // in the default mode, we will make a decision here based on
+                // checkCallingPermission()
+                return (mContext.checkCallingPermission(SYSTEM_ALERT_WINDOW) == PERMISSION_GRANTED)
+                        ? ADD_OKAY : ADD_PERMISSION_DENIED;
         }
-        if (permission != null) {
-            if (android.Manifest.permission.SYSTEM_ALERT_WINDOW.equals(permission)) {
-                final int callingUid = Binder.getCallingUid();
-                // system processes will be automatically allowed privilege to draw
-                if (callingUid == Process.SYSTEM_UID) {
-                    return WindowManagerGlobal.ADD_OKAY;
-                }
-
-                // check if user has enabled this operation. SecurityException will be thrown if
-                // this app has not been allowed by the user
-                final int mode = mAppOpsManager.checkOpNoThrow(outAppOp[0], callingUid,
-                        attrs.packageName);
-                switch (mode) {
-                    case AppOpsManager.MODE_ALLOWED:
-                    case AppOpsManager.MODE_IGNORED:
-                        // although we return ADD_OKAY for MODE_IGNORED, the added window will
-                        // actually be hidden in WindowManagerService
-                        return WindowManagerGlobal.ADD_OKAY;
-                    case AppOpsManager.MODE_ERRORED:
-                        try {
-                            ApplicationInfo appInfo = mContext.getPackageManager()
-                                    .getApplicationInfo(attrs.packageName,
-                                            UserHandle.getUserId(callingUid));
-                            // Don't crash legacy apps
-                            if (appInfo.targetSdkVersion < Build.VERSION_CODES.M) {
-                                return WindowManagerGlobal.ADD_OKAY;
-                            }
-                        } catch (PackageManager.NameNotFoundException e) {
-                            /* ignore */
-                        }
-                        return WindowManagerGlobal.ADD_PERMISSION_DENIED;
-                    default:
-                        // in the default mode, we will make a decision here based on
-                        // checkCallingPermission()
-                        if (mContext.checkCallingPermission(permission) !=
-                                PackageManager.PERMISSION_GRANTED) {
-                            return WindowManagerGlobal.ADD_PERMISSION_DENIED;
-                        } else {
-                            return WindowManagerGlobal.ADD_OKAY;
-                        }
-                }
-            }
-
-            if (mContext.checkCallingOrSelfPermission(permission)
-                    != PackageManager.PERMISSION_GRANTED) {
-                return WindowManagerGlobal.ADD_PERMISSION_DENIED;
-            }
-        }
-        return WindowManagerGlobal.ADD_OKAY;
     }
 
     @Override
@@ -2440,9 +2432,7 @@
         }
 
         // Check if third party app has set window to system window type.
-        return mContext.checkCallingOrSelfPermission(
-                android.Manifest.permission.INTERNAL_SYSTEM_WINDOW)
-                        != PackageManager.PERMISSION_GRANTED;
+        return mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED;
     }
 
     @Override
@@ -2591,130 +2581,9 @@
         }
     }
 
-    /** {@inheritDoc} */
-    @Override
-    public int windowTypeToLayerLw(int type) {
-        if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
-            return 2;
-        }
-        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 2;
-        case TYPE_DOCK_DIVIDER:
-            return 2;
-        case TYPE_QS_DIALOG:
-            return 2;
-        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_DREAM:
-            // used for Dreams (screensavers with TYPE_DREAM windows)
-            return 10;
-        case TYPE_SYSTEM_ALERT:
-            // like the ANR / app crashed dialogs
-            return 11;
-        case TYPE_INPUT_METHOD:
-            // on-screen keyboards and other such input method user interfaces go here.
-            return 12;
-        case TYPE_INPUT_METHOD_DIALOG:
-            // on-screen keyboards and other such input method user interfaces go here.
-            return 13;
-        case TYPE_STATUS_BAR_SUB_PANEL:
-            return 15;
-        case TYPE_STATUS_BAR:
-            return 16;
-        case TYPE_STATUS_BAR_PANEL:
-            return 17;
-        case TYPE_KEYGUARD_DIALOG:
-            return 18;
-        case TYPE_VOLUME_OVERLAY:
-            // the on-screen volume indicator and controller shown when the user
-            // changes the device volume
-            return 19;
-        case TYPE_SYSTEM_OVERLAY:
-            // the on-screen volume indicator and controller shown when the user
-            // changes the device volume
-            return 20;
-        case TYPE_NAVIGATION_BAR:
-            // the navigation bar, if available, shows atop most things
-            return 21;
-        case TYPE_NAVIGATION_BAR_PANEL:
-            // some panels (e.g. search) need to show on top of the navigation bar
-            return 22;
-        case TYPE_SCREENSHOT:
-            // screenshot selection layer shouldn't go above system error, but it should cover
-            // navigation bars at the very least.
-            return 23;
-        case TYPE_SYSTEM_ERROR:
-            // system-level error dialogs
-            return 24;
-        case TYPE_MAGNIFICATION_OVERLAY:
-            // used to highlight the magnified portion of a display
-            return 25;
-        case TYPE_DISPLAY_OVERLAY:
-            // used to simulate secondary display devices
-            return 26;
-        case TYPE_DRAG:
-            // the drag layer: input for drag-and-drop is associated with this window,
-            // which sits above all other focusable windows
-            return 27;
-        case TYPE_ACCESSIBILITY_OVERLAY:
-            // overlay put by accessibility services to intercept user interaction
-            return 28;
-        case TYPE_SECURE_SYSTEM_OVERLAY:
-            return 29;
-        case TYPE_BOOT_PROGRESS:
-            return 30;
-        case TYPE_POINTER:
-            // the (mouse) pointer layer
-            return 31;
-        }
-        Log.e(TAG, "Unknown window type: " + type);
-        return 2;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int subWindowTypeToLayerLw(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;
-        }
-        Log.e(TAG, "Unknown sub-window type: " + type);
-        return 0;
-    }
-
     @Override
     public int getMaxWallpaperLayer() {
-        return windowTypeToLayerLw(TYPE_STATUS_BAR);
+        return getWindowLayerFromTypeLw(TYPE_STATUS_BAR);
     }
 
     private int getNavigationBarWidth(int rotation, int uiMode) {
@@ -2797,8 +2666,7 @@
                 return false;
             default:
                 // Hide only windows below the keyguard host window.
-                return windowTypeToLayerLw(win.getBaseType())
-                        < windowTypeToLayerLw(TYPE_STATUS_BAR);
+                return getWindowLayerLw(win) < getWindowLayerFromTypeLw(TYPE_STATUS_BAR);
         }
     }
 
@@ -3043,7 +2911,7 @@
                         "PhoneWindowManager");
                 break;
         }
-        return WindowManagerGlobal.ADD_OKAY;
+        return ADD_OKAY;
     }
 
     /** {@inheritDoc} */
@@ -7837,8 +7705,8 @@
         immersiveSticky = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0;
         final boolean navAllowedHidden = immersive || immersiveSticky;
 
-        if (hideNavBarSysui && !navAllowedHidden && windowTypeToLayerLw(win.getBaseType())
-                > windowTypeToLayerLw(TYPE_INPUT_CONSUMER)) {
+        if (hideNavBarSysui && !navAllowedHidden
+                && getWindowLayerLw(win) > getWindowLayerFromTypeLw(TYPE_INPUT_CONSUMER)) {
             // We can't hide the navbar from this window otherwise the input consumer would not get
             // the input events.
             vis = (vis & ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 49ffa22..f7a9e41 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -369,6 +369,7 @@
                         case WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
                         case WindowManager.LayoutParams.TYPE_TOAST:
                         case WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY:
+                        case WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY:
                         case WindowManager.LayoutParams.TYPE_PRIORITY_PHONE:
                         case WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG:
                         case WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG:
@@ -687,7 +688,7 @@
                     mSurfaceControl = surfaceControl;
                     mSurfaceControl.setLayerStack(mWindowManager.getDefaultDisplay()
                             .getLayerStack());
-                    mSurfaceControl.setLayer(mWindowManagerService.mPolicy.windowTypeToLayerLw(
+                    mSurfaceControl.setLayer(mWindowManagerService.mPolicy.getWindowLayerFromTypeLw(
                             WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY)
                             * WindowManagerService.TYPE_LAYER_MULTIPLIER);
                     mSurfaceControl.setPosition(0, 0);
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index d643769..061aa83 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -192,7 +192,8 @@
 
     AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction,
             DisplayContent dc) {
-        super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc);
+        super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc,
+                false /* ownerCanManageAppTokens */);
         appToken = token;
         mVoiceInteraction = voiceInteraction;
         mInputApplicationHandle = new InputApplicationHandle(this);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 679f178..c45136c 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2185,7 +2185,7 @@
                     && !mService.mInputMethodTarget.isInMultiWindowMode();
         }
 
-        final int aboveAppLayer = (mService.mPolicy.windowTypeToLayerLw(TYPE_APPLICATION) + 1)
+        final int aboveAppLayer = (mService.mPolicy.getWindowLayerFromTypeLw(TYPE_APPLICATION) + 1)
                 * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
         final MutableBoolean mutableIncludeFullDisplay = new MutableBoolean(includeFullDisplay);
         synchronized(mService.mWindowMap) {
@@ -2728,8 +2728,10 @@
          */
         private final Comparator<WindowToken> mWindowComparator = (token1, token2) ->
                 // Tokens with higher base layer are z-ordered on-top.
-                mService.mPolicy.windowTypeToLayerLw(token1.windowType)
-                < mService.mPolicy.windowTypeToLayerLw(token2.windowType) ? -1 : 1;
+                mService.mPolicy.getWindowLayerFromTypeLw(token1.windowType,
+                        token1.mOwnerCanManageAppTokens)
+                < mService.mPolicy.getWindowLayerFromTypeLw(token2.windowType,
+                        token2.mOwnerCanManageAppTokens) ? -1 : 1;
 
         private final Predicate<WindowState> mGetOrientingWindow = w -> {
             if (!w.isVisibleLw() || !w.mPolicyVisibilityAfterAnim) {
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 1ae987f..3fdafc7 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -239,7 +239,7 @@
     }
 
     int getDragLayerLw() {
-        return mService.mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_DRAG)
+        return mService.mPolicy.getWindowLayerFromTypeLw(WindowManager.LayoutParams.TYPE_DRAG)
                 * WindowManagerService.TYPE_LAYER_MULTIPLIER
                 + WindowManagerService.TYPE_LAYER_OFFSET;
     }
diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java
index b92bfb9..36753b7 100644
--- a/services/core/java/com/android/server/wm/InputConsumerImpl.java
+++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java
@@ -77,7 +77,7 @@
     }
 
     private int getLayerLw(int windowType) {
-        return mService.mPolicy.windowTypeToLayerLw(windowType)
+        return mService.mPolicy.getWindowLayerFromTypeLw(windowType)
                 * WindowManagerService.TYPE_LAYER_MULTIPLIER
                 + WindowManagerService.TYPE_LAYER_OFFSET;
     }
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 5f53d84..37b8deb 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -24,6 +24,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
@@ -237,8 +238,8 @@
                 // Figure out whether this window is layered above system windows.
                 // We need to do this here to help the activity manager know how to
                 // layer its ANR dialog.
-                int systemAlertLayer = mService.mPolicy.windowTypeToLayerLw(
-                        WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+                int systemAlertLayer = mService.mPolicy.getWindowLayerFromTypeLw(
+                        TYPE_APPLICATION_OVERLAY, windowState.mOwnerCanAddInternalSystemWindow);
                 aboveSystem = windowState.mBaseLayer > systemAlertLayer;
             } else if (appWindowToken != null) {
                 Slog.i(TAG_WM, "Input event dispatching timed out "
@@ -471,7 +472,7 @@
     /* Callback to get pointer layer. */
     @Override
     public int getPointerLayer() {
-        return mService.mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_POINTER)
+        return mService.mPolicy.getWindowLayerFromTypeLw(WindowManager.LayoutParams.TYPE_POINTER)
                 * WindowManagerService.TYPE_LAYER_MULTIPLIER
                 + WindowManagerService.TYPE_LAYER_OFFSET;
     }
diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
index 8ea1b3b..28aebbb 100644
--- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java
+++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
@@ -40,8 +40,8 @@
     private static final String TAG = TAG_WITH_CLASS_NAME ? "WallpaperWindowToken" : TAG_WM;
 
     WallpaperWindowToken(WindowManagerService service, IBinder token, boolean explicit,
-            DisplayContent dc) {
-        super(service, token, TYPE_WALLPAPER, explicit, dc);
+            DisplayContent dc, boolean ownerCanManageAppTokens) {
+        super(service, token, TYPE_WALLPAPER, explicit, dc, ownerCanManageAppTokens);
         dc.mWallpaperController.addWallpaperToken(this);
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 9b96523..971794b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -16,13 +16,14 @@
 
 package com.android.server.wm;
 
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
 import static android.Manifest.permission.MANAGE_APP_TOKENS;
 import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS;
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.app.StatusBarManager.DISABLE_MASK;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.DOCKED_INVALID;
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
@@ -101,7 +102,6 @@
 import android.app.ActivityManagerInternal;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
-import android.app.RemoteAction;
 import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -236,7 +236,6 @@
 import java.util.HashMap;
 import java.util.List;
 
-import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
 import static android.Manifest.permission.READ_FRAME_BUFFER;
 /** {@hide} */
 public class WindowManagerService extends IWindowManager.Stub
@@ -523,7 +522,7 @@
     boolean mSupportsPictureInPicture = false;
 
     int getDragLayerLocked() {
-        return mPolicy.windowTypeToLayerLw(TYPE_DRAG) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
+        return mPolicy.getWindowLayerFromTypeLw(TYPE_DRAG) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
     }
 
     class RotationWatcher {
@@ -1099,6 +1098,8 @@
         long origId;
         final int callingUid = Binder.getCallingUid();
         final int type = attrs.type;
+        final boolean ownerCanAddInternalSystemWindow =
+                mContext.checkCallingPermission(INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED;
 
         synchronized(mWindowMap) {
             if (!mDisplayReady) {
@@ -1200,7 +1201,8 @@
                         return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                     }
                 }
-                token = new WindowToken(this, attrs.token, type, false, displayContent);
+                token = new WindowToken(this, attrs.token, type, false, displayContent,
+                        ownerCanAddInternalSystemWindow);
             } else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
                 atoken = token.asAppWindowToken();
                 if (atoken == null) {
@@ -1270,11 +1272,13 @@
                 // It is not valid to use an app token with other system types; we will
                 // instead make a new token for it (as if null had been passed in for the token).
                 attrs.token = null;
-                token = new WindowToken(this, null, type, false, displayContent);
+                token = new WindowToken(this, null, type, false, displayContent,
+                        ownerCanAddInternalSystemWindow);
             }
 
-            WindowState win = new WindowState(this, session, client, token, parentWindow,
-                    appOp[0], seq, attrs, viewVisibility, session.mUid);
+            final WindowState win = new WindowState(this, session, client, token, parentWindow,
+                    appOp[0], seq, attrs, viewVisibility, session.mUid,
+                    ownerCanAddInternalSystemWindow);
             if (win.mDeathRecipient == null) {
                 // Client has apparently died, so there is no reason to
                 // continue.
@@ -2405,9 +2409,10 @@
                 return;
             }
             if (type == TYPE_WALLPAPER) {
-                new WallpaperWindowToken(this, binder, true, dc);
+                new WallpaperWindowToken(this, binder, true, dc,
+                        true /* ownerCanManageAppTokens */);
             } else {
-                new WindowToken(this, binder, type, true, dc);
+                new WindowToken(this, binder, type, true, dc, true /* ownerCanManageAppTokens */);
             }
         }
     }
@@ -3606,7 +3611,7 @@
                         mCircularDisplayMask = new CircularDisplayMask(
                                 getDefaultDisplayContentLocked().getDisplay(),
                                 mFxSession,
-                                mPolicy.windowTypeToLayerLw(
+                                mPolicy.getWindowLayerFromTypeLw(
                                         WindowManager.LayoutParams.TYPE_POINTER)
                                         * TYPE_LAYER_MULTIPLIER + 10, screenOffset, maskThickness);
                     }
@@ -3635,7 +3640,7 @@
                             mContext,
                             getDefaultDisplayContentLocked().getDisplay(),
                             mFxSession,
-                            mPolicy.windowTypeToLayerLw(
+                            mPolicy.getWindowLayerFromTypeLw(
                                     WindowManager.LayoutParams.TYPE_POINTER)
                                     * TYPE_LAYER_MULTIPLIER + 10);
                 }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 050adfe..867080e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -18,7 +18,6 @@
 
 import static android.app.ActivityManager.ENABLE_TASK_SNAPSHOTS;
 import static android.app.ActivityManager.StackId;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.ActivityManager.isLowRamDeviceStatic;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
@@ -164,6 +163,8 @@
     final int mAppOp;
     // UserId and appId of the owner. Don't display windows of non-current user.
     final int mOwnerUid;
+    /** The owner has {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW} */
+    final boolean mOwnerCanAddInternalSystemWindow;
     final IWindowId mWindowId;
     WindowToken mToken;
     // The same object as mToken if this is an app window and null for non-app windows.
@@ -561,7 +562,7 @@
 
     WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
            WindowState parentWindow, int appOp, int seq, WindowManager.LayoutParams a,
-           int viewVisibility, int ownerId) {
+           int viewVisibility, int ownerId, boolean ownerCanAddInternalSystemWindow) {
         mService = service;
         mSession = s;
         mClient = c;
@@ -569,6 +570,7 @@
         mToken = token;
         mAppToken = mToken.asAppWindowToken();
         mOwnerUid = ownerId;
+        mOwnerCanAddInternalSystemWindow = ownerCanAddInternalSystemWindow;
         mWindowId = new IWindowId.Stub() {
             @Override
             public void registerFocusObserver(IWindowFocusObserver observer) {
@@ -613,9 +615,9 @@
         if (mAttrs.type >= FIRST_SUB_WINDOW && mAttrs.type <= LAST_SUB_WINDOW) {
             // The multiplier here is to reserve space for multiple
             // windows in the same type layer.
-            mBaseLayer = mPolicy.windowTypeToLayerLw(parentWindow.mAttrs.type)
+            mBaseLayer = mPolicy.getWindowLayerLw(parentWindow)
                     * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
-            mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
+            mSubLayer = mPolicy.getSubWindowLayerFromTypeLw(a.type);
             mIsChildWindow = true;
 
             if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + parentWindow);
@@ -629,7 +631,7 @@
         } else {
             // The multiplier here is to reserve space for multiple
             // windows in the same type layer.
-            mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
+            mBaseLayer = mPolicy.getWindowLayerLw(this)
                     * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
             mSubLayer = 0;
             mIsChildWindow = false;
@@ -676,6 +678,11 @@
         return mAttrs.packageName;
     }
 
+    @Override
+    public boolean canAddInternalSystemWindow() {
+        return mOwnerCanAddInternalSystemWindow;
+    }
+
     /**
      * Subtracts the insets calculated by intersecting {@param layoutFrame} with {@param insetFrame}
      * from {@param frame}. In other words, it applies the insets that would result if
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 4b94d15..8beb87d 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -77,6 +77,9 @@
     // The display this token is on.
     protected DisplayContent mDisplayContent;
 
+    /** The owner has {@link android.Manifest.permission#MANAGE_APP_TOKENS} */
+    final boolean mOwnerCanManageAppTokens;
+
     /**
      * Compares two child window of this token and returns -1 if the first is lesser than the
      * second in terms of z-order and 1 otherwise.
@@ -98,11 +101,12 @@
     };
 
     WindowToken(WindowManagerService service, IBinder _token, int type, boolean persistOnEmpty,
-            DisplayContent dc) {
+            DisplayContent dc, boolean ownerCanManageAppTokens) {
         mService = service;
         token = _token;
         windowType = type;
         mPersistOnEmpty = persistOnEmpty;
+        mOwnerCanManageAppTokens = ownerCanManageAppTokens;
         onDisplayChanged(dc);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index ec429a0..1e471e3 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -16,49 +16,7 @@
 
 package com.android.server.wm;
 
-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_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-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 org.mockito.Mockito.mock;
 
 import android.annotation.Nullable;
@@ -70,12 +28,10 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.util.Log;
 import android.view.Display;
 import android.view.IWindowManager;
 import android.view.KeyEvent;
 import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
 import android.view.WindowManagerPolicy;
 import android.view.animation.Animation;
 import android.os.PowerManagerInternal;
@@ -163,127 +119,6 @@
     }
 
     @Override
-    public int windowTypeToLayerLw(int type) {
-        // TODO: figure-out a good way to keep this in-sync with PhoneWindowManager...sigh!
-        if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
-            return 2;
-        }
-        switch (type) {
-            case TYPE_PRESENTATION:
-            case TYPE_PRIVATE_PRESENTATION:
-                return 2;
-            case TYPE_WALLPAPER:
-                // wallpaper is at the bottom, though the window manager may move it.
-                return 2;
-            case TYPE_DOCK_DIVIDER:
-                return 2;
-            case TYPE_QS_DIALOG:
-                return 2;
-            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_DREAM:
-                // used for Dreams (screensavers with TYPE_DREAM windows)
-                return 10;
-            case TYPE_SYSTEM_ALERT:
-                // like the ANR / app crashed dialogs
-                return 11;
-            case TYPE_INPUT_METHOD:
-                // on-screen keyboards and other such input method user interfaces go here.
-                return 12;
-            case TYPE_INPUT_METHOD_DIALOG:
-                // on-screen keyboards and other such input method user interfaces go here.
-                return 13;
-            case TYPE_STATUS_BAR_SUB_PANEL:
-                return 15;
-            case TYPE_STATUS_BAR:
-                return 16;
-            case TYPE_STATUS_BAR_PANEL:
-                return 17;
-            case TYPE_KEYGUARD_DIALOG:
-                return 18;
-            case TYPE_VOLUME_OVERLAY:
-                // the on-screen volume indicator and controller shown when the user
-                // changes the device volume
-                return 19;
-            case TYPE_SYSTEM_OVERLAY:
-                // the on-screen volume indicator and controller shown when the user
-                // changes the device volume
-                return 20;
-            case TYPE_NAVIGATION_BAR:
-                // the navigation bar, if available, shows atop most things
-                return 21;
-            case TYPE_NAVIGATION_BAR_PANEL:
-                // some panels (e.g. search) need to show on top of the navigation bar
-                return 22;
-            case TYPE_SCREENSHOT:
-                // screenshot selection layer shouldn't go above system error, but it should cover
-                // navigation bars at the very least.
-                return 23;
-            case TYPE_SYSTEM_ERROR:
-                // system-level error dialogs
-                return 24;
-            case TYPE_MAGNIFICATION_OVERLAY:
-                // used to highlight the magnified portion of a display
-                return 25;
-            case TYPE_DISPLAY_OVERLAY:
-                // used to simulate secondary display devices
-                return 26;
-            case TYPE_DRAG:
-                // the drag layer: input for drag-and-drop is associated with this window,
-                // which sits above all other focusable windows
-                return 27;
-            case TYPE_ACCESSIBILITY_OVERLAY:
-                // overlay put by accessibility services to intercept user interaction
-                return 28;
-            case TYPE_SECURE_SYSTEM_OVERLAY:
-                return 29;
-            case TYPE_BOOT_PROGRESS:
-                return 30;
-            case TYPE_POINTER:
-                // the (mouse) pointer layer
-                return 31;
-        }
-        Log.e(TAG, "Unknown window type: " + type);
-        return 2;
-    }
-
-    @Override
-    public int subWindowTypeToLayerLw(int type) {
-        // TODO: figure-out a good way to keep this in-sync with PhoneWindowManager...
-        switch (type) {
-            case TYPE_APPLICATION_PANEL:
-            case TYPE_APPLICATION_ATTACHED_DIALOG:
-                return 1;
-            case TYPE_APPLICATION_MEDIA:
-                return -2;
-            case TYPE_APPLICATION_MEDIA_OVERLAY:
-                return -1;
-            case TYPE_APPLICATION_SUB_PANEL:
-                return 2;
-            case TYPE_APPLICATION_ABOVE_SUB_PANEL:
-                return 3;
-        }
-        Log.e(TAG, "Unknown sub-window type: " + type);
-        return 0;
-    }
-
-    @Override
     public int getMaxWallpaperLayer() {
         return 0;
     }
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
index 186884b..4cad4e8 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -57,7 +57,8 @@
         final Task mTask;
         boolean mDockedResizingForTest = false;
         WindowStateWithTask(WindowManager.LayoutParams attrs, Task t) {
-            super(sWm, null, mIWindow, mWindowToken, null, 0, 0, attrs, 0, 0);
+            super(sWm, null, mIWindow, mWindowToken, null, 0, 0, attrs, 0, 0,
+                    false /* ownerCanAddInternalSystemWindow */);
             mTask = t;
         }
 
@@ -106,7 +107,7 @@
         sWm.mSystemDecorLayer = 10000;
 
         mWindowToken = new WindowToken(sWm, new Binder(), 0, false,
-                sWm.getDefaultDisplayContentLocked());
+                sWm.getDefaultDisplayContentLocked(), false /* ownerCanManageAppTokens */);
         mStubStack = new TaskStack(sWm, 0);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
index c6f88ed..7dec52d 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -181,7 +181,7 @@
         attrs.setTitle(name);
 
         final WindowState w = new WindowState(sWm, sMockSession, sIWindow, token, parent, OP_NONE,
-                0, attrs, 0, 0);
+                0, attrs, 0, 0, false /* ownerCanAddInternalSystemWindow */);
         // TODO: Probably better to make this call in the WindowState ctor to avoid errors with
         // adding it to the token...
         token.addWindow(w);
@@ -223,7 +223,8 @@
         }
 
         TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) {
-            super(sWm, mock(IBinder.class), type, persistOnEmpty, dc);
+            super(sWm, mock(IBinder.class), type, persistOnEmpty, dc,
+                    false /* ownerCanManageAppTokens */);
         }
 
         int getWindowsCount() {
@@ -403,7 +404,8 @@
         boolean resizeReported;
 
         TestWindowState(WindowManager.LayoutParams attrs, WindowToken token) {
-            super(sWm, sMockSession, sIWindow, token, null, OP_NONE, 0, attrs, 0, 0);
+            super(sWm, sMockSession, sIWindow, token, null, OP_NONE, 0, attrs, 0, 0,
+                    false /* ownerCanAddInternalSystemWindow */);
         }
 
         @Override