Merge "Supporting EXTRA_APPWIDGET_OPTIONS correctly" into jb-mr1-lockscreen-dev
diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java
index 3e8af60..16a0c57 100644
--- a/core/java/android/app/Presentation.java
+++ b/core/java/android/app/Presentation.java
@@ -79,17 +79,16 @@
  * Here's how to use the media router to create and show a presentation on the preferred
  * presentation display using {@link android.media.MediaRouter.RouteInfo#getPresentationDisplay()}.
  * </p>
- * {@samplecode
+ * <pre>
  * MediaRouter mediaRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
  * MediaRouter.RouteInfo route = mediaRouter.getSelectedRoute();
- * if (route != null) $&#123;
+ * if (route != null) {
  *     Display presentationDisplay = route.getPresentationDisplay();
- *     if (presentationDisplay != null) $&#123;
+ *     if (presentationDisplay != null) {
  *         Presentation presentation = new MyPresentation(context, presentationDisplay);
  *         presentation.show();
- *     $&#125;
- * $&#125;
- * }
+ *     }
+ * }</pre>
  * <p>
  * The following sample code from <code>ApiDemos</code> demonstrates how to use the media
  * router to automatically switch between showing content in the main activity and showing
@@ -114,18 +113,17 @@
  * {@link DisplayManager#getDisplays(String)} and the
  * {@link DisplayManager#DISPLAY_CATEGORY_PRESENTATION} category.
  * </p>
- * {@samplecode
+ * <pre>
  * DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
  * Display[] presentationDisplays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
- * if (presentationDisplays.length > 0) $&#123;
+ * if (presentationDisplays.length > 0) {
  *     // If there is more than one suitable presentation display, then we could consider
  *     // giving the user a choice.  For this example, we simply choose the first display
  *     // which is the one the system recommends as the preferred presentation display.
  *     Display display = presentationDisplays[0];
  *     Presentation presentation = new MyPresentation(context, presentationDisplay);
  *     presentation.show();
- * $&#125;
- * }
+ * }</pre>
  * <p>
  * The following sample code from <code>ApiDemos</code> demonstrates how to use the display
  * manager to enumerate displays and show content on multiple presentation displays
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d5e1ed3..ff44475 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5088,24 +5088,35 @@
      */
     protected boolean isVisibleToUser(Rect boundInView) {
         if (mAttachInfo != null) {
+            // Attached to invisible window means this view is not visible.
+            if (mAttachInfo.mWindowVisibility != View.VISIBLE) {
+                return false;
+            }
+            // An invisible predecessor or one with alpha zero means
+            // that this view is not visible to the user.
+            Object current = this;
+            while (current instanceof View) {
+                View view = (View) current;
+                // We have attach info so this view is attached and there is no
+                // need to check whether we reach to ViewRootImpl on the way up.
+                if (view.getAlpha() <= 0 || view.getVisibility() != VISIBLE) {
+                    return false;
+                }
+                current = view.mParent;
+            }
+            // Check if the view is entirely covered by its predecessors.
             Rect visibleRect = mAttachInfo.mTmpInvalRect;
             Point offset = mAttachInfo.mPoint;
-            // The first two checks are made also made by isShown() which
-            // however traverses the tree up to the parent to catch that.
-            // Therefore, we do some fail fast check to minimize the up
-            // tree traversal.
-            boolean isVisible = mAttachInfo.mWindowVisibility == View.VISIBLE
-                && getAlpha() > 0
-                && isShown()
-                && getGlobalVisibleRect(visibleRect, offset);
-            if (isVisible && boundInView != null) {
-                visibleRect.offset(-offset.x, -offset.y);
-                // isVisible is always true here, use a simple assignment
-                isVisible = boundInView.intersect(visibleRect);
+            if (!getGlobalVisibleRect(visibleRect, offset)) {
+                return false;
             }
-            return isVisible;
+            // Check if the visible portion intersects the rectangle of interest.
+            if (boundInView != null) {
+                visibleRect.offset(-offset.x, -offset.y);
+                return boundInView.intersect(visibleRect);
+            }
+            return true;
         }
-
         return false;
     }
 
diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java
index 4c46658..908eb0a 100644
--- a/core/java/android/widget/TextClock.java
+++ b/core/java/android/widget/TextClock.java
@@ -29,6 +29,7 @@
 import android.provider.Settings;
 import android.text.format.DateFormat;
 import android.util.AttributeSet;
+import android.view.RemotableViewMethod;
 
 import com.android.internal.R;
 
@@ -266,6 +267,7 @@
      * 
      * @attr ref android.R.styleable#TextClock_format12Hour
      */
+    @RemotableViewMethod
     public void setFormat12Hour(CharSequence format) {
         mFormat12 = format;
 
@@ -307,6 +309,7 @@
      *
      * @attr ref android.R.styleable#TextClock_format24Hour
      */
+    @RemotableViewMethod
     public void setFormat24Hour(CharSequence format) {
         mFormat24 = format;
 
@@ -366,6 +369,7 @@
      *
      * @attr ref android.R.styleable#TextClock_timeZone
      */
+    @RemotableViewMethod
     public void setTimeZone(String timeZone) {
         mTimeZone = timeZone;
 
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a46481c..5d90400 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8780,8 +8780,8 @@
                     + " before=" + before + " after=" + after + ": " + buffer);
 
             if (AccessibilityManager.getInstance(mContext).isEnabled()
-                    && !isPasswordInputType(getInputType())
-                    && !hasPasswordTransformationMethod()) {
+                    && ((!isPasswordInputType(getInputType()) && !hasPasswordTransformationMethod())
+                            || shouldSpeakPasswordsForAccessibility())) {
                 mBeforeText = buffer.toString();
             }
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 3f20ed1..7971ccb 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -290,7 +290,16 @@
         android:permissionGroup="android.permission-group.PERSONAL_INFO"
         android:protectionLevel="signature|system" />
 
-    <!-- Allows an application to read the user's call log. -->
+    <!-- Allows an application to read the user's call log.
+         <p class="note"><strong>Note:</strong> If your app uses the
+         {@link #READ_CONTACTS} permission and <em>both</em> your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+         minSdkVersion}</a> and <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> values are set to 15 or lower, the system implicitly
+         grants your app this permission. If you don't need this permission, be sure your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> is 16 or higher.</p> -->
     <permission android:name="android.permission.READ_CALL_LOG"
         android:permissionGroup="android.permission-group.SOCIAL_INFO"
         android:protectionLevel="dangerous"
@@ -298,7 +307,16 @@
         android:description="@string/permdesc_readCallLog" />
 
     <!-- Allows an application to write (but not read) the user's
-         contacts data. -->
+         contacts data.
+         <p class="note"><strong>Note:</strong> If your app uses the
+         {@link #WRITE_CONTACTS} permission and <em>both</em> your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+         minSdkVersion}</a> and <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> values are set to 15 or lower, the system implicitly
+         grants your app this permission. If you don't need this permission, be sure your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> is 16 or higher.</p>  -->
     <permission android:name="android.permission.WRITE_CALL_LOG"
         android:permissionGroup="android.permission-group.SOCIAL_INFO"
         android:protectionLevel="dangerous"
@@ -888,7 +906,15 @@
         android:label="@string/permlab_modifyPhoneState"
         android:description="@string/permdesc_modifyPhoneState" />
 
-    <!-- Allows read only access to phone state. -->
+    <!-- Allows read only access to phone state.
+         <p class="note"><strong>Note:</strong> If <em>both</em> your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+         minSdkVersion}</a> and <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> values are set to 3 or lower, the system implicitly
+         grants your app this permission. If you don't need this permission, be sure your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> is 4 or higher. -->
     <permission android:name="android.permission.READ_PHONE_STATE"
         android:permissionGroup="android.permission-group.PHONE_CALLS"
         android:protectionLevel="dangerous"
@@ -931,14 +957,41 @@
         android:permissionGroupFlags="personalInfo"
         android:priority="240" />
 
-    <!-- Allows an application to read from external storage -->
+    <!-- Allows an application to read from external storage.
+         <p>Any app that declares the {@link #WRITE_EXTERNAL_STORAGE} permission is implicitly
+         granted this permission.</p>
+         <p>Currently, this permission is not enforced and all apps still have access to read from
+         external storage without this permission. That will change in a future release and apps
+         will require this permission to read from external storage. So if your
+         app reads from the external storage, you should add this permission to your app now
+         to ensure that it continues to work on future versions of Android.</p>
+         <p>You can test your app with the permission enforced by either running your app on the
+         Android Emulator when running Android 4.1 or higher, or enabling <em>Protect USB
+         storage</em> under Developer options in the Settings app on a device running Android 4.1 or
+         higher.</p>
+         <p class="note"><strong>Note:</strong> If <em>both</em> your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+         minSdkVersion}</a> and <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> values are set to 3 or lower, the system implicitly
+         grants your app this permission. If you don't need this permission, be sure your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> is 4 or higher.-->
     <permission android:name="android.permission.READ_EXTERNAL_STORAGE"
         android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
         android:label="@string/permlab_sdcardRead"
         android:description="@string/permdesc_sdcardRead"
         android:protectionLevel="normal" />
 
-    <!-- Allows an application to write to external storage -->
+    <!-- Allows an application to write to external storage.
+         <p class="note"><strong>Note:</strong> If <em>both</em> your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+         minSdkVersion}</a> and <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> values are set to 3 or lower, the system implicitly
+         grants your app this permission. If you don't need this permission, be sure your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> is 4 or higher. -->
     <permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
         android:permissionGroup="android.permission-group.STORAGE"
         android:label="@string/permlab_sdcardWrite"
diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml
index 9921313..b2bf3f1 100644
--- a/core/res/res/layout-port/keyguard_host_view.xml
+++ b/core/res/res/layout-port/keyguard_host_view.xml
@@ -64,7 +64,6 @@
             android:layout_width="wrap_content"
             android:layout_height="@dimen/keyguard_security_height"
             androidprv:layout_childType="challenge"
-            android:background="@drawable/kg_bouncer_bg_white"
             android:padding="0dp"
             android:gravity="bottom|center_horizontal">
             <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
diff --git a/core/res/res/layout/keyguard_face_unlock_view.xml b/core/res/res/layout/keyguard_face_unlock_view.xml
index 39e8f31..c1e35cf 100644
--- a/core/res/res/layout/keyguard_face_unlock_view.xml
+++ b/core/res/res/layout/keyguard_face_unlock_view.xml
@@ -31,32 +31,39 @@
         android:layout_height="wrap_content"
         />
 
-    <com.android.internal.widget.FaceUnlockView
-        android:id="@+id/face_unlock_area_view"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:background="@*android:drawable/intro_bg"
-        android:gravity="center"
-        android:layout_weight="1">
+    <FrameLayout
+       android:id="@+id/keyguard_bouncer_frame"
+       android:background="@*android:drawable/kg_bouncer_bg_white"
+       android:layout_width="match_parent"
+       android:layout_height="0dp"
+       android:layout_weight="1"
+       >
+       <com.android.internal.widget.FaceUnlockView
+           android:id="@+id/face_unlock_area_view"
+           android:layout_width="match_parent"
+           android:layout_height="match_parent"
+           android:background="@*android:drawable/intro_bg"
+           android:gravity="center">
 
-        <View
-            android:id="@+id/spotlightMask"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:background="@*android:color/facelock_spotlight_mask"
-        />
+           <View
+               android:id="@+id/spotlightMask"
+               android:layout_width="match_parent"
+               android:layout_height="match_parent"
+               android:background="@*android:color/facelock_spotlight_mask"
+           />
 
-        <ImageButton
-            android:id="@+id/face_unlock_cancel_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:padding="5dip"
-            android:layout_alignParentTop="true"
-            android:layout_alignParentEnd="true"
-            android:background="#00000000"
-            android:src="@*android:drawable/ic_facial_backup"
-        />
-    </com.android.internal.widget.FaceUnlockView>
+           <ImageButton
+               android:id="@+id/face_unlock_cancel_button"
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:padding="5dip"
+               android:layout_alignParentTop="true"
+               android:layout_alignParentEnd="true"
+               android:background="#00000000"
+               android:src="@*android:drawable/ic_facial_backup"
+           />
+       </com.android.internal.widget.FaceUnlockView>
+    </FrameLayout>
 
     <include layout="@layout/keyguard_emergency_carrier_area"
         android:id="@+id/keyguard_selector_fade_container"
diff --git a/core/res/res/layout/keyguard_password_view.xml b/core/res/res/layout/keyguard_password_view.xml
index a054d07..2e2ada8 100644
--- a/core/res/res/layout/keyguard_password_view.xml
+++ b/core/res/res/layout/keyguard_password_view.xml
@@ -39,45 +39,51 @@
     <!-- Password entry field -->
     <!-- Note: the entire container is styled to look like the edit field,
          since the backspace/IME switcher looks better inside -->
-     <LinearLayout
+      <FrameLayout
+         android:id="@+id/keyguard_bouncer_frame"
+         android:background="@*android:drawable/kg_bouncer_bg_white"
          android:layout_height="wrap_content"
          android:layout_width="match_parent"
-         android:orientation="horizontal"
-         android:background="#70000000"
-         android:layout_marginTop="8dp"
-         android:layout_marginBottom="8dp"
          >
-
-         <EditText android:id="@+id/passwordEntry"
-             android:layout_width="0dip"
+         <LinearLayout
              android:layout_height="wrap_content"
-             android:layout_weight="1"
-             android:gravity="center_horizontal"
-             android:layout_gravity="center_vertical"
-             android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
-             android:singleLine="true"
-             android:textStyle="normal"
-             android:inputType="textPassword"
-             android:textSize="36sp"
-             android:background="@null"
-             android:textAppearance="?android:attr/textAppearanceMedium"
-             android:textColor="#ffffffff"
-             android:imeOptions="flagForceAscii|actionDone"
-             />
+             android:layout_width="match_parent"
+             android:orientation="horizontal"
+             android:background="#70000000"
+             android:layout_marginTop="8dp"
+             android:layout_marginBottom="8dp"
+             >
 
-         <ImageView android:id="@+id/switch_ime_button"
-             android:layout_width="wrap_content"
-             android:layout_height="wrap_content"
-             android:src="@*android:drawable/ic_lockscreen_ime"
-             android:clickable="true"
-             android:padding="8dip"
-             android:layout_gravity="center"
-             android:background="?android:attr/selectableItemBackground"
-             android:visibility="gone"
-             />
+             <EditText android:id="@+id/passwordEntry"
+                 android:layout_width="0dip"
+                 android:layout_height="wrap_content"
+                 android:layout_weight="1"
+                 android:gravity="center_horizontal"
+                 android:layout_gravity="center_vertical"
+                 android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
+                 android:singleLine="true"
+                 android:textStyle="normal"
+                 android:inputType="textPassword"
+                 android:textSize="36sp"
+                 android:background="@null"
+                 android:textAppearance="?android:attr/textAppearanceMedium"
+                 android:textColor="#ffffffff"
+                 android:imeOptions="flagForceAscii|actionDone"
+                 />
 
-        </LinearLayout>
+             <ImageView android:id="@+id/switch_ime_button"
+                 android:layout_width="wrap_content"
+                 android:layout_height="wrap_content"
+                 android:src="@*android:drawable/ic_lockscreen_ime"
+                 android:clickable="true"
+                 android:padding="8dip"
+                 android:layout_gravity="center"
+                 android:background="?android:attr/selectableItemBackground"
+                 android:visibility="gone"
+                 />
 
+            </LinearLayout>
+       </FrameLayout>
     <include layout="@layout/keyguard_emergency_carrier_area"
              android:id="@+id/keyguard_selector_fade_container"
              android:layout_width="match_parent"
diff --git a/core/res/res/layout/keyguard_pattern_view.xml b/core/res/res/layout/keyguard_pattern_view.xml
index 5ebc000..1c11fdd 100644
--- a/core/res/res/layout/keyguard_pattern_view.xml
+++ b/core/res/res/layout/keyguard_pattern_view.xml
@@ -43,14 +43,17 @@
             android:orientation="vertical"
             android:layout_gravity="center">
 
-            <!-- We need MATCH_PARENT here only to force the size of the parent to be passed to
-            the pattern view for it to compute its size. This is an unusual case, caused by
-            LockPatternView's requirement to maintain a square aspect ratio based on the width
-            of the screen. -->
+          <FrameLayout
+             android:id="@+id/keyguard_bouncer_frame"
+             android:background="@*android:drawable/kg_bouncer_bg_white"
+             android:layout_width="match_parent"
+             android:layout_height="0dp"
+             android:layout_weight="1"
+             >
             <com.android.internal.widget.LockPatternView
                 android:id="@+id/lockPatternView"
-                android:layout_width="wrap_content"
-                android:layout_height="0dp"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
                 android:layout_weight="1"
                 android:layout_marginEnd="8dip"
                 android:layout_marginBottom="4dip"
@@ -58,15 +61,14 @@
                 android:layout_gravity="center_horizontal"
                 android:gravity="center"
                 android:contentDescription="@string/keyguard_accessibility_pattern_area" />
-
-            <include layout="@layout/keyguard_emergency_carrier_area"
-                android:id="@+id/keyguard_selector_fade_container"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="vertical"
-                android:layout_gravity="bottom|center_horizontal"
-                android:gravity="center_horizontal" />
-
+          </FrameLayout>
+          <include layout="@layout/keyguard_emergency_carrier_area"
+              android:id="@+id/keyguard_selector_fade_container"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:orientation="vertical"
+              android:layout_gravity="bottom|center_horizontal"
+              android:gravity="center_horizontal" />
         </LinearLayout>
     </FrameLayout>
 
diff --git a/core/res/res/layout/keyguard_pin_view.xml b/core/res/res/layout/keyguard_pin_view.xml
index d6cfe2a..d486d5e 100644
--- a/core/res/res/layout/keyguard_pin_view.xml
+++ b/core/res/res/layout/keyguard_pin_view.xml
@@ -31,177 +31,185 @@
         android:layout_height="wrap_content"
         />
     <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:orientation="horizontal"
-        android:layout_weight="1"
-        >
-        <TextView android:id="@+id/pinEntry"
-            android:editable="true"
-            android:layout_width="0dip"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            android:gravity="center"
-            android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
-            android:singleLine="true"
-            android:cursorVisible="false"
-            android:background="@null"
-            android:textAppearance="@android:style/TextAppearance.NumPadKey"
-            android:imeOptions="flagForceAscii|actionDone"
-            />
-        <ImageButton android:id="@+id/delete_button"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:gravity="center_vertical"
-            android:src="@*android:drawable/ic_input_delete"
-            android:clickable="true"
-            android:paddingTop="8dip"
-            android:paddingBottom="8dip"
-            android:paddingLeft="24dp"
-            android:paddingRight="24dp"
-            android:background="?android:attr/selectableItemBackground"
-            android:contentDescription="@string/keyboardview_keycode_delete"
-            />
+       android:id="@+id/keyguard_bouncer_frame"
+       android:background="@*android:drawable/kg_bouncer_bg_white"
+       android:layout_width="match_parent"
+       android:layout_height="0dp"
+       android:orientation="vertical"
+       android:layout_weight="1"
+       >
+       <LinearLayout
+          android:layout_width="match_parent"
+          android:layout_height="0dp"
+          android:orientation="horizontal"
+          android:layout_weight="1"
+          >
+          <TextView android:id="@+id/pinEntry"
+               android:editable="true"
+               android:layout_width="0dip"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               android:gravity="center"
+               android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
+               android:singleLine="true"
+               android:cursorVisible="false"
+               android:background="@null"
+               android:textAppearance="@style/TextAppearance.NumPadKey"
+               android:imeOptions="flagForceAscii|actionDone"
+               />
+           <ImageButton android:id="@+id/delete_button"
+               android:layout_width="wrap_content"
+               android:layout_height="match_parent"
+               android:gravity="center_vertical"
+               android:src="@*android:drawable/ic_input_delete"
+               android:clickable="true"
+               android:paddingTop="8dip"
+               android:paddingBottom="8dip"
+               android:paddingLeft="24dp"
+               android:paddingRight="24dp"
+               android:background="?android:attr/selectableItemBackground"
+               android:contentDescription="@string/keyboardview_keycode_delete"
+               />
+       </LinearLayout>
+       <View
+           android:layout_width="wrap_content"
+           android:layout_height="1dp"
+           android:background="#55FFFFFF"
+           />
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key1"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="1"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key2"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="2"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key3"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="3"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key4"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="4"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key5"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="5"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key6"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="6"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:orientation="horizontal"
+           android:layout_weight="1"
+           >
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key7"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="7"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key8"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="8"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key9"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="9"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <Space
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key0"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="0"
+               />
+           <ImageButton
+               android:id="@+id/key_enter"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               android:paddingRight="30dp"
+               android:src="@drawable/sym_keyboard_return_holo"
+               android:contentDescription="@string/keyboardview_keycode_enter"
+               />
+       </LinearLayout>
     </LinearLayout>
-    <View
-        android:layout_width="wrap_content"
-        android:layout_height="1dp"
-        android:background="#55FFFFFF"
-        />
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        android:orientation="horizontal"
-        >
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key1"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="1"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key2"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="2"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key3"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="3"
-            />
-    </LinearLayout>
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        android:orientation="horizontal"
-        >
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key4"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="4"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key5"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="5"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key6"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="6"
-            />
-    </LinearLayout>
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:orientation="horizontal"
-        android:layout_weight="1"
-        >
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key7"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="7"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key8"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="8"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key9"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="9"
-            />
-    </LinearLayout>
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        android:orientation="horizontal"
-        >
-        <Space
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key0"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="0"
-            />
-        <ImageButton
-            android:id="@+id/key_enter"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-			android:paddingRight="30dp"
-            android:src="@drawable/sym_keyboard_return_holo"
-            android:contentDescription="@string/keyboardview_keycode_enter"
-            />
-    </LinearLayout>
-
     <include layout="@layout/keyguard_emergency_carrier_area"
                    android:id="@+id/keyguard_selector_fade_container"
                    android:layout_width="match_parent"
diff --git a/core/res/res/layout/keyguard_sim_pin_view.xml b/core/res/res/layout/keyguard_sim_pin_view.xml
index 36e1b15..67af6f9 100644
--- a/core/res/res/layout/keyguard_sim_pin_view.xml
+++ b/core/res/res/layout/keyguard_sim_pin_view.xml
@@ -27,7 +27,7 @@
     android:gravity="center_horizontal">
 
     <ImageView
-        android:layout_width="wrap_content"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:src="@drawable/ic_lockscreen_sim"/>
 
@@ -36,175 +36,184 @@
         android:layout_height="wrap_content"
         />
     <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:orientation="horizontal"
-        android:layout_weight="1"
-        >
-        <TextView android:id="@+id/pinEntry"
-            android:editable="true"
-            android:layout_width="0dip"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            android:gravity="center"
-            android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
-            android:singleLine="true"
-            android:cursorVisible="false"
-            android:background="@null"
-            android:textAppearance="@style/TextAppearance.NumPadKey"
-            android:imeOptions="flagForceAscii|actionDone"
-            />
-        <ImageButton android:id="@+id/delete_button"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:gravity="center_vertical"
-            android:src="@*android:drawable/ic_input_delete"
-            android:clickable="true"
-            android:paddingTop="8dip"
-            android:paddingBottom="8dip"
-            android:paddingLeft="24dp"
-            android:paddingRight="24dp"
-            android:background="?android:attr/selectableItemBackground"
-            android:contentDescription="@string/keyboardview_keycode_delete"
-            />
-    </LinearLayout>
-    <View
-        android:layout_width="wrap_content"
-        android:layout_height="1dp"
-        android:background="#55FFFFFF"
-        />
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        android:orientation="horizontal"
-        >
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key1"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="1"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key2"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="2"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key3"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="3"
-            />
-    </LinearLayout>
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        android:orientation="horizontal"
-        >
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key4"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="4"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key5"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="5"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key6"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="6"
-            />
-    </LinearLayout>
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:orientation="horizontal"
-        android:layout_weight="1"
-        >
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key7"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="7"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key8"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="8"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key9"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="9"
-            />
-    </LinearLayout>
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        android:orientation="horizontal"
-        >
-        <Space
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key0"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="0"
-            />
-        <ImageButton
-            android:id="@+id/key_enter"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-			android:paddingRight="30dp"
-            android:src="@drawable/sym_keyboard_return_holo"
-            android:contentDescription="@string/keyboardview_keycode_enter"
-            />
+       android:id="@+id/keyguard_bouncer_frame"
+       android:background="@*android:drawable/kg_bouncer_bg_white"
+       android:layout_width="match_parent"
+       android:layout_height="0dp"
+       android:orientation="vertical"
+       android:layout_weight="1"
+       >
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:orientation="horizontal"
+           android:layout_weight="1"
+           >
+           <TextView android:id="@+id/pinEntry"
+               android:editable="true"
+               android:layout_width="0dip"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               android:gravity="center"
+               android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
+               android:singleLine="true"
+               android:cursorVisible="false"
+               android:background="@null"
+               android:textAppearance="@style/TextAppearance.NumPadKey"
+               android:imeOptions="flagForceAscii|actionDone"
+               />
+           <ImageButton android:id="@+id/delete_button"
+               android:layout_width="wrap_content"
+               android:layout_height="match_parent"
+               android:gravity="center_vertical"
+               android:src="@*android:drawable/ic_input_delete"
+               android:clickable="true"
+               android:paddingTop="8dip"
+               android:paddingBottom="8dip"
+               android:paddingLeft="24dp"
+               android:paddingRight="24dp"
+               android:background="?android:attr/selectableItemBackground"
+               android:contentDescription="@string/keyboardview_keycode_delete"
+               />
+       </LinearLayout>
+       <View
+           android:layout_width="wrap_content"
+           android:layout_height="1dp"
+           android:background="#55FFFFFF"
+           />
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key1"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="1"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key2"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="2"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key3"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="3"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key4"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="4"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key5"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="5"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key6"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="6"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:orientation="horizontal"
+           android:layout_weight="1"
+           >
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key7"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="7"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key8"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="8"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key9"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="9"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <Space
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key0"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="0"
+               />
+           <ImageButton
+               android:id="@+id/key_enter"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               android:paddingRight="30dp"
+               android:src="@drawable/sym_keyboard_return_holo"
+               android:contentDescription="@string/keyboardview_keycode_enter"
+               />
+       </LinearLayout>
     </LinearLayout>
 
     <include layout="@layout/keyguard_emergency_carrier_area"
diff --git a/core/res/res/layout/keyguard_sim_puk_view.xml b/core/res/res/layout/keyguard_sim_puk_view.xml
index e846a7b..b5731ec 100644
--- a/core/res/res/layout/keyguard_sim_puk_view.xml
+++ b/core/res/res/layout/keyguard_sim_puk_view.xml
@@ -28,7 +28,7 @@
     android:gravity="center_horizontal">
 
     <ImageView
-        android:layout_width="wrap_content"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:src="@drawable/ic_lockscreen_sim"/>
 
@@ -37,175 +37,184 @@
         android:layout_height="wrap_content"
         />
     <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:orientation="horizontal"
-        android:layout_weight="1"
-        >
-        <TextView android:id="@+id/pinEntry"
-            android:editable="true"
-            android:layout_width="0dip"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            android:gravity="center"
-            android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
-            android:singleLine="true"
-            android:cursorVisible="false"
-            android:background="@null"
-            android:textAppearance="@style/TextAppearance.NumPadKey"
-            android:imeOptions="flagForceAscii|actionDone"
-            />
-        <ImageButton android:id="@+id/delete_button"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:gravity="center_vertical"
-            android:src="@*android:drawable/ic_input_delete"
-            android:clickable="true"
-            android:paddingTop="8dip"
-            android:paddingBottom="8dip"
-            android:paddingLeft="24dp"
-            android:paddingRight="24dp"
-            android:background="?android:attr/selectableItemBackground"
-            android:contentDescription="@string/keyboardview_keycode_delete"
-            />
-    </LinearLayout>
-    <View
-        android:layout_width="wrap_content"
-        android:layout_height="1dp"
-        android:background="#55FFFFFF"
-        />
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        android:orientation="horizontal"
-        >
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key1"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="1"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key2"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="2"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key3"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="3"
-            />
-    </LinearLayout>
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        android:orientation="horizontal"
-        >
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key4"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="4"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key5"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="5"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key6"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="6"
-            />
-    </LinearLayout>
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:orientation="horizontal"
-        android:layout_weight="1"
-        >
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key7"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="7"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key8"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="8"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key9"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="9"
-            />
-    </LinearLayout>
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        android:orientation="horizontal"
-        >
-        <Space
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            />
-        <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-            android:id="@+id/key0"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            androidprv:textView="@+id/pinEntry"
-            androidprv:digit="0"
-            />
-        <ImageButton
-            android:id="@+id/key_enter"
-            style="@style/Widget.Button.NumPadKey"
-            android:layout_width="0px"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-			android:paddingRight="30dp"
-            android:src="@drawable/sym_keyboard_return_holo"
-            android:contentDescription="@string/keyboardview_keycode_enter"
-            />
+       android:id="@+id/keyguard_bouncer_frame"
+       android:background="@*android:drawable/kg_bouncer_bg_white"
+       android:layout_width="match_parent"
+       android:layout_height="0dp"
+       android:orientation="vertical"
+       android:layout_weight="1"
+       >
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:orientation="horizontal"
+           android:layout_weight="1"
+           >
+           <TextView android:id="@+id/pinEntry"
+               android:editable="true"
+               android:layout_width="0dip"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               android:gravity="center"
+               android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
+               android:singleLine="true"
+               android:cursorVisible="false"
+               android:background="@null"
+               android:textAppearance="@style/TextAppearance.NumPadKey"
+               android:imeOptions="flagForceAscii|actionDone"
+               />
+           <ImageButton android:id="@+id/delete_button"
+               android:layout_width="wrap_content"
+               android:layout_height="match_parent"
+               android:gravity="center_vertical"
+               android:src="@*android:drawable/ic_input_delete"
+               android:clickable="true"
+               android:paddingTop="8dip"
+               android:paddingBottom="8dip"
+               android:paddingLeft="24dp"
+               android:paddingRight="24dp"
+               android:background="?android:attr/selectableItemBackground"
+               android:contentDescription="@string/keyboardview_keycode_delete"
+               />
+       </LinearLayout>
+       <View
+           android:layout_width="wrap_content"
+           android:layout_height="1dp"
+           android:background="#55FFFFFF"
+           />
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key1"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="1"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key2"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="2"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key3"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="3"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key4"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="4"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key5"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="5"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key6"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="6"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:orientation="horizontal"
+           android:layout_weight="1"
+           >
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key7"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="7"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key8"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="8"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key9"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="9"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <Space
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               />
+           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
+               android:id="@+id/key0"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="0"
+               />
+           <ImageButton
+               android:id="@+id/key_enter"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               android:paddingRight="30dp"
+               android:src="@drawable/sym_keyboard_return_holo"
+               android:contentDescription="@string/keyboardview_keycode_enter"
+               />
+       </LinearLayout>
     </LinearLayout>
 
     <include layout="@layout/keyguard_emergency_carrier_area"
diff --git a/core/res/res/layout/keyguard_widget_remove_drop_target.xml b/core/res/res/layout/keyguard_widget_remove_drop_target.xml
index c4fe9e0..f9f40ab 100644
--- a/core/res/res/layout/keyguard_widget_remove_drop_target.xml
+++ b/core/res/res/layout/keyguard_widget_remove_drop_target.xml
@@ -24,9 +24,10 @@
     android:paddingRight="40dp"
     android:drawableLeft="@drawable/kg_widget_delete_drop_target"
     android:drawablePadding="4dp"
+    android:text="@string/kg_reordering_delete_drop_target_text"
     android:textColor="#FFF"
     android:textSize="13sp"
     android:shadowColor="#000"
     android:shadowDy="1.0"
     android:shadowRadius="1.0"
-    android:visibility="gone" />
\ No newline at end of file
+    android:visibility="gone" />
diff --git a/core/res/res/values-land/bools.xml b/core/res/res/values-land/bools.xml
index 85c64d9..a1dd2e4 100644
--- a/core/res/res/values-land/bools.xml
+++ b/core/res/res/values-land/bools.xml
@@ -16,6 +16,7 @@
 
 <resources>
     <bool name="kg_enable_camera_default_widget">false</bool>
+    <bool name="kg_top_align_page_shrink_on_bouncer_visible">true</bool>
     <bool name="kg_share_status_area">false</bool>
     <bool name="kg_sim_puk_account_full_screen">false</bool>
 </resources>
diff --git a/core/res/res/values-sw600dp/bools.xml b/core/res/res/values-sw600dp/bools.xml
index eae4f87..00f45c1 100644
--- a/core/res/res/values-sw600dp/bools.xml
+++ b/core/res/res/values-sw600dp/bools.xml
@@ -21,4 +21,6 @@
     <bool name="kg_sim_puk_account_full_screen">false</bool>
     <!-- No camera for you, tablet user -->
     <bool name="kg_enable_camera_default_widget">false</bool>
+    <bool name="kg_center_small_widgets_vertically">true</bool>
+    <bool name="kg_top_align_page_shrink_on_bouncer_visible">false</bool>
 </resources>
diff --git a/core/res/res/values/bools.xml b/core/res/res/values/bools.xml
index d4ead01..457131a 100644
--- a/core/res/res/values/bools.xml
+++ b/core/res/res/values/bools.xml
@@ -16,6 +16,8 @@
 
 <resources>
     <bool name="kg_enable_camera_default_widget">true</bool>
+    <bool name="kg_center_small_widgets_vertically">false</bool>
+    <bool name="kg_top_align_page_shrink_on_bouncer_visible">true</bool>
     <bool name="action_bar_embed_tabs">true</bool>
     <bool name="action_bar_embed_tabs_pre_jb">false</bool>
     <bool name="split_action_bar_is_narrow">true</bool>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 3a24cc1..b8ec138 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -335,4 +335,9 @@
     due to the appearance of the IME), then drop the multiuser selector. -->
     <dimen name="kg_squashed_layout_threshold">600dp</dimen>
 
+    <!-- The height of widgets which do not support vertical resizing. This is only
+    used on tablets; on phones, this size is determined by the space left by the
+    security mode. -->
+    <dimen name="kg_small_widget_height">160dp</dimen>
+
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 73b9021..9932d1e 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3970,6 +3970,8 @@
     <!-- Sequence of characters used to separate message strings in keyguard. Typically just em-dash
          with spaces on either side. [CHAR LIMIT=3] -->
     <string name="kg_text_message_separator" product="default">" \u2014 "</string>
+    <!-- The delete-widget drop target button text -->
+    <string name="kg_reordering_delete_drop_target_text">Remove</string>
 
     <!-- Message shown in dialog when user is attempting to set the music volume above the
     recommended maximum level for headphones -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a12c14c..cd21d80 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1215,7 +1215,9 @@
   <java-symbol type="bool" name="kg_enable_camera_default_widget" />
   <java-symbol type="bool" name="kg_share_status_area" />
   <java-symbol type="bool" name="kg_sim_puk_account_full_screen" />
+  <java-symbol type="bool" name="kg_top_align_page_shrink_on_bouncer_visible" />
   <java-symbol type="bool" name="target_honeycomb_needs_options_menu" />
+  <java-symbol type="bool" name="kg_center_small_widgets_vertically" />
   <java-symbol type="color" name="kg_multi_user_text_active" />
   <java-symbol type="color" name="kg_multi_user_text_inactive" />
   <java-symbol type="color" name="kg_widget_pager_gradient" />
@@ -1235,6 +1237,7 @@
   <java-symbol type="dimen" name="keyguard_avatar_frame_shadow_radius" />
   <java-symbol type="dimen" name="kg_edge_swipe_region_size" />
   <java-symbol type="dimen" name="kg_squashed_layout_threshold" />
+  <java-symbol type="dimen" name="kg_small_widget_height" />
   <java-symbol type="drawable" name="ic_jog_dial_sound_off" />
   <java-symbol type="drawable" name="ic_jog_dial_sound_on" />
   <java-symbol type="drawable" name="ic_jog_dial_unlock" />
@@ -1320,6 +1323,7 @@
   <java-symbol type="id" name="keyguard_account_view" />
   <java-symbol type="id" name="keyguard_selector_fade_container" />
   <java-symbol type="id" name="keyguard_widget_pager_delete_target" />
+  <java-symbol type="id" name="keyguard_bouncer_frame" />
   <java-symbol type="id" name="app_widget_container" />
   <java-symbol type="id" name="view_flipper" />
   <java-symbol type="id" name="emergency_call_button" />
diff --git a/docs/html/training/load-data-background/define-launch-query.jd b/docs/html/training/load-data-background/define-launch-query.jd
new file mode 100644
index 0000000..f7978f4
--- /dev/null
+++ b/docs/html/training/load-data-background/define-launch-query.jd
@@ -0,0 +1,83 @@
+page.title=Defining and Launching the Query
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<!-- This is the training bar -->
+<div id="tb-wrapper">
+  <div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+    <li>
+        <a href="#DefineLaunch">Define and Launch the Query</a>
+    </li>
+</ol>
+  </div>
+</div>
+
+<p>
+    To perform a query, create the {@link android.support.v4.content.CursorLoader}, set up its
+    query, and pass it to the loader framework. From then on, the framework manages everything.
+    It runs the query on a background thread, returns the results to the foreground, and
+    watches for changes to the data associated with the query.
+</p>
+<p>
+    Pass a {@link android.support.v4.content.CursorLoader} to the loader framework in
+    your implementation of
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}.
+    The loader framework calls this method when you <i>create</i> a loader by calling
+    {@link android.support.v4.app.LoaderManager#initLoader initLoader()}. You can create
+    a {@link android.support.v4.content.CursorLoader} anywhere,
+    but the preferred way is to create it in
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()},
+    because this defers creation until the object is actually needed.
+</p>
+<p>
+    Notice that {@link android.support.v4.app.LoaderManager#initLoader initLoader()} will only
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}
+    if the {@link android.support.v4.content.CursorLoader} doesn't already exist; otherwise, it
+    re-uses the existing {@link android.support.v4.content.CursorLoader}. The loader framework
+    tracks {@link android.support.v4.content.CursorLoader} instance using the <code>id</code>
+    value passed to {@link android.support.v4.app.LoaderManager#initLoader initLoader()}.
+</p>
+<h2 id="DefineLaunch">Define and Launch the Query</h2>
+<p>
+    To create a {@link android.support.v4.content.CursorLoader} and define its
+    query at the same time, call the constructor
+{@link android.support.v4.content.CursorLoader#CursorLoader(Context, Uri, String[], String, String[], String)
+    CursorLoader(context, uri, projection, selection, selectionArgs, sortOrder)}. The
+    <code>context</code> and <code>uri</code> arguments are required, but the others are optional.
+    To use the default value for an optional argument, pass in <code>null</code>. The
+    {@link android.support.v4.content.CursorLoader} runs the query against the
+    {@link android.content.ContentProvider} identified by <code>uri</code>, just as if you had
+    called {@link android.content.ContentResolver#query ContentResolver.query()} with the same
+    arguments.
+</p>
+<p>
+    For example:
+</p>
+<pre>
+public Loader&lt;Cursor&gt; onCreateLoader(int loaderID, Bundle bundle)
+{
+    /*
+     * Takes action based on the ID of the Loader that's being created
+     */
+    switch (loaderID) {
+        case URL_LOADER:
+            /*
+             * Return a new CursorLoader
+             */
+            return new CursorLoader(
+                this,                           // Context
+                DataProviderContract.IMAGE_URI, // Provider's content URI
+                PROJECTION,                     // Columns to return
+                null,                           // Return all rows
+                null,                           // No search arguments
+                null);                          // Default search order
+        default:
+            // An invalid id was passed in
+            return null;
+    }
+}
+</pre>
diff --git a/docs/html/training/load-data-background/handle-results.jd b/docs/html/training/load-data-background/handle-results.jd
new file mode 100644
index 0000000..f8e003a
--- /dev/null
+++ b/docs/html/training/load-data-background/handle-results.jd
@@ -0,0 +1,104 @@
+page.title=Handling the Results
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<!-- This is the training bar -->
+<div id="tb-wrapper">
+  <div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li>
+    <a href="#HandleResults">Handle Query Results</a>
+  </li>
+  <li>
+    <a href="#HandleReset">Clear Out Old Data</a></li>
+</ol>
+  </div>
+</div>
+
+<p>
+    {@link android.support.v4.content.CursorLoader} returns its query results to your
+    implementation of
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished
+    LoaderCallbacks.onLoadFinished()}, in the form of a {@link android.database.Cursor}. In the
+    callback, you can update your data display, do further processing on the
+    {@link android.database.Cursor} data, and so forth.
+</p>
+<p>
+    When the loader framework detects changes to data associated with the query,
+    it resets the {@link android.support.v4.content.CursorLoader}, closes the current
+    {@link android.database.Cursor}, and then invokes your implementation of
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}.
+    Use this callback to delete references to the current {@link android.database.Cursor}; when the
+    loader framework destroys the {@link android.database.Cursor}, you won't have outstanding
+    references that cause memory leaks.
+</p>
+<h2 id="HandleFinished">Handle Query Results</h2>
+<p>
+    The following two snippets are an example of displaying the results of a query, using a
+    {@link android.widget.ListView} backed by a
+    {@link android.support.v4.widget.SimpleCursorAdapter}.
+</p>
+<p>
+    The first snippet shows the {@link android.widget.ListView} and
+    {@link android.support.v4.widget.SimpleCursorAdapter}:
+</p>
+<pre>
+// Gets a handle to the Android built-in ListView widget
+mListView = ((ListView) findViewById(android.R.id.list));
+// Creates a CursorAdapter
+mAdapter =
+    new SimpleCursorAdapter(
+    this,                   // Current context
+    R.layout.logitem,       // View for each item in the list
+    null,                   // Don't provide the cursor yet
+    FROM_COLUMNS,           // List of cursor columns to display
+    TO_FIELDS,              // List of TextViews in each line
+    0                       // flags
+);
+// Links the adapter to the ListView
+mListView.setAdapter(mAdapter);
+</pre>
+<p>
+    The next snippet shows an implementation of
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()}
+    that moves the query results in the returned {@link android.database.Cursor} to the
+    {@link android.support.v4.widget.SimpleCursorAdapter}. Changing the
+    {@link android.database.Cursor} in the
+    {@link android.support.v4.widget.SimpleCursorAdapter} triggers a refresh of the
+    {@link android.widget.ListView} with the new data:
+</p>
+<pre>
+public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor cursor)
+{
+    /*
+     * Move the results into the adapter. This
+     * triggers the ListView to re-display.
+     */
+    mAdapter.swapCursor(cursor);
+}
+</pre>
+<h2 id="HandleReset">Handle a Loader Reset</h2>
+<p>
+    The loader framework resets the {@link android.support.v4.content.CursorLoader} whenever the
+    {@link android.database.Cursor} becomes invalid. This usually occurs because the data associated
+    with the {@link android.database.Cursor} has changed. Before re-running the query,
+    the framework calls your implementation of
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}. In
+    this callback, make sure to prevent memory leaks by deleting all references to the current
+    {@link android.database.Cursor}. Once you return from
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()},
+    the loader framework re-runs the query.
+</p>
+<p>
+    For example:
+</p>
+<pre>
+public void onLoaderReset(Loader&lt;Cursor&gt; loader)
+{
+    // Remove the reference to the current Cursor
+    mAdapter.swapCursor(null);
+}
+</pre>
diff --git a/docs/html/training/load-data-background/index.jd b/docs/html/training/load-data-background/index.jd
new file mode 100644
index 0000000..574a32c
--- /dev/null
+++ b/docs/html/training/load-data-background/index.jd
@@ -0,0 +1,117 @@
+page.title=Loading Data in the Background
+trainingnavtop=true
+startpage=true
+
+@jd:body
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- Required platform, tools, add-ons, devices, knowledge, etc. -->
+<h2>Dependencies and prerequisites</h2>
+<h3>Dependencies</h3>
+<ul>
+    <li>
+        Android 1.6 or later
+    </li>
+</ul>
+<h3>Prerequisites</h3>
+<ul>
+    <li>
+        <a href="{@docRoot}training/basics/firstapp/index.html">Building Your First App</a> class
+    </li>
+    <li>
+        <a href="{@docRoot}training/basics/activity-lifecycle/index.html">
+        Managing the Activity Lifecycle</a> class
+    </li>
+</ul>
+
+<!-- related docs (NOT javadocs) -->
+<h2>You should also read</h2>
+<ul>
+    <li>
+        <a href="{@docRoot}guide/components/loaders.html">Loaders</a>
+    </li>
+    <li>
+        <a href="{@docRoot}guide/topics/data/data-storage.html#db">Using Databases</a>
+    </li>
+    <li>
+<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">Content Provider Basics</a>
+    </li>
+</ul>
+</div>
+</div>
+<p>
+    A {@link android.support.v4.content.CursorLoader} runs a query against a
+    {@link android.content.ContentProvider} on a background thread and returns a
+    {@link android.database.Cursor} to the main thread.
+</p>
+<p>
+    {@link android.support.v4.content.CursorLoader} has these advantages over alternate ways of
+    running a query:
+</p>
+<dl>
+    <dt>
+        Query on a background thread
+    </dt>
+    <dd>
+        A {@link android.support.v4.content.CursorLoader} query runs asynchronously on a
+        background thread, so it doesn't cause "Application Not Responding" (ANR) errors on the UI
+        thread. {@link android.support.v4.content.CursorLoader} creates and starts the
+        background thread; all you have to do is initialize the loader framework and handle the
+        results of the query.
+    </dd>
+    <dt>
+        Automatic re-query
+    </dt>
+    <dd>
+        A {@link android.support.v4.content.CursorLoader} automatically runs a new query when
+        the loader framework detects that the data underlying the {@link android.database.Cursor}
+        has changed.
+    </dd>
+    <dt>
+        Simple API
+    </dt>
+    <dd>
+        The {@link android.support.v4.content.CursorLoader} API provides the
+        query framework and cursor monitoring that you would have to define yourself if you used
+        {@link android.os.AsyncTask}.
+    </dd>
+</dl>
+<p>
+    A {@link android.support.v4.content.CursorLoader} is limited in that the query must be
+    against a {@link android.net.Uri} and must return a {@link android.database.Cursor}. Because of
+    this, a {@link android.support.v4.content.CursorLoader} can only run a query against a
+    {@link android.content.ContentProvider}.
+</p>
+<p>
+    This class describes how to define and use a {@link android.support.v4.content.CursorLoader}.
+    Examples in this class use the {@link android.support.v4 v4 support library} versions of
+    classes, which support platforms starting with Android 1.6.
+</p>
+<h2>Lessons</h2>
+<dl>
+    <dt>
+        <strong><a href="setup-loader.html">Setting Up the Loader</a></strong>
+    </dt>
+    <dd>
+        Learn how to set up an {@link android.app.Activity} that inherits the necessary classes
+        for running a {@link android.support.v4.content.CursorLoader} and returning results.
+    </dd>
+    <dt>
+        <strong><a href="define-launch-query.html">Defining and Launching the Query</a></strong>
+    </dt>
+    <dd>
+        Learn how to perform a query against a {@link android.content.ContentProvider} using
+        a {@link android.support.v4.content.CursorLoader}.
+    </dd>
+    <dt>
+        <strong>
+        <a href="handle-results.html">Handling the Results</a>
+        </strong>
+    </dt>
+    <dd>
+        Learn how to handle the {@link android.database.Cursor} returned from the query, and how
+        to remove references to the current {@link android.database.Cursor} when the loader
+        framework re-sets the {@link android.support.v4.content.CursorLoader}.
+    </dd>
+</dl>
diff --git a/docs/html/training/load-data-background/setup-loader.jd b/docs/html/training/load-data-background/setup-loader.jd
new file mode 100644
index 0000000..4b40611
--- /dev/null
+++ b/docs/html/training/load-data-background/setup-loader.jd
@@ -0,0 +1,90 @@
+page.title=Setting Up the Loader
+trainingnavtop=true
+startpage=true
+
+@jd:body
+
+<!-- This is the training bar -->
+<div id="tb-wrapper">
+  <div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+    <li>
+        <a href="#AddExtensions">Extend an Activity</a>
+    </li>
+    <li>
+        <a href="#GetLoader">Retrieve a LoaderManager</a>
+    </li>
+    <li>
+        <a href="#InitializeLoader">Initialize the Loader Framework</a>
+    </li>
+</ol>
+  </div>
+</div>
+<p>
+    You create a {@link android.support.v4.content.CursorLoader} within a
+    <b>loader framework</b>. To set up the framework, you implement the
+    {@link android.support.v4.app.LoaderManager.LoaderCallbacks LoaderCallbacks&lt;Cursor&gt;}
+    as part of an {@link android.app.Activity}. In addition, to provide compatibility
+    compatible with platform versions starting with Android 1.6, you must extend the
+    {@link android.app.Activity} with the {@link android.support.v4.app.FragmentActivity} class.
+</p>
+<p class="note">
+    <strong>Note:</strong> A {@link android.support.v4.app.Fragment} is not a prerequisite for
+    {@link android.support.v4.content.CursorLoader}. As a convenience, the support library class
+    {@link android.support.v4.app.FragmentActivity} contains the fragment and the loader frameworks,
+    but they are completely independent of each other.
+</p>
+<p>
+    Before you can use the loader framework, you need to initialize it. To do this, retrieve
+    a {@link android.support.v4.app.LoaderManager} object and call its
+    {@link android.support.v4.app.LoaderManager#initLoader initLoader()} method.
+</p>
+<p>
+    If you do use one or more {@link android.support.v4.app.Fragment} objects in an
+    {@link android.app.Activity}, the {@link android.support.v4.app.LoaderManager} you retrieve is
+    available to all of them.
+</p>
+<h2 id="AddExtensions">Extend an Activity</h2>
+<p>
+    To set up an {@link android.app.Activity} subclass to contain a
+    {@link android.support.v4.content.CursorLoader}, extend the subclass with
+    must extend {@link android.support.v4.app.FragmentActivity}, which provides the loader
+    framework, and implement the {@link android.support.v4.app.LoaderManager.LoaderCallbacks
+    LoaderCallbacks&lt;Cursor&gt;} interface, which specifies method signatures that the loader
+    framework uses to interact with the {@link android.app.Activity}.
+</p>
+<p>
+    For example:
+</p>
+<pre>
+public class DisplayActivity extends FragmentActivity
+        implements LoaderManager.LoaderCallbacks&lt;Cursor&gt;
+</pre>
+<h2 id="GetLoader">Retrieve a LoaderManager</h2>
+<p>
+    To get an instance {@link android.support.v4.app.LoaderManager} for use in your
+    {@link android.app.Activity}, call
+    {@link android.support.v4.app.FragmentActivity#getSupportLoaderManager
+    FragmentActivity.getSupportLoaderManager()} at the beginning of the
+    {@link android.app.Activity#onCreate onCreate()} method. For example:
+</p>
+<pre>
+private LoaderManager mLoaderManager;
+public void onCreate() {
+...
+mLoaderManager = this.getSupportLoaderManager();
+</pre>
+<h2 id="InitializeLoader">Initialize the Loader Framework</h2>
+<p>
+    Once you have the {@link android.support.v4.app.LoaderManager} object, initialize
+    it by calling {@link android.support.v4.app.LoaderManager#initLoader initLoader()}. For
+    example:
+</p>
+<pre>
+// CursorLoader instance identifier
+public static final int URL_LOADER = 0;
+...
+// Initializes the CursorLoader
+getSupportLoaderManager().initLoader(URL_LOADER, null, this);
+</pre>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 4a5b0fa..1c85ae8 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -58,7 +58,7 @@
           </li>
         </ul>
       </li>
-      
+
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot ?>training/basics/supporting-devices/index.html">
             <span class="en">Supporting Different Devices</span>
@@ -78,7 +78,7 @@
           </li>
         </ul>
       </li>
-      
+
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot ?>training/basics/fragments/index.html">
             <span class="en">Building a Dynamic UI with Fragments</span>
@@ -143,9 +143,9 @@
         </ul>
       </li>
 
-      
+
     </ul>
-  </li><!-- end basic training -->    
+  </li><!-- end basic training -->
   <li class="nav-section">
     <div class="nav-section-header">
       <a href="<?cs var:toroot ?>training/advanced.html">
@@ -193,7 +193,7 @@
           </li>
         </ul>
       </li>
-      
+
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot ?>training/efficient-downloads/index.html">
             <span class="en">Transferring Data Without Draining the Battery</span>
@@ -233,12 +233,12 @@
           </li>
         </ul>
       </li>
-      
+
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot ?>training/multiscreen/index.html"
           zh-CN-lang="针对多种屏幕进行设计"
           ja-lang="複数画面のデザイン"
-          es-lang="Cómo diseñar aplicaciones para varias pantallas"               
+          es-lang="Cómo diseñar aplicaciones para varias pantallas"
           >Designing for Multiple Screens</a>
         </div>
         <ul>
@@ -246,24 +246,24 @@
             zh-CN-lang="支持各种屏幕尺寸"
             ko-lang="다양한 화면 크기 지원"
             ja-lang="さまざまな画面サイズのサポート"
-            es-lang="Cómo admitir varios tamaños de pantalla"               
+            es-lang="Cómo admitir varios tamaños de pantalla"
             >Designing for Multiple Screens</a>
           </li>
           <li><a href="<?cs var:toroot ?>training/multiscreen/screendensities.html"
             zh-CN-lang="支持各种屏幕密度"
             ja-lang="さまざまな画面密度のサポート"
-            es-lang="Cómo admitir varias densidades de pantalla"               
+            es-lang="Cómo admitir varias densidades de pantalla"
             >Supporting Different Screen Densities</a>
           </li>
           <li><a href="<?cs var:toroot ?>training/multiscreen/adaptui.html"
             zh-CN-lang="实施自适应用户界面流程"
             ja-lang="順応性のある UI フローの実装"
-            es-lang="Cómo implementar interfaces de usuario adaptables"               
+            es-lang="Cómo implementar interfaces de usuario adaptables"
             >Implementing Adaptive UI Flows</a>
           </li>
         </ul>
       </li>
-      
+
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot ?>training/improving-layouts/index.html">
             <span class="en">Improving Layout Performance</span>
@@ -335,37 +335,37 @@
           </li>
         </ul>
       </li>
-      
+
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot ?>training/monitoring-device-state/index.html"
           zh-CN-lang="优化电池使用时间"
           ja-lang="電池消費量の最適化"
-          es-lang="Cómo optimizar la duración de la batería"               
+          es-lang="Cómo optimizar la duración de la batería"
           >Optimizing Battery Life</a>
         </div>
         <ul>
           <li><a href="<?cs var:toroot ?>training/monitoring-device-state/battery-monitoring.html"
             zh-CN-lang="监控电池电量和充电状态"
             ja-lang="電池残量と充電状態の監視"
-            es-lang="Cómo controlar el nivel de batería y el estado de carga"               
+            es-lang="Cómo controlar el nivel de batería y el estado de carga"
             >Monitoring the Battery Level and Charging State</a>
           </li>
           <li><a href="<?cs var:toroot ?>training/monitoring-device-state/docking-monitoring.html"
             zh-CN-lang="确定和监控基座对接状态和类型"
             ja-lang="ホルダーの装着状態とタイプの特定と監視"
-            es-lang="Cómo determinar y controlar el tipo de conector y el estado de la conexión"               
+            es-lang="Cómo determinar y controlar el tipo de conector y el estado de la conexión"
             >Determining and Monitoring the Docking State and Type</a>
           </li>
           <li><a href="<?cs var:toroot ?>training/monitoring-device-state/connectivity-monitoring.html"
             zh-CN-lang="确定和监控网络连接状态"
             ja-lang="接続状態の特定と監視"
-            es-lang="Cómo determinar y controlar el estado de la conectividad"               
+            es-lang="Cómo determinar y controlar el estado de la conectividad"
             >Determining and Monitoring the Connectivity Status</a>
           </li>
           <li><a href="<?cs var:toroot ?>training/monitoring-device-state/manifest-receivers.html"
             zh-CN-lang="根据需要操作广播接收器"
             ja-lang="オンデマンドでのブロードキャスト レシーバ操作"
-            es-lang="Cómo manipular los receptores de emisión bajo demanda"               
+            es-lang="Cómo manipular los receptores de emisión bajo demanda"
             >Manipulating Broadcast Receivers On Demand</a>
           </li>
         </ul>
@@ -455,7 +455,7 @@
           </li>
         </ul>
       </li>
-      
+
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot ?>training/camera/index.html">
             <span class="en">Capturing Photos</span>
@@ -475,7 +475,7 @@
           </li>
         </ul>
       </li>
-      
+
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot ?>training/multiple-apks/index.html">
             <span class="en">Maintaining Multiple APKs</span>
@@ -535,7 +535,7 @@
           </li>
         </ul>
       </li>
-      
+
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot ?>training/monetization/index.html">
             <span class="en">Monetizing Your App</span>
@@ -547,7 +547,7 @@
           </li>
         </ul>
       </li>
-      
+
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot ?>training/design-navigation/index.html">
             <span class="en">Designing Effective Navigation</span>
@@ -620,7 +620,7 @@
           </li>
         </ul>
       </li>
-      
+
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot ?>training/displaying-bitmaps/index.html">
             <span class="en">Displaying Bitmaps Efficiently</span>
@@ -717,6 +717,25 @@
         </ul>
       </li>
 
+      <li class="nav-section">
+        <div class="nav-section-header"><a href="<?cs var:toroot ?>training/load-data-background/index.html">
+            <span class="en">Loading Data in the Background</span>
+          </a></div>
+        <ul>
+          <li><a href="<?cs var:toroot ?>training/load-data-background/setup-loader.html">
+            <span class="en">Setting Up the Loader</span>
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/load-data-background/define-launch-query.html">
+            <span class="en">Defining and Launching the Query</span>
+          </a>
+          </li>
+          <li><a href="<?cs var:toroot ?>training/load-data-background/handle-results.html">
+            <span class="en">Handling the Results</span>
+          </a>
+          </li>
+        </ul>
+      </li>
 
     </ul>
   </li>
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java b/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java
index 9858c77..259f1e4 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java
@@ -149,6 +149,9 @@
             Log.e(TAG, "stop() called from non-UI thread");
         }
 
+        // Clearing any old service connected messages.
+        mHandler.removeMessages(MSG_SERVICE_CONNECTED);
+
         boolean mWasRunning = mIsRunning;
 
         stopUi();
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java
index 71526d2..7c769a7 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.os.CountDownTimer;
 import android.os.SystemClock;
 import android.text.Editable;
@@ -43,6 +44,8 @@
     protected TextView mPasswordEntry;
     protected LockPatternUtils mLockPatternUtils;
     protected SecurityMessageDisplay mSecurityMessageDisplay;
+    protected View mEcaView;
+    private Drawable mBouncerFrame;
     protected boolean mEnableHaptics;
 
     // To avoid accidental lockout due to events while the device in in the pocket, ignore
@@ -122,6 +125,11 @@
             }
         });
         mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
+        mEcaView = findViewById(R.id.keyguard_selector_fade_container);
+        View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame);
+        if (bouncerFrameView != null) {
+            mBouncerFrame = bouncerFrameView.getBackground();
+        }
     }
 
     @Override
@@ -239,5 +247,17 @@
                     | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
         }
     }
+
+    @Override
+    public void showBouncer(int duration) {
+        KeyguardSecurityViewHelper.
+                showBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+    }
+
+    @Override
+    public void hideBouncer(int duration) {
+        KeyguardSecurityViewHelper.
+                hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+    }
 }
 
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java
index 9c87755..3ce61d9 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java
@@ -318,5 +318,13 @@
     @Override
     public void showUsabilityHint() {
     }
+
+    @Override
+    public void showBouncer(int duration) {
+    }
+
+    @Override
+    public void hideBouncer(int duration) {
+    }
 }
 
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
index c0095de..8ca6d2a 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
@@ -16,6 +16,7 @@
 package com.android.internal.policy.impl.keyguard;
 
 import android.content.Context;
+import android.graphics.drawable.Drawable;
 import android.os.PowerManager;
 import android.telephony.TelephonyManager;
 import android.util.AttributeSet;
@@ -37,6 +38,9 @@
     private BiometricSensorUnlock mBiometricUnlock;
     private View mFaceUnlockAreaView;
     private ImageButton mCancelButton;
+    private SecurityMessageDisplay mSecurityMessageDisplay;
+    private View mEcaView;
+    private Drawable mBouncerFrame;
 
     private boolean mIsShowing = false;
     private final Object mIsShowingLock = new Object();
@@ -54,6 +58,13 @@
         super.onFinishInflate();
 
         initializeBiometricUnlockView();
+
+        mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
+        mEcaView = findViewById(R.id.keyguard_selector_fade_container);
+        View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame);
+        if (bouncerFrameView != null) {
+            mBouncerFrame = bouncerFrameView.getBackground();
+        }
     }
 
     @Override
@@ -217,4 +228,17 @@
     @Override
     public void showUsabilityHint() {
     }
+
+    @Override
+    public void showBouncer(int duration) {
+        KeyguardSecurityViewHelper.
+                showBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+    }
+
+    @Override
+    public void hideBouncer(int duration) {
+        KeyguardSecurityViewHelper.
+                hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+    }
+
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index 854ef01..11e600e 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -162,9 +162,11 @@
         mAppWidgetContainer.setViewStateManager(mViewStateManager);
         mAppWidgetContainer.setLockPatternUtils(mLockPatternUtils);
 
+        ChallengeLayout challenge = slider != null ? slider :
+            (ChallengeLayout) findViewById(R.id.multi_pane_challenge);
+        challenge.setOnBouncerStateChangedListener(mViewStateManager);
         mViewStateManager.setPagedView(mAppWidgetContainer);
-        mViewStateManager.setChallengeLayout(slider != null ? slider :
-                (ChallengeLayout) findViewById(R.id.multi_pane_challenge));
+        mViewStateManager.setChallengeLayout(challenge);
         mSecurityViewContainer = (KeyguardSecurityViewFlipper) findViewById(R.id.view_flipper);
         mKeyguardSelectorView = (KeyguardSelectorView) findViewById(R.id.keyguard_selector_view);
         mViewStateManager.setSecurityViewContainer(mSecurityViewContainer);
@@ -196,6 +198,11 @@
             KeyguardSecurityView ksv = (KeyguardSecurityView) view;
             ksv.setKeyguardCallback(mCallback);
             ksv.setLockPatternUtils(mLockPatternUtils);
+            if (mViewStateManager.isBouncing()) {
+                ksv.showBouncer(0);
+            } else {
+                ksv.hideBouncer(0);
+            }
         } else {
             Log.w(TAG, "View " + view + " is not a KeyguardSecurityView");
         }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java
index f6f3fab..ee5c4a6 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java
@@ -240,22 +240,33 @@
     }
 
     private void hideMessage(int duration, boolean thenUpdate) {
-        Animator anim = ObjectAnimator.ofFloat(this, "alpha", 0f);
-        anim.setDuration(duration);
-        if (thenUpdate) {
-            anim.addListener(new AnimatorListenerAdapter() {
-                    @Override
-                        public void onAnimationEnd(Animator animation) {
-                        update();
-                    }
+        if (duration > 0) {
+            Animator anim = ObjectAnimator.ofFloat(this, "alpha", 0f);
+            anim.setDuration(duration);
+            if (thenUpdate) {
+                anim.addListener(new AnimatorListenerAdapter() {
+                        @Override
+                            public void onAnimationEnd(Animator animation) {
+                            update();
+                        }
                 });
+            }
+            anim.start();
+        } else {
+            setAlpha(0f);
+            if (thenUpdate) {
+                update();
+            }
         }
-        anim.start();
     }
 
     private void showMessage(int duration) {
-        Animator anim = ObjectAnimator.ofFloat(this, "alpha", 1f);
-        anim.setDuration(duration);
-        anim.start();
+        if (duration > 0) {
+            Animator anim = ObjectAnimator.ofFloat(this, "alpha", 1f);
+            anim.setDuration(duration);
+            anim.start();
+        } else {
+            setAlpha(1f);
+        }
     }
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
index 82cb44b..3a82687 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
@@ -23,6 +23,7 @@
 import android.accounts.OperationCanceledException;
 import android.content.Context;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.CountDownTimer;
 import android.os.SystemClock;
@@ -84,6 +85,8 @@
     };
     private Rect mTempRect = new Rect();
     private SecurityMessageDisplay mSecurityMessageDisplay;
+    private View mEcaView;
+    private Drawable mBouncerFrame;
 
     enum FooterMode {
         Normal,
@@ -136,6 +139,11 @@
 
         maybeEnableFallback(mContext);
         mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
+        mEcaView = findViewById(R.id.keyguard_selector_fade_container);
+        View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame);
+        if (bouncerFrameView != null) {
+            mBouncerFrame = bouncerFrameView.getBackground();
+        }
     }
 
     private void updateFooter(FooterMode mode) {
@@ -381,7 +389,16 @@
     public KeyguardSecurityCallback getCallback() {
         return mCallback;
     }
+
+    @Override
+    public void showBouncer(int duration) {
+        KeyguardSecurityViewHelper.
+                showBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+    }
+
+    @Override
+    public void hideBouncer(int duration) {
+        KeyguardSecurityViewHelper.
+                hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+    }
 }
-
-
-
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityContainer.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityContainer.java
index 7b11507..375a96a 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityContainer.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityContainer.java
@@ -1,11 +1,6 @@
 package com.android.internal.policy.impl.keyguard;
 
-import android.animation.Animator;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
 import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.FrameLayout;
@@ -13,10 +8,6 @@
 import com.android.internal.R;
 
 public class KeyguardSecurityContainer extends FrameLayout {
-
-    private float mBackgroundAlpha;
-    private Drawable mBackgroundDrawable;
-
     public KeyguardSecurityContainer(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
@@ -27,68 +18,30 @@
 
     public KeyguardSecurityContainer(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-        mBackgroundDrawable = context.getResources().getDrawable(R.drawable.kg_bouncer_bg_white);
     }
 
-    public void setBackgroundAlpha(float alpha) {
-        if (Float.compare(mBackgroundAlpha, alpha) != 0) {
-            mBackgroundAlpha = alpha;
-            invalidate();
-        }
-    }
-
-    public float getBackgroundAlpha() {
-        return mBackgroundAlpha;
-    }
-
-    @Override
-    protected void dispatchDraw(Canvas canvas) {
-        if (mBackgroundAlpha > 0.0f && mBackgroundDrawable != null) {
-            Drawable bg = mBackgroundDrawable;
-            bg.setAlpha((int) (mBackgroundAlpha * 255));
-            bg.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
-            bg.draw(canvas);
-        }
-        super.dispatchDraw(canvas);
-    }
-
-    public void showBouncer(int duration) {
-        SecurityMessageDisplay message = new KeyguardMessageArea.Helper(getSecurityView());
-        message.showBouncer(duration);
-        AnimatorSet anim = new AnimatorSet();
-        anim.playTogether(ObjectAnimator.ofFloat(this, "backgroundAlpha", 1f), getEcaAnim(0f));
-        anim.setDuration(duration);
-        anim.start();
-    }
-
-    public void hideBouncer(int duration) {
-        SecurityMessageDisplay message = new KeyguardMessageArea.Helper(getSecurityView());
-        message.hideBouncer(duration);
-        AnimatorSet anim = new AnimatorSet();
-        anim.playTogether(ObjectAnimator.ofFloat(this, "backgroundAlpha", 0f), getEcaAnim(1f));
-        anim.setDuration(duration);
-        anim.start();
-    }
-
-    View getSecurityView() {
+    KeyguardSecurityViewFlipper getFlipper() {
         for (int i = 0; i < getChildCount(); i++) {
             View child = getChildAt(i);
             if (child instanceof KeyguardSecurityViewFlipper) {
-                return (View) (((KeyguardSecurityViewFlipper) child).getSecurityView());
+                return (KeyguardSecurityViewFlipper) child;
             }
         }
         return null;
     }
 
-    Animator getEcaAnim(float alpha) {
-        Animator anim = null;
-        View securityView = getSecurityView();
-        if (securityView != null) {
-            View ecaView = securityView.findViewById(R.id.keyguard_selector_fade_container);
-            if (ecaView != null) {
-                anim = ObjectAnimator.ofFloat(ecaView, "alpha", alpha);
-            }
+    public void showBouncer(int duration) {
+        KeyguardSecurityViewFlipper flipper = getFlipper();
+        if (flipper != null) {
+            flipper.showBouncer(duration);
         }
-        return anim;
+    }
+
+    public void hideBouncer(int duration) {
+        KeyguardSecurityViewFlipper flipper = getFlipper();
+        if (flipper != null) {
+            flipper.hideBouncer(duration);
+        }
     }
 }
+
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java
index 2651743..027b16e 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java
@@ -66,4 +66,18 @@
      *
      */
     void showUsabilityHint();
+
+    /**
+     * Place the security view into bouncer mode.
+     * Animate transisiton if duration is non-zero.
+     * @param duration millisends for the transisiton animation.
+     */
+    void showBouncer(int duration);
+
+    /**
+     * Place the security view into non-bouncer mode.
+     * Animate transisiton if duration is non-zero.
+     * @param duration millisends for the transisiton animation.
+     */
+    void hideBouncer(int duration);
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java
index 58cf567..3d4cb19 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java
@@ -125,4 +125,26 @@
             ksv.showUsabilityHint();
         }
     }
+
+    @Override
+    public void showBouncer(int duration) {
+        for (int i = 0; i < getChildCount(); i++) {
+            View child = getChildAt(i);
+            if (child instanceof KeyguardSecurityView) {
+                KeyguardSecurityView ksv = (KeyguardSecurityView) child;
+                ksv.showBouncer(child.getVisibility() == View.VISIBLE ? duration : 0);
+            }
+        }
+    }
+
+    @Override
+    public void hideBouncer(int duration) {
+        for (int i = 0; i < getChildCount(); i++) {
+            View child = getChildAt(i);
+            if (child instanceof KeyguardSecurityView) {
+                KeyguardSecurityView ksv = (KeyguardSecurityView) child;
+                ksv.hideBouncer(child.getVisibility() == View.VISIBLE ? duration : 0);
+            }
+        }
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewHelper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewHelper.java
new file mode 100644
index 0000000..2ccdc1d
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewHelper.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2012 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.impl.keyguard;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+
+/**
+ * Some common functions that are useful for KeyguardSecurityViews.
+ */
+public class KeyguardSecurityViewHelper {
+
+    public static void showBouncer(SecurityMessageDisplay securityMessageDisplay,
+            View ecaView, Drawable bouncerFrame, int duration) {
+        if (securityMessageDisplay != null) {
+            securityMessageDisplay.showBouncer(duration);
+        }
+        if (ecaView != null) {
+            if (duration > 0) {
+                Animator anim = ObjectAnimator.ofFloat(ecaView, "alpha", 0f);
+                anim.setDuration(duration);
+                anim.start();
+            } else {
+                ecaView.setAlpha(0f);
+            }
+        }
+        if (bouncerFrame != null) {
+            if (duration > 0) {
+                Animator anim = ObjectAnimator.ofInt(bouncerFrame, "alpha", 255);
+                anim.setDuration(duration);
+                anim.start();
+            } else {
+                bouncerFrame.setAlpha(255);
+            }
+        }
+    }
+
+    public static void hideBouncer(SecurityMessageDisplay securityMessageDisplay,
+            View ecaView, Drawable bouncerFrame, int duration) {
+        if (securityMessageDisplay != null) {
+            securityMessageDisplay.hideBouncer(duration);
+        }
+        if (ecaView != null) {
+            if (duration > 0) {
+                Animator anim = ObjectAnimator.ofFloat(ecaView, "alpha", 1f);
+                anim.setDuration(duration);
+                anim.start();
+            } else {
+                ecaView.setAlpha(1f);
+            }
+        }
+        if (bouncerFrame != null) {
+            if (duration > 0) {
+                Animator anim = ObjectAnimator.ofInt(bouncerFrame, "alpha", 0);
+                anim.setDuration(duration);
+                anim.start();
+            } else {
+                bouncerFrame.setAlpha(0);
+            }
+        }
+    }
+}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
index 776827c..9167412 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
@@ -261,4 +261,12 @@
     public KeyguardSecurityCallback getCallback() {
         return mCallback;
     }
+
+    @Override
+    public void showBouncer(int duration) {
+    }
+
+    @Override
+    public void hideBouncer(int duration) {
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
index 7c117d9..6d88652 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
@@ -122,6 +122,7 @@
     class ViewManagerHost extends FrameLayout {
         public ViewManagerHost(Context context) {
             super(context);
+            setFitsSystemWindows(true);
         }
 
         @Override
@@ -164,7 +165,8 @@
 
             mKeyguardHost = new ViewManagerHost(mContext);
 
-            int flags = WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN
+            int flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                    | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
                     | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 
             if (!mNeedsInput) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
index d0fa81e..3648d99 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
@@ -881,7 +881,9 @@
      * Dismiss the keyguard through the security layers.
      */
     public void dismiss() {
-        mKeyguardViewManager.dismiss();
+        if (mShowing && !mHidden) {
+            mKeyguardViewManager.dismiss();
+        }
     }
 
     /**
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java
index 054b9b2..e53358b 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java
@@ -19,7 +19,9 @@
 import android.os.Looper;
 import android.view.View;
 
-public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChallengeScrolledListener {
+public class KeyguardViewStateManager implements
+        SlidingChallengeLayout.OnChallengeScrolledListener,
+        ChallengeLayout.OnBouncerStateChangedListener {
 
     private KeyguardWidgetPager mKeyguardWidgetPager;
     private ChallengeLayout mChallengeLayout;
@@ -92,6 +94,10 @@
         mChallengeLayout.showBouncer();
     }
 
+    public boolean isBouncing() {
+        return mChallengeLayout.isBouncing();
+    }
+
     public void fadeOutSecurity(int duration) {
         ((View) mKeyguardSecurityContainer).animate().alpha(0).setDuration(duration);
     }
@@ -192,6 +198,7 @@
     @Override
     public void onScrollStateChanged(int scrollState) {
         if (mKeyguardWidgetPager == null || mChallengeLayout == null) return;
+
         boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping();
 
         if (scrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) {
@@ -222,15 +229,24 @@
             KeyguardWidgetFrame frame = mKeyguardWidgetPager.getWidgetPageAt(mPageListeningToSlider);
             if (frame == null) return;
 
-            frame.showFrame(this);
+            // Skip showing the frame and shrinking the widget if we are
+            if (!mChallengeLayout.isBouncing()) {
+                frame.showFrame(this);
 
-            // As soon as the security begins sliding, the widget becomes small (if it wasn't
-            // small to begin with).
-            if (!frame.isSmall()) {
-                // We need to fetch the final page, in case the pages are in motion.
-                mPageListeningToSlider = mKeyguardWidgetPager.getNextPage();
-                frame.shrinkWidget();
+                // As soon as the security begins sliding, the widget becomes small (if it wasn't
+                // small to begin with).
+                if (!frame.isSmall()) {
+                    // We need to fetch the final page, in case the pages are in motion.
+                    mPageListeningToSlider = mKeyguardWidgetPager.getNextPage();
+                    frame.shrinkWidget();
+                }
+            } else {
+                if (!frame.isSmall()) {
+                    // We need to fetch the final page, in case the pages are in motion.
+                    mPageListeningToSlider = mKeyguardWidgetPager.getNextPage();
+                }
             }
+
             // View is on the move.  Pause the security view until it completes.
             mKeyguardSecurityContainer.onPause();
         }
@@ -275,4 +291,14 @@
     public int getTransportState() {
         return mTransportState;
     }
+
+    // ChallengeLayout.OnBouncerStateChangedListener
+    @Override
+    public void onBouncerStateChanged(boolean bouncerActive) {
+        if (bouncerActive) {
+            mKeyguardWidgetPager.zoomOutToBouncer();
+        } else {
+            mKeyguardWidgetPager.zoomInFromBouncer();
+        }
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java
index 213b82f..fa1a1ae 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java
@@ -112,6 +112,10 @@
 
         mFrameStrokeAdjustment = (int) (2 * density);
 
+        // This will be overriden on phones based on the current security mode, however on tablets
+        // we need to specify a height.
+        mSmallWidgetHeight =
+                res.getDimensionPixelSize(com.android.internal.R.dimen.kg_small_widget_height);
         mBackgroundDrawable = res.getDrawable(R.drawable.kg_bouncer_bg_white);
         mGradientColor = res.getColor(com.android.internal.R.color.kg_widget_pager_gradient);
         mGradientPaint.setXfermode(sAddBlendMode);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
index 7943b23..274e12b 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
@@ -44,7 +44,7 @@
 import java.util.ArrayList;
 
 public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwitchListener,
-        OnLongClickListener {
+        OnLongClickListener, ChallengeLayout.OnBouncerStateChangedListener {
 
     ZInterpolator mZInterpolator = new ZInterpolator(0.5f);
     private static float CAMERA_DISTANCE = 10000;
@@ -64,6 +64,7 @@
 
     private static final long CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT = 30000;
     private static final String TAG = "KeyguardWidgetPager";
+    private boolean mCenterSmallWidgetsVertically;
 
     private int mPage = 0;
     private Callbacks mCallbacks;
@@ -72,6 +73,10 @@
 
     private int mWidgetToResetAfterFadeOut;
 
+    // Bouncer
+    protected int BOUNCER_ZOOM_IN_OUT_DURATION = 250;
+    private float BOUNCER_SCALE_FACTOR = 0.67f;
+
     // Background worker thread: used here for persistence, also made available to widget frames
     private final HandlerThread mBackgroundWorkerThread;
     private final Handler mBackgroundWorkerHandler;
@@ -94,6 +99,8 @@
 
         Resources r = getResources();
         mCameraWidgetEnabled = r.getBoolean(R.bool.kg_enable_camera_default_widget);
+        mCenterSmallWidgetsVertically =
+                r.getBoolean(com.android.internal.R.bool.kg_center_small_widgets_vertically);
         mBackgroundWorkerThread = new HandlerThread("KeyguardWidgetPager Worker");
         mBackgroundWorkerThread.start();
         mBackgroundWorkerHandler = new Handler(mBackgroundWorkerThread.getLooper());
@@ -277,6 +284,9 @@
                 } else {
                     // Lock the widget to be small.
                     frame.setWidgetLockedSmall(true);
+                    if (mCenterSmallWidgetsVertically) {
+                        lp.gravity = Gravity.CENTER;
+                    }
                 }
             }
         } else {
@@ -706,4 +716,46 @@
         KeyguardWidgetFrame child = getWidgetPageAt(viewIndex);
         child.setIsHoveringOverDeleteDropTarget(isHovering);
     }
+
+    // ChallengeLayout.OnBouncerStateChangedListener
+    @Override
+    public void onBouncerStateChanged(boolean bouncerActive) {
+        if (bouncerActive) {
+            zoomOutToBouncer();
+        } else {
+            zoomInFromBouncer();
+        }
+    }
+
+    // Zoom in after the bouncer is dismissed
+    void zoomInFromBouncer() {
+        if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
+            mZoomInOutAnim.cancel();
+        }
+        final View currentPage = getPageAt(getCurrentPage());
+        if (currentPage.getScaleX() < 1f || currentPage.getScaleY() < 1f) {
+            mZoomInOutAnim = new AnimatorSet();
+            mZoomInOutAnim.setDuration(BOUNCER_ZOOM_IN_OUT_DURATION);
+            mZoomInOutAnim.playTogether(
+                    ObjectAnimator.ofFloat(currentPage, "scaleX", 1f),
+                    ObjectAnimator.ofFloat(currentPage , "scaleY", 1f));
+            mZoomInOutAnim.start();
+        }
+    }
+
+    // Zoom out after the bouncer is initiated
+    void zoomOutToBouncer() {
+        if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
+            mZoomInOutAnim.cancel();
+        }
+        View currentPage = getPageAt(getCurrentPage());
+        if (!(currentPage.getScaleX() < 1f || currentPage.getScaleY() < 1f)) {
+            mZoomInOutAnim = new AnimatorSet();
+            mZoomInOutAnim.setDuration(BOUNCER_ZOOM_IN_OUT_DURATION);
+            mZoomInOutAnim.playTogether(
+                    ObjectAnimator.ofFloat(currentPage, "scaleX", BOUNCER_SCALE_FACTOR),
+                    ObjectAnimator.ofFloat(currentPage, "scaleY", BOUNCER_SCALE_FACTOR));
+            mZoomInOutAnim.start();
+        }
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java b/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
index 00a0aed..8f47578 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
@@ -24,6 +24,7 @@
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.content.Context;
+import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Matrix;
@@ -209,7 +210,7 @@
     private long REORDERING_DELETE_DROP_TARGET_FADE_DURATION = 150;
     private float mMinScale = 1f;
     protected View mDragView;
-    private AnimatorSet mZoomInOutAnim;
+    protected AnimatorSet mZoomInOutAnim;
     private Runnable mSidePageHoverRunnable;
     private int mSidePageHoverIndex = -1;
     // This variable's scope is only for the duration of startReordering() and endReordering()
@@ -246,6 +247,9 @@
     // Drop to delete
     private View mDeleteDropTarget;
 
+    // Bouncer
+    private boolean mTopAlignPageWhenShrinkingForBouncer = false;
+
     public interface PageSwitchListener {
         void onPageSwitching(View newPage, int newPageIndex);
         void onPageSwitched(View newPage, int newPageIndex);
@@ -270,8 +274,10 @@
                 a.getDimensionPixelSize(R.styleable.PagedView_scrollIndicatorPaddingRight, 0);
         a.recycle();
 
-        mEdgeSwipeRegionSize =
-                getResources().getDimensionPixelSize(R.dimen.kg_edge_swipe_region_size);
+        Resources r = getResources();
+        mEdgeSwipeRegionSize = r.getDimensionPixelSize(R.dimen.kg_edge_swipe_region_size);
+        mTopAlignPageWhenShrinkingForBouncer =
+                r.getBoolean(R.bool.kg_top_align_page_shrink_on_bouncer_visible);
 
         setHapticFeedbackEnabled(false);
         init();
@@ -645,6 +651,10 @@
                 MeasureSpec.makeMeasureSpec(heightSize - verticalPadding, childHeightMode);
 
             child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+            if (mTopAlignPageWhenShrinkingForBouncer) {
+                child.setPivotX(child.getWidth() / 2);
+                child.setPivotY(0f);
+            }
         }
         setMeasuredDimension(scaledWidthSize, scaledHeightSize);
 
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
index 2712494..16ec8c5 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
@@ -29,6 +29,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
+import android.util.DisplayMetrics;
 import android.util.FloatProperty;
 import android.util.Log;
 import android.util.Property;
@@ -64,6 +65,8 @@
     private Drawable mFrameDrawable;
     private boolean mEdgeCaptured;
 
+    private DisplayMetrics mDisplayMetrics;
+
     // Initialized during measurement from child layoutparams
     private View mExpandChallengeView;
     private KeyguardSecurityContainer mChallengeView;
@@ -264,7 +267,8 @@
         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
         mTouchSlopSquare = mTouchSlop * mTouchSlop;
 
-        final float density = res.getDisplayMetrics().density;
+        mDisplayMetrics = res.getDisplayMetrics();
+        final float density = mDisplayMetrics.density;
 
         // top half of the lock icon, plus another 25% to be sure
         mDragHandleClosedAbove = (int) (DRAG_HANDLE_CLOSED_ABOVE * density + 0.5f);
@@ -481,6 +485,14 @@
             return;
         }
         mChallengeShowing = showChallenge;
+
+        if (mExpandChallengeView == null || mChallengeView == null) {
+            // These might not be here yet if we haven't been through layout.
+            // If we haven't, the first layout pass will set everything up correctly
+            // based on mChallengeShowing as set above.
+            return;
+        }
+
         if (mChallengeShowing) {
             mExpandChallengeView.setVisibility(View.INVISIBLE);
             mChallengeView.setVisibility(View.VISIBLE);
@@ -520,8 +532,8 @@
     @Override
     public void showBouncer() {
         if (mIsBouncing) return;
-        showChallenge(true);
         mIsBouncing = true;
+        showChallenge(true);
         if (mScrimView != null) {
             mScrimView.setVisibility(VISIBLE);
         }
@@ -887,9 +899,27 @@
                 continue;
             }
             // Don't measure the challenge view twice!
-            if (child != mChallengeView) {
-                measureChildWithMargins(child, widthSpec, 0, heightSpec, 0);
+            if (child == mChallengeView) continue;
+
+            // Measure children. Widget frame measures special, so that we can ignore
+            // insets for the IME.
+            int parentWidthSpec = widthSpec, parentHeightSpec = heightSpec;
+            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            if (lp.childType == LayoutParams.CHILD_TYPE_WIDGETS) {
+                final View root = getRootView();
+                if (root != null) {
+                    // This calculation is super dodgy and relies on several assumptions.
+                    // Specifically that the root of the window will be padded in for insets
+                    // and that the window is LAYOUT_IN_SCREEN.
+                    final int windowWidth = mDisplayMetrics.widthPixels;
+                    final int windowHeight = mDisplayMetrics.heightPixels - root.getPaddingTop();
+                    parentWidthSpec = MeasureSpec.makeMeasureSpec(
+                            windowWidth, MeasureSpec.EXACTLY);
+                    parentHeightSpec = MeasureSpec.makeMeasureSpec(
+                            windowHeight, MeasureSpec.EXACTLY);
+                }
             }
+            measureChildWithMargins(child, parentWidthSpec, 0, parentHeightSpec, 0);
         }
     }