Add support for secure system overlays.

Manual merge from Gingerbread.

This change adds a new window type for secure system overlays
created by the system itself from non-secure system overlays that
might be created by applications that have the system alert permission.
Secure views ignore the presence of secure system overlays.

Bug: 3098519
Change-Id: Id876736fd8bf332ff9a5428bde59f5268aa49c3a
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 7cb4671..0b2d0f6 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -167,7 +167,8 @@
             @ViewDebug.IntToString(from = TYPE_KEYGUARD_DIALOG, to = "TYPE_KEYGUARD_DIALOG"),
             @ViewDebug.IntToString(from = TYPE_SYSTEM_ERROR, to = "TYPE_SYSTEM_ERROR"),
             @ViewDebug.IntToString(from = TYPE_INPUT_METHOD, to = "TYPE_INPUT_METHOD"),
-            @ViewDebug.IntToString(from = TYPE_INPUT_METHOD_DIALOG, to = "TYPE_INPUT_METHOD_DIALOG")
+            @ViewDebug.IntToString(from = TYPE_INPUT_METHOD_DIALOG, to = "TYPE_INPUT_METHOD_DIALOG"),
+            @ViewDebug.IntToString(from = TYPE_SECURE_SYSTEM_OVERLAY, to = "TYPE_SECURE_SYSTEM_OVERLAY")
         })
         public int type;
     
@@ -345,13 +346,25 @@
          * Window type: panel that slides out from the status bar
          */
         public static final int TYPE_STATUS_BAR_PANEL   = FIRST_SYSTEM_WINDOW+14;
-        
+
+        /**
+         * Window type: secure system overlay windows, which need to be displayed
+         * on top of everything else.  These windows must not take input
+         * focus, or they will interfere with the keyguard.
+         *
+         * This is exactly like {@link #TYPE_SYSTEM_OVERLAY} except that only the
+         * system itself is allowed to create these overlays.  Applications cannot
+         * obtain permission to create secure system overlays.
+         * @hide
+         */
+        public static final int TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+15;
+
         /**
          * Window type: the drag-and-drop pseudowindow.  There is only one
          * drag layer (at most), and it is placed on top of all other windows.
          * @hide
          */
-        public static final int TYPE_DRAG               = FIRST_SYSTEM_WINDOW+15;
+        public static final int TYPE_DRAG               = FIRST_SYSTEM_WINDOW+16;
 
         /**
          * End of types of system windows.
diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h
index 63185d3..b811ace 100644
--- a/include/ui/InputDispatcher.h
+++ b/include/ui/InputDispatcher.h
@@ -183,6 +183,7 @@
         TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW+12,
         TYPE_WALLPAPER          = FIRST_SYSTEM_WINDOW+13,
         TYPE_STATUS_BAR_PANEL   = FIRST_SYSTEM_WINDOW+14,
+        TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+15,
         LAST_SYSTEM_WINDOW      = 2999,
     };
 
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index 84c3db8..949dc4d 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -149,7 +149,8 @@
 
 bool InputWindow::isTrustedOverlay() const {
     return layoutParamsType == TYPE_INPUT_METHOD
-            || layoutParamsType == TYPE_INPUT_METHOD_DIALOG;
+            || layoutParamsType == TYPE_INPUT_METHOD_DIALOG
+            || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
 }
 
 
@@ -1350,7 +1351,7 @@
         target.flags = 0;
         target.xOffset = 0;
         target.yOffset = 0;
-        target.windowType = InputWindow::TYPE_SYSTEM_OVERLAY;
+        target.windowType = -1;
     }
 }
 
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index c6898d4..2cd615d 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -96,6 +96,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_PHONE;
 import static android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
 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_SYSTEM_DIALOG;
@@ -163,6 +164,7 @@
     static final int DRAG_LAYER = 16;
     // things in here CAN NOT take focus, but are shown on top of everything else.
     static final int SYSTEM_OVERLAY_LAYER = 17;
+    static final int SECURE_SYSTEM_OVERLAY_LAYER = 18;
 
     static final int APPLICATION_MEDIA_SUBLAYER = -2;
     static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
@@ -691,7 +693,7 @@
             WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                     WindowManager.LayoutParams.MATCH_PARENT,
                     WindowManager.LayoutParams.MATCH_PARENT);
-            lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
+            lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
             lp.flags = 
                 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
@@ -787,6 +789,7 @@
     public void adjustWindowParamsLw(WindowManager.LayoutParams attrs) {
         switch (attrs.type) {
             case TYPE_SYSTEM_OVERLAY:
+            case TYPE_SECURE_SYSTEM_OVERLAY:
             case TYPE_TOAST:
                 // These types of windows can't receive input events.
                 attrs.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
@@ -864,6 +867,8 @@
             return INPUT_METHOD_DIALOG_LAYER;
         case TYPE_SYSTEM_OVERLAY:
             return SYSTEM_OVERLAY_LAYER;
+        case TYPE_SECURE_SYSTEM_OVERLAY:
+            return SECURE_SYSTEM_OVERLAY_LAYER;
         case TYPE_PRIORITY_PHONE:
             return PRIORITY_PHONE_LAYER;
         case TYPE_TOAST:
diff --git a/services/java/com/android/server/LoadAverageService.java b/services/java/com/android/server/LoadAverageService.java
index 0d86429..b6baadb 100644
--- a/services/java/com/android/server/LoadAverageService.java
+++ b/services/java/com/android/server/LoadAverageService.java
@@ -272,7 +272,7 @@
         WindowManager.LayoutParams params = new WindowManager.LayoutParams(
             WindowManager.LayoutParams.WRAP_CONTENT,
             WindowManager.LayoutParams.WRAP_CONTENT,
-            WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
+            WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY,
             WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
             WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
             PixelFormat.TRANSLUCENT);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 83351bc..c8c88c5 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -5965,7 +5965,7 @@
                 View v = LayoutInflater.from(mContext).inflate(
                         com.android.internal.R.layout.safe_mode, null);
                 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
-                lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
+                lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
                 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
                 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
                 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;