Make Keyguard a library and make StatusBar the new Keyguard.

This change achieves a couple of things:
- Let Keyguard be a library, so we can use it in SystemUI.
- Introduce FLAG_KEYGUARD for windows and deprecate TYPE_KEYGUARD. Make
all the TYPE_KEYGUARD behaviour dependant on the flag.
- Implement a new KeyguardService in SystemUI, and bind that service
from PhoneWindowManager.
- Introduce BaseStatusBar.setKeyguardState and inflate
KeyguardSimpleHostView there and use FLAG_KEYGUARD for the window, such
that the status bar window essentially gets the Keyguard.

Bug: 13635952
Change-Id: I059d80d8b9b9818a778ab685f4672ea2694def63
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 53a4c0d0..0856492 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -49,7 +49,7 @@
 public interface WindowManager extends ViewManager {
     /**
      * Exception that is thrown when trying to add view whose
-     * {@link WindowManager.LayoutParams} {@link WindowManager.LayoutParams#token}
+     * {@link LayoutParams} {@link LayoutParams#token}
      * is invalid.
      */
     public static class BadTokenException extends RuntimeException {
@@ -173,7 +173,6 @@
          * @see #TYPE_SEARCH_BAR
          * @see #TYPE_PHONE
          * @see #TYPE_SYSTEM_ALERT
-         * @see #TYPE_KEYGUARD
          * @see #TYPE_TOAST
          * @see #TYPE_SYSTEM_OVERLAY
          * @see #TYPE_PRIORITY_PHONE
@@ -197,7 +196,6 @@
             @ViewDebug.IntToString(from = TYPE_SEARCH_BAR, to = "TYPE_SEARCH_BAR"),
             @ViewDebug.IntToString(from = TYPE_PHONE, to = "TYPE_PHONE"),
             @ViewDebug.IntToString(from = TYPE_SYSTEM_ALERT, to = "TYPE_SYSTEM_ALERT"),
-            @ViewDebug.IntToString(from = TYPE_KEYGUARD, to = "TYPE_KEYGUARD"),
             @ViewDebug.IntToString(from = TYPE_TOAST, to = "TYPE_TOAST"),
             @ViewDebug.IntToString(from = TYPE_SYSTEM_OVERLAY, to = "TYPE_SYSTEM_OVERLAY"),
             @ViewDebug.IntToString(from = TYPE_PRIORITY_PHONE, to = "TYPE_PRIORITY_PHONE"),
@@ -341,13 +339,13 @@
          * In multiuser systems shows only on the owning user's window.
          */
         public static final int TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3;
-        
+
         /**
          * Window type: keyguard window.
          * In multiuser systems shows on all users' windows.
          */
         public static final int TYPE_KEYGUARD           = FIRST_SYSTEM_WINDOW+4;
-        
+
         /**
          * Window type: transient notifications.
          * In multiuser systems shows only on the owning user's window.
@@ -913,7 +911,6 @@
          */
         public static final int FLAG_NEEDS_MENU_KEY = 0x40000000;
 
-
         /**
          * Various behavioral options/flags.  Default is none.
          * 
@@ -1087,6 +1084,14 @@
         public static final int PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR = 0x00000200;
 
         /**
+         * Flag whether the current window is a keyguard window, meaning that it will hide all other
+         * windows behind it except for windows with flag {@link #FLAG_SHOW_WHEN_LOCKED} set.
+         * Further, this can only be set by {@link LayoutParams#TYPE_STATUS_BAR}.
+         * {@hide}
+         */
+        public static final int PRIVATE_FLAG_KEYGUARD = 0x00000400;
+
+        /**
          * Control flags that are private to the platform.
          * @hide
          */
diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
index 63ff5a0..7fc024d 100644
--- a/core/java/com/android/internal/policy/IKeyguardService.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -30,7 +30,19 @@
     boolean isDismissable();
     oneway void verifyUnlock(IKeyguardExitCallback callback);
     oneway void keyguardDone(boolean authenticated, boolean wakeup);
-    oneway void setHidden(boolean isHidden);
+
+    /**
+     * Hides the Keyguard when a window comes on top of the Keyguard with flag
+     * FLAG_SHOW_ON_LOCK_SCREEN.
+     *
+     * @param isHidden Whether the Keyguard should be hidden.
+     * @return See IKeyguardServiceConstants.KEYGUARD_SERVICE_HIDE_*. This is needed because
+     *         PhoneWindowManager needs to set these flags immediately and can't wait for the
+     *         Keyguard thread to pick it up. In the hidden case, PhoneWindowManager is solely
+     *         responsible to make sure that the flags are unset.
+     */
+    int setHidden(boolean isHidden);
+
     oneway void dismiss();
     oneway void onDreamingStarted();
     oneway void onDreamingStopped();
diff --git a/core/java/com/android/internal/policy/IKeyguardServiceConstants.java b/core/java/com/android/internal/policy/IKeyguardServiceConstants.java
new file mode 100644
index 0000000..d94cca7
--- /dev/null
+++ b/core/java/com/android/internal/policy/IKeyguardServiceConstants.java
@@ -0,0 +1,41 @@
+/*
+ * 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 com.android.internal.policy;
+
+/**
+ * @hide
+ */
+public class IKeyguardServiceConstants {
+
+    /**
+     * Constant for {@link com.android.internal.policy.IKeyguardService#setHidden(boolean)}:
+     * Don't change the keyguard window flags.
+     */
+    public static final int KEYGUARD_SERVICE_HIDE_RESULT_NONE = 0;
+
+    /**
+     * Constant for {@link com.android.internal.policy.IKeyguardService#setHidden(boolean)}:
+     * Set the keyguard window flags to FLAG_SHOW_WALLPAPER and PRIVATE_FLAG_KEYGUARD.
+     */
+    public static final int KEYGUARD_SERVICE_HIDE_RESULT_SET_FLAGS = 1;
+
+    /**
+     * Constant for {@link com.android.internal.policy.IKeyguardService#setHidden(boolean)}:
+     * Unset the keyguard window flags to FLAG_SHOW_WALLPAPER and PRIVATE_FLAG_KEYGUARD.
+     */
+    public static final int KEYGUARD_SERVICE_HIDE_RESULT_UNSET_FLAGS = 2;
+}
diff --git a/packages/Keyguard/Android.mk b/packages/Keyguard/Android.mk
index 5b08674..1be44f9 100644
--- a/packages/Keyguard/Android.mk
+++ b/packages/Keyguard/Android.mk
@@ -19,7 +19,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-subdir-Iaidl-files) \
                    $(call all-proto-files-under,src)
 
-LOCAL_PACKAGE_NAME := Keyguard
+LOCAL_MODULE := Keyguard
 
 LOCAL_CERTIFICATE := platform
 
@@ -30,6 +30,8 @@
 LOCAL_PROTOC_OPTIMIZE_TYPE := nano
 LOCAL_PROTO_JAVA_OUTPUT_PARAMS := optional_field_style=accessors
 
-include $(BUILD_PACKAGE)
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
-#include $(call all-makefiles-under,$(LOCAL_PATH))
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+#include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/packages/Keyguard/AndroidManifest.xml b/packages/Keyguard/AndroidManifest.xml
index 66d1e75..b19f08a 100644
--- a/packages/Keyguard/AndroidManifest.xml
+++ b/packages/Keyguard/AndroidManifest.xml
@@ -45,8 +45,5 @@
         android:persistent="true"
         android:supportsRtl="true">
 
-        <service android:name=".KeyguardService"
-            android:exported="true" />
-
     </application>
 </manifest>
diff --git a/packages/Keyguard/res/layout-land/keyguard_host_view.xml b/packages/Keyguard/res/layout-land/keyguard_host_view.xml
index 9f1c1f0..1d596d3 100644
--- a/packages/Keyguard/res/layout-land/keyguard_host_view.xml
+++ b/packages/Keyguard/res/layout-land/keyguard_host_view.xml
@@ -21,7 +21,7 @@
     and the security view. -->
 <com.android.keyguard.KeyguardHostView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:id="@+id/keyguard_host_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
diff --git a/packages/Keyguard/res/layout-land/keyguard_simple_host_view.xml b/packages/Keyguard/res/layout-land/keyguard_simple_host_view.xml
index ebd0a64..49b4212 100644
--- a/packages/Keyguard/res/layout-land/keyguard_simple_host_view.xml
+++ b/packages/Keyguard/res/layout-land/keyguard_simple_host_view.xml
@@ -21,7 +21,7 @@
     and the security view. -->
 <com.android.keyguard.KeyguardSimpleHostView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:id="@+id/keyguard_host_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
diff --git a/packages/Keyguard/res/layout-land/keyguard_widget_pager.xml b/packages/Keyguard/res/layout-land/keyguard_widget_pager.xml
index da31065..50c2709 100644
--- a/packages/Keyguard/res/layout-land/keyguard_widget_pager.xml
+++ b/packages/Keyguard/res/layout-land/keyguard_widget_pager.xml
@@ -19,7 +19,7 @@
 
 <!-- This is the selector widget that allows the user to select an action. -->
 <com.android.keyguard.KeyguardWidgetCarousel
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:paddingLeft="25dp"
     android:paddingRight="25dp"
diff --git a/packages/Keyguard/res/layout-port/keyguard_host_view.xml b/packages/Keyguard/res/layout-port/keyguard_host_view.xml
index 136b296..8223db4 100644
--- a/packages/Keyguard/res/layout-port/keyguard_host_view.xml
+++ b/packages/Keyguard/res/layout-port/keyguard_host_view.xml
@@ -21,7 +21,7 @@
     and the security view. -->
 <com.android.keyguard.KeyguardHostView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:id="@+id/keyguard_host_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
diff --git a/packages/Keyguard/res/layout-port/keyguard_simple_host_view.xml b/packages/Keyguard/res/layout-port/keyguard_simple_host_view.xml
index cba7667..ed600b0 100644
--- a/packages/Keyguard/res/layout-port/keyguard_simple_host_view.xml
+++ b/packages/Keyguard/res/layout-port/keyguard_simple_host_view.xml
@@ -21,7 +21,7 @@
     and the security view. -->
 <com.android.keyguard.KeyguardSimpleHostView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:id="@+id/keyguard_host_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
diff --git a/packages/Keyguard/res/layout-port/keyguard_widget_pager.xml b/packages/Keyguard/res/layout-port/keyguard_widget_pager.xml
index d0a07ca..6d7d864 100644
--- a/packages/Keyguard/res/layout-port/keyguard_widget_pager.xml
+++ b/packages/Keyguard/res/layout-port/keyguard_widget_pager.xml
@@ -19,7 +19,7 @@
 
 <!-- This is the selector widget that allows the user to select an action. -->
 <com.android.keyguard.KeyguardWidgetPager
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/app_widget_container"
     android:paddingLeft="25dp"
diff --git a/packages/Keyguard/res/layout-sw600dp-port/keyguard_host_view.xml b/packages/Keyguard/res/layout-sw600dp-port/keyguard_host_view.xml
index 85f6b6d..ba2f3a6 100644
--- a/packages/Keyguard/res/layout-sw600dp-port/keyguard_host_view.xml
+++ b/packages/Keyguard/res/layout-sw600dp-port/keyguard_host_view.xml
@@ -21,7 +21,7 @@
     and the security view. -->
 <com.android.keyguard.KeyguardHostView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:id="@+id/keyguard_host_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
diff --git a/packages/Keyguard/res/layout/keyguard_account_view.xml b/packages/Keyguard/res/layout/keyguard_account_view.xml
index 766effa..bde2ec6 100644
--- a/packages/Keyguard/res/layout/keyguard_account_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_account_view.xml
@@ -18,7 +18,7 @@
 -->
 <com.android.keyguard.KeyguardAccountView
     xmlns:android="http://schemas.android.com/apk/res/android"
-	xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+	xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:id="@+id/keyguard_account_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
diff --git a/packages/Keyguard/res/layout/keyguard_face_unlock_view.xml b/packages/Keyguard/res/layout/keyguard_face_unlock_view.xml
index 94c68a5..8c8ec7a 100644
--- a/packages/Keyguard/res/layout/keyguard_face_unlock_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_face_unlock_view.xml
@@ -20,7 +20,7 @@
 <!-- This is the screen that allows the user to unlock by showing their face.  -->
 <com.android.keyguard.KeyguardFaceUnlockView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:id="@+id/keyguard_face_unlock_view"
     android:orientation="vertical"
     android:layout_width="match_parent"
diff --git a/packages/Keyguard/res/layout/keyguard_multi_user_selector.xml b/packages/Keyguard/res/layout/keyguard_multi_user_selector.xml
index c1d5326..83036ab 100644
--- a/packages/Keyguard/res/layout/keyguard_multi_user_selector.xml
+++ b/packages/Keyguard/res/layout/keyguard_multi_user_selector.xml
@@ -17,7 +17,7 @@
 */
 -->
 <com.android.keyguard.KeyguardMultiUserSelectorView
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     xmlns:android="http://schemas.android.com/apk/res/android"
     androidprv:layout_childType="userSwitcher"
     android:id="@+id/keyguard_user_selector"
diff --git a/packages/Keyguard/res/layout/keyguard_password_view.xml b/packages/Keyguard/res/layout/keyguard_password_view.xml
index d8012bf..ed3f0e0 100644
--- a/packages/Keyguard/res/layout/keyguard_password_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_password_view.xml
@@ -18,7 +18,7 @@
 -->
 <com.android.keyguard.KeyguardPasswordView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:id="@+id/keyguard_password_view"
     android:orientation="vertical"
     android:layout_width="match_parent"
diff --git a/packages/Keyguard/res/layout/keyguard_pattern_view.xml b/packages/Keyguard/res/layout/keyguard_pattern_view.xml
index 0c9380c..3d7820f 100644
--- a/packages/Keyguard/res/layout/keyguard_pattern_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_pattern_view.xml
@@ -22,7 +22,7 @@
      is the portrait layout.  -->
 <com.android.keyguard.KeyguardPatternView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:id="@+id/keyguard_pattern_view"
     android:orientation="vertical"
     android:layout_width="match_parent"
diff --git a/packages/Keyguard/res/layout/keyguard_pin_view.xml b/packages/Keyguard/res/layout/keyguard_pin_view.xml
index 00c6a21..a804c8c 100644
--- a/packages/Keyguard/res/layout/keyguard_pin_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_pin_view.xml
@@ -19,7 +19,7 @@
 
 <com.android.keyguard.KeyguardPINView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:id="@+id/keyguard_pin_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
diff --git a/packages/Keyguard/res/layout/keyguard_presentation.xml b/packages/Keyguard/res/layout/keyguard_presentation.xml
index 7df0b70..ab676aa 100644
--- a/packages/Keyguard/res/layout/keyguard_presentation.xml
+++ b/packages/Keyguard/res/layout/keyguard_presentation.xml
@@ -20,7 +20,7 @@
 <!-- This is a view that shows general status information in Keyguard. -->
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:id="@+id/presentation"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
diff --git a/packages/Keyguard/res/layout/keyguard_selector_view.xml b/packages/Keyguard/res/layout/keyguard_selector_view.xml
index 6cb5e67..d3064ed 100644
--- a/packages/Keyguard/res/layout/keyguard_selector_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_selector_view.xml
@@ -20,7 +20,7 @@
 <!-- This is the selector widget that allows the user to select an action. -->
 <com.android.keyguard.KeyguardSelectorView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:id="@+id/keyguard_selector_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
diff --git a/packages/Keyguard/res/layout/keyguard_sim_pin_view.xml b/packages/Keyguard/res/layout/keyguard_sim_pin_view.xml
index eccac19..e96220e 100644
--- a/packages/Keyguard/res/layout/keyguard_sim_pin_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_sim_pin_view.xml
@@ -19,7 +19,7 @@
 <!-- This is the SIM PIN view that allows the user to enter a SIM PIN to unlock the device. -->
 <com.android.keyguard.KeyguardSimPinView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:id="@+id/keyguard_sim_pin_view"
     android:orientation="vertical"
     android:layout_width="match_parent"
diff --git a/packages/Keyguard/res/layout/keyguard_sim_puk_view.xml b/packages/Keyguard/res/layout/keyguard_sim_puk_view.xml
index fe37203..bf15ba0 100644
--- a/packages/Keyguard/res/layout/keyguard_sim_puk_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_sim_puk_view.xml
@@ -20,7 +20,7 @@
     carrier-provided PUK code and entering a new SIM PIN for it. -->
 <com.android.keyguard.KeyguardSimPukView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:id="@+id/keyguard_sim_puk_view"
     android:orientation="vertical"
     android:layout_width="match_parent"
diff --git a/packages/Keyguard/res/layout/keyguard_status_area.xml b/packages/Keyguard/res/layout/keyguard_status_area.xml
index 98ba512..2730517 100644
--- a/packages/Keyguard/res/layout/keyguard_status_area.xml
+++ b/packages/Keyguard/res/layout/keyguard_status_area.xml
@@ -20,7 +20,7 @@
 <!-- This is a view that shows general status information in Keyguard. -->
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="horizontal"
diff --git a/packages/Keyguard/res/layout/keyguard_status_view.xml b/packages/Keyguard/res/layout/keyguard_status_view.xml
index a4d298a..b6a6740 100644
--- a/packages/Keyguard/res/layout/keyguard_status_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_status_view.xml
@@ -20,7 +20,7 @@
 <!-- This is a view that shows general status information in Keyguard. -->
 <com.android.keyguard.KeyguardWidgetFrame
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:id="@+id/keyguard_status_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index 2e76f19..3f3a5df 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -118,7 +118,7 @@
         void userActivity();
     }
 
-    /*package*/ interface OnDismissAction {
+    public interface OnDismissAction {
         /* returns true if the dismiss should be deferred */
         boolean onDismiss();
     }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
index 97aec68..ab24133 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
@@ -57,12 +57,10 @@
         public void onTrigger(View v, int target) {
             final int resId = mGlowPadView.getResourceIdForTarget(target);
 
-            switch (resId) {
-                case R.drawable.ic_lockscreen_unlock_phantom:
-                case R.drawable.ic_lockscreen_unlock:
-                    mCallback.userActivity(0);
-                    mCallback.dismiss(false);
-                break;
+            if (resId == R.drawable.ic_lockscreen_unlock_phantom
+                    || resId == R.drawable.ic_lockscreen_unlock) {
+                mCallback.userActivity(0);
+                mCallback.dismiss(false);
             }
         }
 
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardService.java b/packages/Keyguard/src/com/android/keyguard/KeyguardService.java
deleted file mode 100644
index 36b2446..0000000
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardService.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.keyguard;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-import android.app.Service;
-import android.content.Intent;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Debug;
-import android.os.IBinder;
-import android.util.Log;
-import android.view.MotionEvent;
-
-import com.android.internal.policy.IKeyguardService;
-import com.android.internal.policy.IKeyguardExitCallback;
-import com.android.internal.policy.IKeyguardShowCallback;
-import com.android.internal.widget.LockPatternUtils;
-
-public class KeyguardService extends Service {
-    static final String TAG = "KeyguardService";
-    static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD;
-    private KeyguardViewMediator mKeyguardViewMediator;
-
-    @Override
-    public void onCreate() {
-        if (mKeyguardViewMediator == null) {
-            mKeyguardViewMediator = new KeyguardViewMediator(
-                    KeyguardService.this, new LockPatternUtils(KeyguardService.this));
-        }
-        Log.v(TAG, "onCreate()");
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return mBinder;
-    }
-
-    @Override
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        // TODO
-    }
-
-    void checkPermission() {
-        if (getBaseContext().checkCallingOrSelfPermission(PERMISSION) != PERMISSION_GRANTED) {
-            Log.w(TAG, "Caller needs permission '" + PERMISSION + "' to call " + Debug.getCaller());
-            throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
-                    + ", must have permission " + PERMISSION);
-        }
-    }
-
-    private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() {
-        public boolean isShowing() {
-            return mKeyguardViewMediator.isShowing();
-        }
-        public boolean isSecure() {
-            return mKeyguardViewMediator.isSecure();
-        }
-        public boolean isShowingAndNotHidden() {
-            return mKeyguardViewMediator.isShowingAndNotHidden();
-        }
-        public boolean isInputRestricted() {
-            return mKeyguardViewMediator.isInputRestricted();
-        }
-        public void verifyUnlock(IKeyguardExitCallback callback) {
-            mKeyguardViewMediator.verifyUnlock(callback);
-        }
-        public void keyguardDone(boolean authenticated, boolean wakeup) {
-            checkPermission();
-            mKeyguardViewMediator.keyguardDone(authenticated, wakeup);
-        }
-        public void setHidden(boolean isHidden) {
-            checkPermission();
-            mKeyguardViewMediator.setHidden(isHidden);
-        }
-        public void dismiss() {
-            mKeyguardViewMediator.dismiss();
-        }
-        public void onDreamingStarted() {
-            checkPermission();
-            mKeyguardViewMediator.onDreamingStarted();
-        }
-        public void onDreamingStopped() {
-            checkPermission();
-            mKeyguardViewMediator.onDreamingStopped();
-        }
-        public void onScreenTurnedOff(int reason) {
-            checkPermission();
-            mKeyguardViewMediator.onScreenTurnedOff(reason);
-        }
-        public void onScreenTurnedOn(IKeyguardShowCallback callback) {
-            checkPermission();
-            mKeyguardViewMediator.onScreenTurnedOn(callback);
-        }
-        public void setKeyguardEnabled(boolean enabled) {
-            checkPermission();
-            mKeyguardViewMediator.setKeyguardEnabled(enabled);
-        }
-        public boolean isDismissable() {
-            return mKeyguardViewMediator.isDismissable();
-        }
-        public void onSystemReady() {
-            checkPermission();
-            mKeyguardViewMediator.onSystemReady();
-        }
-        public void doKeyguardTimeout(Bundle options) {
-            checkPermission();
-            mKeyguardViewMediator.doKeyguardTimeout(options);
-        }
-        public void setCurrentUser(int userId) {
-            checkPermission();
-            mKeyguardViewMediator.setCurrentUser(userId);
-        }
-        public void showAssistant() {
-            checkPermission();
-            mKeyguardViewMediator.showAssistant();
-        }
-        public void dispatch(MotionEvent event) {
-            checkPermission();
-            mKeyguardViewMediator.dispatch(event);
-        }
-        public void launchCamera() {
-            checkPermission();
-            mKeyguardViewMediator.launchCamera();
-        }
-        public void onBootCompleted() {
-            checkPermission();
-            mKeyguardViewMediator.onBootCompleted();
-        }
-    };
-
-}
-
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk
index f8f064a..69c6159 100644
--- a/packages/SystemUI/Android.mk
+++ b/packages/SystemUI/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src) \
     src/com/android/systemui/EventLogTags.logtags
 
+LOCAL_STATIC_JAVA_LIBRARIES := Keyguard
 LOCAL_JAVA_LIBRARIES := telephony-common
 
 LOCAL_PACKAGE_NAME := SystemUI
@@ -14,6 +15,11 @@
 
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
+LOCAL_RESOURCE_DIR := \
+    frameworks/base/packages/Keyguard/res \
+    $(LOCAL_PATH)/res
+LOCAL_AAPT_FLAGS := --auto-add-overlay --extra-packages com.android.keyguard
+
 include $(BUILD_PACKAGE)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index b09cc1d..5d03367 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -240,6 +240,10 @@
             </intent-filter>
         </service>
 
+        <service
+            android:name=".keyguard.KeyguardService"
+            android:exported="true" />
+
         <activity android:name=".Somnambulator"
             android:label="@string/start_dreams"
             android:icon="@mipmap/ic_launcher_dreams"
diff --git a/packages/SystemUI/res/layout-sw600dp/super_status_bar.xml b/packages/SystemUI/res/layout-sw600dp/super_status_bar.xml
index 0947c6f..49314cd 100644
--- a/packages/SystemUI/res/layout-sw600dp/super_status_bar.xml
+++ b/packages/SystemUI/res/layout-sw600dp/super_status_bar.xml
@@ -31,7 +31,6 @@
         android:layout_height="@*android:dimen/status_bar_height"
         />
 
-
     <com.android.systemui.statusbar.phone.PanelHolder
         android:id="@+id/panel_holder"
         android:layout_width="match_parent"
@@ -49,4 +48,10 @@
             android:layout_gravity="end|top"
             />
     </com.android.systemui.statusbar.phone.PanelHolder>
+
+    <FrameLayout android:id="@+id/keyguard"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone">
+    </FrameLayout>
 </com.android.systemui.statusbar.phone.StatusBarWindowView>
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 2b56618..188c8a6 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -48,4 +48,9 @@
             />
     </com.android.systemui.statusbar.phone.PanelHolder>
 
+    <FrameLayout android:id="@+id/keyguard"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone">
+    </FrameLayout>
 </com.android.systemui.statusbar.phone.StatusBarWindowView>
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
new file mode 100644
index 0000000..cc87735
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -0,0 +1,272 @@
+/*
+ * 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 com.android.systemui.keyguard;
+
+import com.android.internal.policy.IKeyguardExitCallback;
+import com.android.internal.policy.IKeyguardService;
+import com.android.internal.policy.IKeyguardServiceConstants;
+import com.android.internal.policy.IKeyguardShowCallback;
+import com.android.systemui.statusbar.CommandQueue;
+
+import android.app.ActivityManagerNative;
+import android.app.Service;
+import android.app.StatusBarManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.MotionEvent;
+
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
+public class KeyguardService extends Service {
+    static final String TAG = "KeyguardService";
+    static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD;
+
+    public static final String ACTION_STATUS_BAR_BIND = "action.status_bar_bind";
+
+    private CommandQueue mCommandQueue;
+    private StatusBarManager mStatusBarManager;
+
+    @Override
+    public void onCreate() {
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (ACTION_STATUS_BAR_BIND.equals(intent.getAction())) {
+            return mKeyguardStatusBarBinder;
+        } else {
+            return mBinder;
+        }
+    }
+
+    void checkPermission() {
+        if (getBaseContext().checkCallingOrSelfPermission(PERMISSION) != PERMISSION_GRANTED) {
+            Log.w(TAG, "Caller needs permission '" + PERMISSION + "' to call " + Debug.getCaller());
+            throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
+                    + ", must have permission " + PERMISSION);
+        }
+    }
+
+    private final KeyguardStatusBarBinder mKeyguardStatusBarBinder =
+            new KeyguardStatusBarBinder() {
+
+        @Override
+        public void register(CommandQueue commandQueue) {
+            mCommandQueue = commandQueue;
+        }
+
+        @Override
+        public void dismissKeyguard() {
+            try {
+                mBinder.dismiss();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Could not dismiss keyguard", e);
+            }
+        }
+    };
+
+    private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() {
+
+        /** Whether the Keyguard is visible. */
+        private boolean mShowing;
+
+        /**
+         * Whether the Keyguard is hidden by a window with
+         * {@link android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED}. So mShowing might
+         * be true, but also mHidden. So in the end, the Keyguard would not be visible.
+         */
+        private boolean mHidden;
+        private boolean mShowingDream;
+
+        @Override
+        public synchronized boolean isShowing() {
+            return mShowing;
+        }
+
+        @Override
+        public synchronized boolean isSecure() {
+            return true;
+        }
+
+        @Override
+        public synchronized boolean isShowingAndNotHidden() {
+            return mShowing && !mHidden;
+        }
+
+        @Override
+        public synchronized boolean isInputRestricted() {
+            return false;
+        }
+
+        @Override
+        public synchronized void verifyUnlock(IKeyguardExitCallback callback) {
+        }
+
+        @Override
+        public synchronized void keyguardDone(boolean authenticated, boolean wakeup) {
+            checkPermission();
+            mShowing = false;
+            adjustStatusBarLocked();
+            if (mCommandQueue != null) {
+                mCommandQueue.setKeyguardShown(false, null, true);
+            }
+        }
+
+        @Override
+        public synchronized int setHidden(boolean isHidden) {
+            checkPermission();
+            if (mHidden == isHidden) {
+                return IKeyguardServiceConstants.KEYGUARD_SERVICE_HIDE_RESULT_NONE;
+            }
+            mHidden = isHidden;
+            try {
+                ActivityManagerNative.getDefault().setLockScreenShown(mShowing && !mHidden
+                        || mShowingDream);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Could not update activity manager lock screen state", e);
+            }
+            adjustStatusBarLocked();
+            if (mCommandQueue != null) {
+                mCommandQueue.setKeyguardShown(!isHidden, null, false);
+            }
+            return isShowingAndNotHidden()
+                    ? IKeyguardServiceConstants.KEYGUARD_SERVICE_HIDE_RESULT_SET_FLAGS
+                    : IKeyguardServiceConstants.KEYGUARD_SERVICE_HIDE_RESULT_UNSET_FLAGS;
+        }
+
+        @Override
+        public synchronized void dismiss() {
+            checkPermission();
+            mShowing = false;
+            adjustStatusBarLocked();
+            if (mCommandQueue != null) {
+                mCommandQueue.setKeyguardShown(false, null, true);
+            }
+        }
+
+        @Override
+        public synchronized void onDreamingStarted() {
+            checkPermission();
+            mShowingDream = true;
+        }
+
+        @Override
+        public synchronized void onDreamingStopped() {
+            checkPermission();
+            mShowingDream = false;
+        }
+
+        @Override
+        public synchronized void onScreenTurnedOff(int reason) {
+            checkPermission();
+        }
+
+        @Override
+        public synchronized void onScreenTurnedOn(IKeyguardShowCallback callback) {
+            checkPermission();
+            mShowing = true;
+            adjustStatusBarLocked();
+            if (mCommandQueue != null) {
+                mCommandQueue.setKeyguardShown(isShowingAndNotHidden(), callback, true);
+            }
+        }
+
+        @Override
+        public synchronized void setKeyguardEnabled(boolean enabled) {
+            checkPermission();
+        }
+
+        @Override
+        public synchronized boolean isDismissable() {
+            return !isSecure();
+        }
+
+        @Override
+        public synchronized void onSystemReady() {
+            checkPermission();
+        }
+
+        @Override
+        public synchronized void doKeyguardTimeout(Bundle options) {
+            checkPermission();
+        }
+
+        @Override
+        public synchronized void setCurrentUser(int userId) {
+            checkPermission();
+        }
+
+        @Override
+        public synchronized void showAssistant() {
+            checkPermission();
+        }
+
+        @Override
+        public synchronized void dispatch(MotionEvent event) {
+            checkPermission();
+        }
+
+        @Override
+        public synchronized void launchCamera() {
+            checkPermission();
+        }
+
+        @Override
+        public synchronized void onBootCompleted() {
+            checkPermission();
+            onScreenTurnedOn(null);
+        }
+
+        private void adjustStatusBarLocked() {
+            if (mStatusBarManager == null) {
+                mStatusBarManager = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE);
+            }
+            if (mStatusBarManager == null) {
+                Log.w(TAG, "Could not get status bar manager");
+            } else {
+                // Disable aspects of the system/status/navigation bars that must not be re-enabled by
+                // windows that appear on top, ever
+                int flags = StatusBarManager.DISABLE_NONE;
+                if (isShowing()) {
+                    // Permanently disable components not available when keyguard is enabled
+                    // (like recents). Temporary enable/disable (e.g. the "back" button) are
+                    // done in KeyguardHostView.
+                    flags |= StatusBarManager.DISABLE_RECENT;
+                    if (isSecure()) {
+                        // showing secure lockscreen; disable ticker and switch private notifications
+                        // to show their public versions, if available.
+                        flags |= StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS;
+                    }
+                    if (false) {
+                        flags |= StatusBarManager.DISABLE_SEARCH;
+                    }
+                }
+                if (isShowingAndNotHidden()) {
+                    flags |= StatusBarManager.DISABLE_HOME;
+                }
+                mStatusBarManager.disable(flags);
+            }
+        }
+    };
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardStatusBarBinder.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardStatusBarBinder.java
new file mode 100644
index 0000000..566943b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardStatusBarBinder.java
@@ -0,0 +1,32 @@
+/*
+ * 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 com.android.systemui.keyguard;
+
+import com.android.systemui.statusbar.CommandQueue;
+
+import android.os.Binder;
+import android.os.IBinder;
+
+/**
+ * Communication interface from status bar to {@link com.android.systemui.keyguard.KeyguardService}.
+ */
+public abstract class KeyguardStatusBarBinder extends Binder {
+
+    public abstract void register(CommandQueue commandQueue);
+
+    public abstract void dismissKeyguard();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index bad5641..eee6876 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -22,9 +22,11 @@
 import android.app.PendingIntent;
 import android.app.TaskStackBuilder;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.ServiceConnection;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -77,6 +79,8 @@
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.SearchPanelView;
 import com.android.systemui.SystemUI;
+import com.android.systemui.keyguard.KeyguardService;
+import com.android.systemui.keyguard.KeyguardStatusBarBinder;
 import com.android.systemui.statusbar.phone.KeyguardTouchDelegate;
 
 import java.util.ArrayList;
@@ -172,6 +176,8 @@
 
     protected int mZenMode;
 
+    protected KeyguardStatusBarBinder mKeyguardService;
+
     public IStatusBarService getStatusBarService() {
         return mBarService;
     }
@@ -314,6 +320,7 @@
 
         createAndAddWindows();
 
+        startKeyguardService();
         disable(switches[0]);
         setSystemUiVisibility(switches[1], 0xffffffff);
         topAppWindowChanged(switches[2] != 0);
@@ -364,6 +371,25 @@
         updateRelatedUserCache();
     }
 
+    private void startKeyguardService() {
+        Intent intent = new Intent(mContext, KeyguardService.class);
+        intent.setAction(KeyguardService.ACTION_STATUS_BAR_BIND);
+        if (!mContext.bindService(intent, new ServiceConnection() {
+            @Override
+            public void onServiceConnected(ComponentName name, IBinder service) {
+                mKeyguardService = (KeyguardStatusBarBinder) service;
+                mKeyguardService.register(mCommandQueue);
+            }
+
+            @Override
+            public void onServiceDisconnected(ComponentName name) {
+
+            }
+        }, Context.BIND_AUTO_CREATE)) {
+            throw new RuntimeException("Couldn't bind status bar keyguard.");
+        }
+    }
+
     public void userSwitched(int newUserId) {
         // should be overridden
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 39333d7..cf6f60c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -21,6 +21,7 @@
 import android.os.Message;
 import android.service.notification.StatusBarNotification;
 
+import com.android.internal.policy.IKeyguardShowCallback;
 import com.android.internal.statusbar.IStatusBar;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.statusbar.StatusBarIconList;
@@ -56,6 +57,7 @@
     private static final int MSG_PRELOAD_RECENT_APPS        = 14 << MSG_SHIFT;
     private static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 15 << MSG_SHIFT;
     private static final int MSG_SET_WINDOW_STATE           = 16 << MSG_SHIFT;
+    private static final int MSG_SET_KEYGUARD_SHOWN         = 17 << MSG_SHIFT;
 
     public static final int FLAG_EXCLUDE_NONE = 0;
     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -98,6 +100,8 @@
         public void hideSearchPanel();
         public void cancelPreloadRecentApps();
         public void setWindowState(int window, int state);
+        public void setKeyguardShown(boolean showKeyguard, IKeyguardShowCallback callback,
+                boolean updateWindowFlags);
     }
 
     public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
@@ -232,6 +236,15 @@
         }
     }
 
+    public void setKeyguardShown(boolean showKeyguard, IKeyguardShowCallback callback,
+            boolean updateWindowFlags) {
+        synchronized (mList) {
+            mHandler.removeMessages(MSG_SET_KEYGUARD_SHOWN);
+            mHandler.obtainMessage(MSG_SET_KEYGUARD_SHOWN,
+                    showKeyguard ? 1 : 0, updateWindowFlags ? 1 : 0, callback).sendToTarget();
+        }
+    }
+
     private final class H extends Handler {
         public void handleMessage(Message msg) {
             final int what = msg.what & MSG_MASK;
@@ -295,7 +308,7 @@
                     mCallbacks.topAppWindowChanged(msg.arg1 != 0);
                     break;
                 case MSG_SHOW_IME_BUTTON:
-                    mCallbacks.setImeWindowStatus((IBinder)msg.obj, msg.arg1, msg.arg2);
+                    mCallbacks.setImeWindowStatus((IBinder) msg.obj, msg.arg1, msg.arg2);
                     break;
                 case MSG_SET_HARD_KEYBOARD_STATUS:
                     mCallbacks.setHardKeyboardStatus(msg.arg1 != 0, msg.arg2 != 0);
@@ -312,6 +325,10 @@
                 case MSG_SET_WINDOW_STATE:
                     mCallbacks.setWindowState(msg.arg1, msg.arg2);
                     break;
+                case MSG_SET_KEYGUARD_SHOWN:
+                    mCallbacks.setKeyguardShown(msg.arg1 != 0, (IKeyguardShowCallback) msg.obj,
+                            msg.arg2 != 0);
+                    break;
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index e7f96dc..44f5e3a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -65,6 +65,7 @@
 import android.util.Log;
 import android.view.Display;
 import android.view.Gravity;
+import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
@@ -72,17 +73,22 @@
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewPropertyAnimator;
 import android.view.ViewStub;
+import android.view.ViewTreeObserver;
 import android.view.WindowManager;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 import android.view.animation.DecelerateInterpolator;
+import android.widget.Button;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import com.android.internal.policy.IKeyguardShowCallback;
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.keyguard.KeyguardHostView;
+import com.android.keyguard.KeyguardSimpleHostView;
 import com.android.systemui.DemoMode;
 import com.android.systemui.EventLogTags;
 import com.android.systemui.R;
@@ -350,6 +356,12 @@
             }
         }};
 
+    private boolean mKeyguardShowing;
+
+    private ViewGroup mKeyguard;
+
+    private Button mDismissKeyguard;
+
     @Override
     public void setZenMode(int mode) {
         super.setZenMode(mode);
@@ -431,6 +443,7 @@
                     }
                 });
 
+        mKeyguard = (ViewGroup) mStatusBarWindow.findViewById(R.id.keyguard);
         if (!ActivityManager.isHighEndGfx()) {
             mStatusBarWindow.setBackground(null);
             mNotificationPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
@@ -1495,15 +1508,19 @@
 
         // Expand the window to encompass the full screen in anticipation of the drag.
         // This is only possible to do atomically because the status bar is at the top of the screen!
+        expandWindow();
+
+        visibilityChanged(true);
+
+        setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
+    }
+
+    private void expandWindow() {
         WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
         lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
         lp.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
         lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
         mWindowManager.updateViewLayout(mStatusBarWindow, lp);
-
-        visibilityChanged(true);
-
-        setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
     }
 
     private void releaseFocus() {
@@ -1539,7 +1556,7 @@
             mHandler.sendEmptyMessage(MSG_CLOSE_SEARCH_PANEL);
         }
 
-        if (mStatusBarWindow != null) {
+        if (mStatusBarWindow != null && !mKeyguardShowing) {
             mStatusBarWindow.cancelExpandHelper();
             mStatusBarView.collapseAllPanels(true);
         }
@@ -1751,7 +1768,7 @@
         if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
                 + " mExpandedVisible=" + mExpandedVisible);
 
-        if (!mExpandedVisible || mStatusBarWindow == null) {
+        if (!mExpandedVisible || mStatusBarWindow == null || mKeyguardShowing) {
             return;
         }
 
@@ -1785,11 +1802,7 @@
         visibilityChanged(false);
 
         // Shrink the window to the size of the status bar only
-        WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
-        lp.height = getStatusBarHeight();
-        lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-        lp.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
-        mWindowManager.updateViewLayout(mStatusBarWindow, lp);
+        contractWindow();
 
         if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
             setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
@@ -1806,6 +1819,15 @@
         setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
     }
 
+    private void contractWindow() {
+        WindowManager.LayoutParams lp =
+                (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
+        lp.height = getStatusBarHeight();
+        lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+        lp.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+        mWindowManager.updateViewLayout(mStatusBarWindow, lp);
+    }
+
     /**
      * Enables or disables layers on the children of the notifications pile.
      *
@@ -1914,7 +1936,7 @@
                 && mStatusBarWindowState != state) {
             mStatusBarWindowState = state;
             if (DEBUG_WINDOW_STATE) Log.d(TAG, "Status bar " + windowStateToString(state));
-            if (!showing) {
+            if (!showing && !mKeyguardShowing) {
                 mStatusBarView.collapseAllPanels(false);
             }
         }
@@ -2356,7 +2378,6 @@
                 PixelFormat.TRANSLUCENT);
 
         lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
-
         lp.gravity = getStatusBarGravity();
         lp.setTitle("StatusBar");
         lp.packageName = mContext.getPackageName();
@@ -2671,6 +2692,67 @@
         }
     }
 
+    @Override
+    public void setKeyguardShown(boolean showKeyguard, final IKeyguardShowCallback callback,
+            boolean updateWindowFlags) {
+        mKeyguardShowing = showKeyguard;
+        if (updateWindowFlags) {
+            WindowManager.LayoutParams lp =
+                    (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
+            if (showKeyguard) {
+                lp.flags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+                lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+            } else {
+                lp.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+                lp.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+            }
+            mWindowManager.updateViewLayout(mStatusBarWindow, lp);
+        }
+        if (!showKeyguard) {
+            mKeyguard.setVisibility(View.GONE);
+            mKeyguard.removeAllViews();
+            contractWindow();
+        } else {
+            expandWindow();
+            mKeyguard.setVisibility(View.VISIBLE);
+            KeyguardSimpleHostView view = (KeyguardSimpleHostView) LayoutInflater.from(mContext)
+                    .inflate(R.layout.keyguard_simple_host_view, mKeyguard, false);
+            mKeyguard.addView(view);
+            view.setOnDismissAction(new KeyguardHostView.OnDismissAction() {
+                @Override
+                public boolean onDismiss() {
+                    contractWindow();
+                    if (mKeyguardService != null) {
+                        mKeyguardService.dismissKeyguard();
+                    }
+                    return false;
+                }
+            });
+            view.show();
+        }
+        if (callback != null) {
+            mStatusBarView.getViewTreeObserver().addOnPreDrawListener(
+                    new ViewTreeObserver.OnPreDrawListener() {
+                @Override
+                public boolean onPreDraw() {
+                    mStatusBarView.getViewTreeObserver().removeOnPreDrawListener(this);
+                    mStatusBarView.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            try {
+                                callback.onShown(mStatusBarWindow.getWindowToken());
+                            } catch (RemoteException e) {
+                                Log.e(TAG, "Could not call show callback", e);
+                            }
+                        }
+                    });
+                    return true;
+                }
+            });
+        }
+
+    }
+
     /**
      * Reload some of our resources when the configuration changes.
      *
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index dd13e31..2dc3373 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -22,6 +22,7 @@
 import android.view.ViewGroup.LayoutParams;
 import android.view.WindowManager;
 
+import com.android.internal.policy.IKeyguardShowCallback;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.systemui.statusbar.BaseStatusBar;
 
@@ -93,6 +94,11 @@
     }
 
     @Override
+    public void setKeyguardShown(boolean showKeyguard, IKeyguardShowCallback callback,
+            boolean updateKeyguardFlags) {
+    }
+
+    @Override
     protected void createAndAddWindows() {
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index ededbb2..fe032f9 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -96,6 +96,8 @@
 import android.view.animation.AnimationUtils;
 
 import com.android.internal.R;
+import com.android.internal.policy.IKeyguardService;
+import com.android.internal.policy.IKeyguardServiceConstants;
 import com.android.internal.policy.PolicyManager;
 import com.android.internal.policy.impl.keyguard.KeyguardServiceDelegate;
 import com.android.internal.statusbar.IStatusBarService;
@@ -174,6 +176,7 @@
      * Keyguard stuff
      */
     private WindowState mKeyguardScrim;
+    private boolean mKeyguardHidden;
 
     /* Table of Application Launch keys.  Maps from key codes to intent categories.
      *
@@ -248,7 +251,6 @@
     int[] mNavigationBarHeightForRotation = new int[4];
     int[] mNavigationBarWidthForRotation = new int[4];
 
-    WindowState mKeyguard = null;
     KeyguardServiceDelegate mKeyguardDelegate;
     GlobalActions mGlobalActions;
     volatile boolean mPowerKeyHandled; // accessed from input reader and handler thread
@@ -1311,7 +1313,6 @@
             case TYPE_BOOT_PROGRESS:
             case TYPE_DISPLAY_OVERLAY:
             case TYPE_HIDDEN_NAV_CONSUMER:
-            case TYPE_KEYGUARD:
             case TYPE_KEYGUARD_SCRIM:
             case TYPE_KEYGUARD_DIALOG:
             case TYPE_MAGNIFICATION_OVERLAY:
@@ -1348,6 +1349,17 @@
                         | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
                 attrs.flags &= ~WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
                 break;
+            case TYPE_STATUS_BAR:
+
+                // If the Keyguard is in a hidden state (occluded by another window), we force to
+                // remove the wallpaper and keyguard flag so that any change in-flight after setting
+                // the keyguard as occluded wouldn't set these flags again.
+                // See {@link #processKeyguardSetHiddenResultLw}.
+                if (mKeyguardHidden) {
+                    attrs.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+                    attrs.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+                }
+                break;
         }
     }
     
@@ -1434,54 +1446,50 @@
         case TYPE_KEYGUARD_SCRIM:
             // the safety window that shows behind keyguard while keyguard is starting
             return 12;
-        case TYPE_KEYGUARD:
-            // the keyguard; nothing on top of these can take focus, since they are
-            // responsible for power management when displayed.
-            return 13;
-        case TYPE_KEYGUARD_DIALOG:
-            return 14;
         case TYPE_STATUS_BAR_SUB_PANEL:
-            return 15;
+            return 13;
         case TYPE_STATUS_BAR:
-            return 16;
+            return 14;
         case TYPE_STATUS_BAR_PANEL:
-            return 17;
+            return 15;
+        case TYPE_KEYGUARD_DIALOG:
+            return 16;
         case TYPE_VOLUME_OVERLAY:
             // the on-screen volume indicator and controller shown when the user
             // changes the device volume
-            return 18;
+            return 17;
         case TYPE_SYSTEM_OVERLAY:
             // the on-screen volume indicator and controller shown when the user
             // changes the device volume
-            return 19;
+            return 18;
         case TYPE_NAVIGATION_BAR:
             // the navigation bar, if available, shows atop most things
-            return 20;
+            return 19;
         case TYPE_NAVIGATION_BAR_PANEL:
             // some panels (e.g. search) need to show on top of the navigation bar
-            return 21;
+            return 20;
         case TYPE_SYSTEM_ERROR:
             // system-level error dialogs
-            return 22;
+            return 21;
         case TYPE_MAGNIFICATION_OVERLAY:
             // used to highlight the magnified portion of a display
-            return 23;
+            return 22;
         case TYPE_DISPLAY_OVERLAY:
             // used to simulate secondary display devices
-            return 24;
+            return 23;
         case TYPE_DRAG:
             // the drag layer: input for drag-and-drop is associated with this window,
             // which sits above all other focusable windows
-            return 25;
+            return 24;
         case TYPE_SECURE_SYSTEM_OVERLAY:
-            return 26;
+            return 25;
         case TYPE_BOOT_PROGRESS:
-            return 27;
+            return 26;
         case TYPE_POINTER:
             // the (mouse) pointer layer
-            return 28;
+            return 27;
         case TYPE_HIDDEN_NAV_CONSUMER:
-            return 29;
+            return 28;
         }
         Log.e(TAG, "Unknown window type: " + type);
         return 2;
@@ -1551,7 +1559,7 @@
 
     @Override
     public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) {
-        return attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD;
+        return (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0;
     }
 
     @Override
@@ -1562,7 +1570,6 @@
             case TYPE_WALLPAPER:
             case TYPE_DREAM:
             case TYPE_UNIVERSE_BACKGROUND:
-            case TYPE_KEYGUARD:
             case TYPE_KEYGUARD_SCRIM:
                 return false;
             default:
@@ -1761,12 +1768,6 @@
                         android.Manifest.permission.STATUS_BAR_SERVICE,
                         "PhoneWindowManager");
                 break;
-            case TYPE_KEYGUARD:
-                if (mKeyguard != null) {
-                    return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
-                }
-                mKeyguard = win;
-                break;
             case TYPE_KEYGUARD_SCRIM:
                 if (mKeyguardScrim != null) {
                     return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
@@ -1783,9 +1784,6 @@
         if (mStatusBar == win) {
             mStatusBar = null;
             mStatusBarController.setWindow(null);
-        } else if (mKeyguard == win) {
-            Log.v(TAG, "Removing keyguard window (Did it crash?)");
-            mKeyguard = null;
             mKeyguardDelegate.showScrim();
         } else if (mKeyguardScrim == win) {
             Log.v(TAG, "Removing keyguard scrim");
@@ -1804,12 +1802,13 @@
         if (PRINT_ANIM) Log.i(TAG, "selectAnimation in " + win
               + ": transit=" + transit);
         if (win == mStatusBar) {
+            boolean isKeyguard = (win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0;
             if (transit == TRANSIT_EXIT
                     || transit == TRANSIT_HIDE) {
-                return R.anim.dock_top_exit;
+                return isKeyguard ? -1 : R.anim.dock_top_exit;
             } else if (transit == TRANSIT_ENTER
                     || transit == TRANSIT_SHOW) {
-                return R.anim.dock_top_enter;
+                return isKeyguard ? -1 : R.anim.dock_top_enter;
             }
         } else if (win == mNavigationBar) {
             // This can be on either the bottom or the right.
@@ -2030,9 +2029,9 @@
             WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
             if (attrs != null) {
                 final int type = attrs.type;
-                if (type == WindowManager.LayoutParams.TYPE_KEYGUARD
-                        || type == WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM
-                        || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {
+                if (type == WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM
+                        || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG
+                        || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
                     // the "app" is keyguard, so give it the key
                     return 0;
                 }
@@ -3083,9 +3082,8 @@
                                 + mOverscanScreenHeight;
                     } else if (canHideNavigationBar()
                             && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
-                            && (attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD || (
-                                attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
-                             && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW))) {
+                            && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
+                            && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
                         // Asking for layout as if the nav bar is hidden, lets the
                         // application extend into the unrestricted overscan screen area.  We
                         // only do this for application windows to ensure no window that
@@ -3395,13 +3393,13 @@
         if (mTopFullscreenOpaqueWindowState == null &&
                 win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw()) {
             if ((fl & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
-                if (attrs.type == TYPE_KEYGUARD) {
+                if ((attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
                     mForceStatusBarFromKeyguard = true;
                 } else {
                     mForceStatusBar = true;
                 }
             }
-            if (attrs.type == TYPE_KEYGUARD) {
+            if ((attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
                 mShowingLockscreen = true;
             }
             boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW
@@ -3531,57 +3529,54 @@
 
         // Hide the key guard if a visible window explicitly specifies that it wants to be
         // displayed when the screen is locked.
-        if (mKeyguard != null) {
-            if (localLOGV) Slog.v(TAG, "finishPostLayoutPolicyLw: mHideKeyguard="
-                    + mHideLockScreen);
-            if (mDismissKeyguard != DISMISS_KEYGUARD_NONE && !isKeyguardSecure()) {
-                if (mKeyguard.hideLw(true)) {
-                    changes |= FINISH_LAYOUT_REDO_LAYOUT
-                            | FINISH_LAYOUT_REDO_CONFIG
-                            | FINISH_LAYOUT_REDO_WALLPAPER;
-                }
-                if (mKeyguardDelegate.isShowing()) {
-                    mHandler.post(new Runnable() {
-                        @Override
-                        public void run() {
-                            mKeyguardDelegate.keyguardDone(false, false);
-                        }
-                    });
-                }
-            } else if (mHideLockScreen) {
-                if (mKeyguard.hideLw(true)) {
-                    changes |= FINISH_LAYOUT_REDO_LAYOUT
-                            | FINISH_LAYOUT_REDO_CONFIG
-                            | FINISH_LAYOUT_REDO_WALLPAPER;
-                }
-                if (!mShowingDream) {
-                    mKeyguardDelegate.setHidden(true);
-                }
-            } else if (mDismissKeyguard != DISMISS_KEYGUARD_NONE) {
-                // This is the case of keyguard isSecure() and not mHideLockScreen.
-                if (mDismissKeyguard == DISMISS_KEYGUARD_START) {
-                    // Only launch the next keyguard unlock window once per window.
-                    if (mKeyguard.showLw(true)) {
-                        changes |= FINISH_LAYOUT_REDO_LAYOUT
-                                | FINISH_LAYOUT_REDO_CONFIG
-                                | FINISH_LAYOUT_REDO_WALLPAPER;
+        if (localLOGV) Slog.v(TAG, "finishPostLayoutPolicyLw: mHideKeyguard="
+                + mHideLockScreen);
+        if (mDismissKeyguard != DISMISS_KEYGUARD_NONE && !isKeyguardSecure()) {
+            mKeyguardHidden = true;
+            if (processKeyguardSetHiddenResultLw(mKeyguardDelegate.setHidden(true))) {
+                changes |= FINISH_LAYOUT_REDO_LAYOUT
+                        | FINISH_LAYOUT_REDO_CONFIG
+                        | FINISH_LAYOUT_REDO_WALLPAPER;
+            }
+            if (mKeyguardDelegate.isShowing()) {
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mKeyguardDelegate.keyguardDone(false, false);
                     }
-                    mKeyguardDelegate.setHidden(false);
-                    mHandler.post(new Runnable() {
-                        @Override
-                        public void run() {
-                            mKeyguardDelegate.dismiss();
-                        }
-                    });
-                }
-            } else {
-                mWinDismissingKeyguard = null;
-                if (mKeyguard.showLw(true)) {
+                });
+            }
+        } else if (mHideLockScreen) {
+            mKeyguardHidden = true;
+            if (processKeyguardSetHiddenResultLw(mKeyguardDelegate.setHidden(true))) {
+                changes |= FINISH_LAYOUT_REDO_LAYOUT
+                        | FINISH_LAYOUT_REDO_CONFIG
+                        | FINISH_LAYOUT_REDO_WALLPAPER;
+            }
+        } else if (mDismissKeyguard != DISMISS_KEYGUARD_NONE) {
+            // This is the case of keyguard isSecure() and not mHideLockScreen.
+            if (mDismissKeyguard == DISMISS_KEYGUARD_START) {
+                // Only launch the next keyguard unlock window once per window.
+                mKeyguardHidden = false;
+                if (processKeyguardSetHiddenResultLw(mKeyguardDelegate.setHidden(false))) {
                     changes |= FINISH_LAYOUT_REDO_LAYOUT
                             | FINISH_LAYOUT_REDO_CONFIG
                             | FINISH_LAYOUT_REDO_WALLPAPER;
                 }
-                mKeyguardDelegate.setHidden(false);
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mKeyguardDelegate.dismiss();
+                    }
+                });
+            }
+        } else {
+            mWinDismissingKeyguard = null;
+            mKeyguardHidden = false;
+            if (processKeyguardSetHiddenResultLw(mKeyguardDelegate.setHidden(false))) {
+                changes |= FINISH_LAYOUT_REDO_LAYOUT
+                        | FINISH_LAYOUT_REDO_CONFIG
+                        | FINISH_LAYOUT_REDO_WALLPAPER;
             }
         }
 
@@ -3596,9 +3591,38 @@
         return changes;
     }
 
+    /**
+     * Processes the result code of {@link IKeyguardService#setHidden}. This is needed because we
+     * immediately need to put the wallpaper directly behind the Keyguard when a window with flag
+     * {@link android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED} gets dismissed. If we
+     * would wait for Keyguard to change the flags, that would be running asynchronously and thus be
+     * too late so the user might see the window behind.
+     *
+     * @param setHiddenResult The result code from {@link IKeyguardService#setHidden}.
+     * @return Whether the flags have changed and we have to redo the layout.
+     */
+    private boolean processKeyguardSetHiddenResultLw(int setHiddenResult) {
+        if (setHiddenResult == IKeyguardServiceConstants.KEYGUARD_SERVICE_HIDE_RESULT_SET_FLAGS) {
+            mStatusBar.getAttrs().privateFlags |= PRIVATE_FLAG_KEYGUARD;
+            mStatusBar.getAttrs().flags |= FLAG_SHOW_WALLPAPER;
+            return true;
+        } else if (setHiddenResult
+                == IKeyguardServiceConstants.KEYGUARD_SERVICE_HIDE_RESULT_UNSET_FLAGS) {
+            mStatusBar.getAttrs().privateFlags &= ~PRIVATE_FLAG_KEYGUARD;
+            mStatusBar.getAttrs().flags &= ~FLAG_SHOW_WALLPAPER;
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private boolean isStatusBarKeyguard() {
+        return mStatusBar != null
+                && (mStatusBar.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0;
+    }
+
     public boolean allowAppAnimationsLw() {
-        if (mKeyguard != null && mKeyguard.isVisibleLw() && !mKeyguard.isAnimatingLw()
-                || mShowingDream) {
+        if (isStatusBarKeyguard() || mShowingDream) {
             // If keyguard or dreams is currently visible, no reason to animate behind it.
             return false;
         }
@@ -5118,7 +5142,7 @@
         if (win == null) {
             return 0;
         }
-        if (win.getAttrs().type == TYPE_KEYGUARD && mHideLockScreen == true) {
+        if ((win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 && mHideLockScreen == true) {
             // We are updating at a point where the keyguard has gotten
             // focus, but we were last in a state where the top window is
             // hiding it.  This is probably because the keyguard as been
@@ -5164,8 +5188,8 @@
 
     private int updateSystemBarsLw(WindowState win, int oldVis, int vis) {
         // apply translucent bar vis flags
-        WindowState transWin = mKeyguard != null && mKeyguard.isVisibleLw() && !mHideLockScreen
-                ? mKeyguard
+        WindowState transWin = isStatusBarKeyguard() && !mHideLockScreen
+                ? mStatusBar
                 : mTopFullscreenOpaqueWindowState;
         vis = mStatusBarController.applyTranslucentFlagLw(transWin, vis, oldVis);
         vis = mNavigationBarController.applyTranslucentFlagLw(transWin, vis, oldVis);
@@ -5423,15 +5447,13 @@
         if (mStatusBar != null) {
             pw.print(prefix); pw.print("mStatusBar=");
                     pw.println(mStatusBar);
+            pw.print(prefix); pw.print("isStatusBarKeyguard=");
+                    pw.print(isStatusBarKeyguard());
         }
         if (mNavigationBar != null) {
             pw.print(prefix); pw.print("mNavigationBar=");
                     pw.println(mNavigationBar);
         }
-        if (mKeyguard != null) {
-            pw.print(prefix); pw.print("mKeyguard=");
-                    pw.println(mKeyguard);
-        }
         if (mFocusedWindow != null) {
             pw.print(prefix); pw.print("mFocusedWindow=");
                     pw.println(mFocusedWindow);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
index 812e817..d0281d1 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
@@ -29,8 +29,8 @@
  */
 public class KeyguardServiceDelegate {
     // TODO: propagate changes to these to {@link KeyguardTouchDelegate}
-    public static final String KEYGUARD_PACKAGE = "com.android.keyguard";
-    public static final String KEYGUARD_CLASS = "com.android.keyguard.KeyguardService";
+    public static final String KEYGUARD_PACKAGE = "com.android.systemui";
+    public static final String KEYGUARD_CLASS = "com.android.systemui.keyguard.KeyguardService";
 
     private static final String TAG = "KeyguardServiceDelegate";
     private static final boolean DEBUG = true;
@@ -174,11 +174,13 @@
         }
     }
 
-    public void setHidden(boolean isHidden) {
+    public int setHidden(boolean isHidden) {
+        int result = 0;
         if (mKeyguardService != null) {
-            mKeyguardService.setHidden(isHidden);
+            result = mKeyguardService.setHidden(isHidden);
         }
         mKeyguardState.hidden = isHidden;
+        return result;
     }
 
     public void dismiss() {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
index 9fb2a50..20a00e3 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
@@ -100,11 +100,12 @@
         }
     }
 
-    public void setHidden(boolean isHidden) {
+    public int setHidden(boolean isHidden) {
         try {
-            mService.setHidden(isHidden);
+            return mService.setHidden(isHidden);
         } catch (RemoteException e) {
             Slog.w(TAG , "Remote Exception", e);
+            return 0;
         }
     }
 
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 35f873e..a72965d 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -2972,7 +2972,6 @@
                     return AccessibilityWindowInfo.TYPE_INPUT_METHOD;
                 }
 
-                case WindowManager.LayoutParams.TYPE_KEYGUARD:
                 case WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG:
                 case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR:
                 case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL:
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 4aae5c1..a1b82c4 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -284,7 +284,7 @@
                 final boolean hasFocus = (child == mInputFocus);
                 final boolean isVisible = child.isVisibleLw();
                 final boolean hasWallpaper = (child == mService.mWallpaperTarget)
-                        && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
+                        && (privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD) == 0;
                 final boolean onDefaultDisplay = (child.getDisplayId() == Display.DEFAULT_DISPLAY);
 
                 // If there's a drag in progress and 'child' is a potential drop target,
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index dcf5880..c6e997e 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1885,7 +1885,9 @@
                 int insertionIndex = 0;
                 if (visible && foundW != null) {
                     final int type = foundW.mAttrs.type;
-                    if (type == TYPE_KEYGUARD || type == TYPE_KEYGUARD_SCRIM) {
+                    final int privateFlags = foundW.mAttrs.privateFlags;
+                    if ((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0
+                            || type == TYPE_KEYGUARD_SCRIM) {
                         insertionIndex = windows.indexOf(foundW);
                     }
                 }
@@ -5347,7 +5349,7 @@
                 final int N = windows.size();
                 for (int i=0; i<N; i++) {
                     WindowState w = windows.get(i);
-                    if (w.mAttrs.type == TYPE_KEYGUARD) {
+                    if ((w.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
                         // Only if there is a keyguard attached to the window manager
                         // will we consider ourselves as having a keyguard.  If it
                         // isn't attached, we don't know if it wants to be shown or
@@ -5369,7 +5371,7 @@
                             haveApp = true;
                         } else if (w.mAttrs.type == TYPE_WALLPAPER) {
                             haveWallpaper = true;
-                        } else if (w.mAttrs.type == TYPE_KEYGUARD) {
+                        } else if ((w.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
                             haveKeyguard = true;
                         }
                     }
@@ -8307,7 +8309,7 @@
             // just don't display").
             if (!gone || !win.mHaveFrame || win.mLayoutNeeded
                     || ((win.isConfigChanged() || win.setInsetsChanged()) &&
-                            (win.mAttrs.type == TYPE_KEYGUARD ||
+                            ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
                             win.mAppToken != null && win.mAppToken.layoutConfigChanges))
                     || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
                 if (!win.mLayoutAttached) {
@@ -8847,8 +8849,8 @@
             if (canBeSeen
                     && (type == TYPE_SYSTEM_DIALOG
                      || type == TYPE_RECENTS_OVERLAY
-                     || type == TYPE_KEYGUARD
-                     || type == TYPE_SYSTEM_ERROR)) {
+                     || type == TYPE_SYSTEM_ERROR
+                     || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0)) {
                 mInnerFields.mSyswin = true;
             }
 
@@ -8861,7 +8863,7 @@
                     // content on secondary displays (by forcibly enabling mirroring unless
                     // there is other content we want to show) but still allow opaque
                     // keyguard dialogs to be shown.
-                    if (type == TYPE_DREAM || type == TYPE_KEYGUARD) {
+                    if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
                         mInnerFields.mObscureApplicationContentOnSecondaryDisplays = true;
                     }
                     mInnerFields.mDisplayHasContent = true;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 2c0e99e..2ff4830 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -23,12 +23,12 @@
 import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
 
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
 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;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
 import android.app.AppOpsManager;
@@ -1010,7 +1010,7 @@
                 && (mConfiguration == null
                         || (mConfiguration.diff(mService.mCurConfiguration) != 0));
 
-        if (mAttrs.type == TYPE_KEYGUARD) {
+        if ((mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
             // Retain configuration changed status until resetConfiguration called.
             mConfigHasChanged |= configChanged;
             configChanged = mConfigHasChanged;